Niedziałający KeyListener

Odpowiedz Nowy wątek
2018-11-27 14:51
0

Witam, robię symulator samochodu i chciałbym, aby po wciśnięciu klawisza "W" zwiększała się prędkość, lecz nic się nie dzieje... Mógłby ktoś doradzić?

import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Color;

@SuppressWarnings("serial")
public class CarSimulator extends JPanel {
    int predkosc;
    int obroty;
    int bieg;
    boolean silnikOdpalony = false;
    Timer timer;
    int delay = 33;
    private JTextField txtPredkosc;
    private JTextField txtBieg;
    private JTextField txtObroty;

    public CarSimulator() {
        setBackground(Color.LIGHT_GRAY);
        setLayout(null);
        JPanel panel = new JPanel();
        add(panel);
        panel.setLayout(null);
        panel.addKeyListener(new SpeedListener());

        JLabel lblPredkosc = new JLabel("Predkosc:");
        lblPredkosc.setHorizontalAlignment(SwingConstants.RIGHT);
        lblPredkosc.setBounds(217, 29, 68, 14);
        add(lblPredkosc);

        JLabel lblBieg = new JLabel("Bieg:");
        lblBieg.setHorizontalAlignment(SwingConstants.RIGHT);
        lblBieg.setBounds(217, 60, 68, 14);
        add(lblBieg);

        JLabel lblObroty = new JLabel("Obroty:");
        lblObroty.setHorizontalAlignment(SwingConstants.RIGHT);
        lblObroty.setBounds(217, 91, 68, 14);
        add(lblObroty);

        JButton btnStart = new JButton("START");
        btnStart.setBounds(232, 183, 135, 70);
        add(btnStart);

        txtPredkosc = new JTextField();
        txtPredkosc.setText("0");
        txtPredkosc.setHorizontalAlignment(SwingConstants.CENTER);
        txtPredkosc.setColumns(10);
        txtPredkosc.setBounds(297, 26, 86, 20);
        txtPredkosc.setEditable(false);
        add(txtPredkosc);

        txtBieg = new JTextField();
        txtBieg.setText("N");
        txtBieg.setHorizontalAlignment(SwingConstants.CENTER);
        txtBieg.setColumns(10);
        txtBieg.setBounds(297, 57, 86, 20);
        txtBieg.setEditable(false);
        add(txtBieg);

        txtObroty = new JTextField();
        txtObroty.setText("0");
        txtObroty.setHorizontalAlignment(SwingConstants.CENTER);
        txtObroty.setColumns(10);
        txtObroty.setBounds(297, 88, 86, 20);
        txtObroty.setEditable(false);
        add(txtObroty);

    }

    public class SpeedListener implements KeyListener {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_W) {
                setPredkosc(1);
                txtPredkosc.setText(Integer.toString(getPredkosc()));
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_W) {
                setPredkosc(-1);
                txtPredkosc.setText(Integer.toString(getPredkosc()));
            }
        }

        @Override
        public void keyTyped(KeyEvent arg0) {
            // TODO Auto-generated method stub

        }
    }

    public void setPredkosc(int predkosc) {
        this.predkosc += predkosc;
    }

    public int getPredkosc() {
        return predkosc;
    }
}
edytowany 1x, ostatnio: bogdans, 2018-12-11 06:14

Pozostało 580 znaków

2018-11-29 07:36
eL
0

Ja to się na takich cudach to zbytnio nie znam ale... Uruchamiałeś to w debugu? Postaw breakpointa na wysokości linijki if (e.getKeyCode() == KeyEvent.VK_W) { i zobacz czy po kliknięciu w klawisz wpada Ci tutaj. Potem sprawdź co zwraca Ci e.getKeyCode() czy to na pewno jest ten klawisz który oczekujesz... Na końcu sprawdź jeszcze czy ten warunek e.getKeyCode() == KeyEvent.VK_W zwraca oczekiwaną wartość. Najlepiej zrobić tak że w debugu zaznacz sobie ten fragment kodu, kliknij PPM i wybierz Evaluate Expression. Potem Kliknij evaluate i powinnieś zobaczyć wynik. Jeśli wcisnąłeś W to powinno być true. Tutaj masz więcej na ten temat

A tak poza tym to ten kod wydaje mi się być trochę bezsensu...
Masz KeyListenera który ma 2 metody zaimplementowane:

  @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_W) {
                setPredkosc(1);
                txtPredkosc.setText(Integer.toString(getPredkosc()));
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_W) {
                setPredkosc(-1);
                txtPredkosc.setText(Integer.toString(getPredkosc()));
            }
        }

Jeśli dobrze rozumiem to przyciśnięcie W spowoduje setPredkosc(1); natomiast puszczenie klawisza wywołuje setPredkosc(-1); czyli tak naprawdę nic się nie zmienia. To nie będzie działało tak że jak będziesz trzymał to będzie cały czas +1 +1 +1 +1 +1 tylko raz zrobi +1 a za chwile jak puścisz to -1.

Kolejna sprawa że nazywanie zmiennej setPredkosc wskazuje na to że będziesz prędkość ustawiał na wartość którą przekażesz czyli setPredkosc(1); spowoduje ustawienie prędkości = 1 a tym czasem jak się spojrzy na implementację tej metody to jest niespodzianka:

    public void setPredkosc(int predkosc) {
        this.predkosc += predkosc;
    }

Nie idź tą drogą :O

Ps. Zmienne w klasie (prędkośc, obroty itd itd) ustaw na private.

Pozostało 580 znaków

2018-11-29 12:40
0

Z tego co pamietam, żeby swingowy JComponent rejestrował eventy klawiatury, to musi być focused. Sprawdź sobie, czy faktycznie twój komponent ma ten focus (są od tego metody w stylu isFocused

Pozostało 580 znaków

2018-12-10 16:34
0
Tyvrel napisał(a):

Z tego co pamietam, żeby swingowy JComponent rejestrował eventy klawiatury, to musi być focused. Sprawdź sobie, czy faktycznie twój komponent ma ten focus (są od tego metody w stylu isFocused

Mimo tego, że dodałem na końcu kostruktora panel.requestFocus(), to i tak nic nie daje. Mógłby ktoś coś doradzić? :/

Pozostało 580 znaków

2018-12-10 17:11
0

Masz w kodzie dwa obiekty typu JPanel, na jednym z nich umieszczasz wszystkie komponenty, do drugiego podpinasz KeyListenera, Usuń jeden z tych obiektów.
A konkretnie, to zamień

JPanel panel = new JPanel();
add(panel);
panel.setLayout(null);
panel.addKeyListener(new SpeedListener());

na

addKeyListener(new SpeedListener());

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 4x, ostatnio: bogdans, 2018-12-11 06:32

Pozostało 580 znaków

2019-01-03 23:58
0
bogdans napisał(a):

Masz w kodzie dwa obiekty typu JPanel, na jednym z nich umieszczasz wszystkie komponenty, do drugiego podpinasz KeyListenera, Usuń jeden z tych obiektów.
A konkretnie, to zamień

JPanel panel = new JPanel();
add(panel);
panel.setLayout(null);
panel.addKeyListener(new SpeedListener());

na

addKeyListener(new SpeedListener());

Po tak długim czasie, wracam do tego, lecz wciąż to nie działa. Pomimo usunięcia tego panela, wciąż nie przyśpiesza.

Pozostało 580 znaków

2019-01-04 00:31
Krwawy Kaczor
0
leicer131 napisał(a):
Tyvrel napisał(a):

Z tego co pamietam, żeby swingowy JComponent rejestrował eventy klawiatury, to musi być focused. Sprawdź sobie, czy faktycznie twój komponent ma ten focus (są od tego metody w stylu isFocused

Mimo tego, że dodałem na końcu kostruktora panel.requestFocus(), to i tak nic nie daje. Mógłby ktoś coś doradzić? :/
To musi być dodane po pokazaniu JFrame.

Pozostało 580 znaków

2019-01-04 00:36
0
Krwawy Kaczor napisał(a):
leicer131 napisał(a):
Tyvrel napisał(a):

Z tego co pamietam, żeby swingowy JComponent rejestrował eventy klawiatury, to musi być focused. Sprawdź sobie, czy faktycznie twój komponent ma ten focus (są od tego metody w stylu isFocused

Mimo tego, że dodałem na końcu kostruktora panel.requestFocus(), to i tak nic nie daje. Mógłby ktoś coś doradzić? :/
To musi być dodane po pokazaniu JFrame.

Czyli gdzie powinienem to wklepać?

edytowany 1x, ostatnio: leicer131, 2019-01-04 00:36

Pozostało 580 znaków

2019-01-04 11:45
Krwawy Kaczor
0

Czyli gdzie powinienem to wklepać?
Po metodzie jframe.setVisible(true);

Pozostało 580 znaków

2019-01-04 12:00
0
Krwawy Kaczor napisał(a):

Czyli gdzie powinienem to wklepać?
Po metodzie jframe.setVisible(true);

public static void main(String[] args) {
        JFrame frame = new JFrame("Car Simulatori");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new SamSymulator());
        frame.setSize(new Dimension(600,400));
        frame.setVisible(true);
        frame.getContentPane().requestFocus();
    }

Wciąż to samo, nic sie nie dzieje, po wcisnieciu klawisza W.

Pozostało 580 znaków

2019-01-04 12:13
Krwawy Kaczor
0
leicer131 napisał(a):
Krwawy Kaczor napisał(a):

Czyli gdzie powinienem to wklepać?
Po metodzie jframe.setVisible(true);

public static void main(String[] args) {
      JFrame frame = new JFrame("Car Simulatori");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new SamSymulator());
      frame.setSize(new Dimension(600,400));
      frame.setVisible(true);
      frame.getContentPane().requestFocus();
  }

Wciąż to samo, nic sie nie dzieje, po wcisnieciu klawisza W.

A poprawiłeś wszystko, na co inni zwrócili Ci uwagę?
Dodatkowo, skoro ustawiasz listener na panelu to kliknięcie na przycisk lub pole textowe powoduje, że już Ci ten kod nie zadziała bo panel straci focus i na nowo już go nie odzyska

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0