KeyListener nie wykonuje polecenia

0

chciałbym aby po wciśnięciu klawisza ESCAPE program kończył działanie, tak się jednak nie dzieje. Gdzie znajduje się błąd w moim pojmowaniu KeyListenera?

http://pastebin.com/ANtUeR6u

public void keyPressed(KeyEvent e) {
 
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
            dispose();
 
    }
0

Zdarzenie klawiaturowe (naciśnięcie ESC) dociera do tego komponentu, który ma aktualnie fokus. Niemożliwe żeby fokus miało okno - obiekt klasy JFrame.

0

Czyli focus mogą mieć obiekty klas dziedziczących po JComponent, zgadza się? bp. Jpanel

0

Tak, ponadto przyciski, pola tekstowe,..
Z panelem musisz być ostrożny, użytkownik może mieć problem z przeniesieniem fokusu na JPanel. Pooksperymentuj z poniższym programem. Uruchom go w podanej wersji, a potem próbuj odkomentować instrukcje z konstruktora.

/* Przesuwanie kwadraciku na dwóch różnych panelach
 */
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TwoPanels extends JFrame implements KeyListener
{
    private MyPanel left = new MyPanel();
    private MyPanel right = new MyPanel();
    //------------------------    
    public static void main(String[] args)
    {
        new TwoPanels();
    }
    //------------------------
    public TwoPanels()
    {
        setTitle("A,W,S,Z po lewej, strzałki po prawej");
        setLayout(new FlowLayout(FlowLayout.CENTER));
        left.addKeyListener(this);
        //left.setFocusable(true);
        right.addKeyListener(this);
        add(left);
        //add(new JTextField("   "));        
        add(right);
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        //left.requestFocus();
    }
    //------------------------
    public void keyTyped(KeyEvent ke)
    {
    }
    //------------------------
    public void keyPressed(KeyEvent ke)
    {
        if(ke.getKeyCode() == KeyEvent.VK_S)
        {
            left.moveX(1);
        }
        if(ke.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            right.moveX(1);
        }
        if(ke.getKeyCode() == KeyEvent.VK_A)
        {
            left.moveX(-1);
        }
        if(ke.getKeyCode() == KeyEvent.VK_LEFT)
        {
            right.moveX(-1);
        }
        if(ke.getKeyCode() == KeyEvent.VK_W)
        {
            left.moveY(-1);
        }
        if(ke.getKeyCode() == KeyEvent.VK_UP)
        {
            right.moveY(-1);
        }
        if(ke.getKeyCode() == KeyEvent.VK_Z)
        {
            left.moveY(1);
        }
        if(ke.getKeyCode() == KeyEvent.VK_DOWN)
        {
            right.moveY(1);
        }        
        repaint();         
    }
    //------------------------
    public void keyReleased(KeyEvent ke)
    {
    }
    //------------------------     
    class MyPanel extends JPanel
    {
        private int x = 0;
        private int y = 0;
        private final int WIDTH = 300;
        private final int HEIGHT = 300;
        //--------------------
        public MyPanel()
        {
            setPreferredSize(new Dimension(WIDTH,HEIGHT));
            setBorder(BorderFactory.createLineBorder(Color.BLACK));
            setBackground(Color.WHITE);
        }
        //--------------------
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g); 
            g.setColor(Color.RED);
            g.fillRect(x,y,5,5);
        }
        //--------------------
        public void moveX(int delta)
        {
            x+=delta;
            x = x % WIDTH;
            if(x<0)
            {
                x = WIDTH - 1;
            }
        }
        //--------------------
        public void moveY(int delta)
        {
            y+=delta;
            y = y % HEIGHT;
            if(y<0)
            {
                y = HEIGHT - 1;
            }
        }        
    }
}
0

Zauważyłem właśnie ten problem z focusem na JPanelu w moim programie- przy starcie programu jak się nic nie klika jest spoko, ale gdy focus przeniesie się na obszar typu BufferedImage, JPanel go traci. Rozwiązałem to poprzez dodanie keyListenera do obszaru BufferedImage.

Jeszcze jedno pytanie odnośnie aplikacji której kod wstawiłeś, jak chciałbym ją rozbudować o możliwość jednoczesnego przesuwania kropki na obu stronach to powinienem zainteresować się Wątkami?

0

Jeśli na panelu wywołasz wcześniej setFocusable(true) to można mu przywrócić fokus naciskając odpowiednią ilość razy Tab lub Shift+Tab, myszą chyba nie można przywrócić fokusu.
Myślę, że starczy dwa timery. Jeden przesuwa (wywołuje metodę moveX lub moveY) w lewym panelu, drugi w prawym. keyPressed startuje timer w odpowiednim panelu (wpierw zatrzymuje działający Timer - jeśli jest taki), keyReleased zatrzymuje timer.

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