Niedziałający KeyListener

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;
    }
}
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.

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

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ć? :/

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());
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.

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.

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ć?

0

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

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.

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