Java: JPanel cannot receive key events after button is clicked (which has no registered event listener)?

StackOverflow https://stackoverflow.com/questions/8622962

Question

First of all, thanks for taking the time to read my question, I appreciate it.

Here's the overview of what I've got now:

I'm writing a slider puzzle game, 3 by 3 using buttons as grid cells. I've added a key listener to the JPanel which holds those buttons, and they respond to keyboard events just fine.

However, the problem's somewhat peculiar, and I haven't really been able to pinpoint why it renders this erratic behavior. After clicking on one of those 'buttons', none of which have event listeners registered, none of the buttons move, but when you follow that with a key event, the keys become unresponsive.

My question is this: I know this is pretty vague, but does this ring a bell to anyone to be a Java problem, or does it sound like my faulty code's behind all this?

I'm really open to any suggestions, since this has been bothering me for about a week now, and I still don't know what caused the problem.

Again, thank you for taking the time to peruse this.

@trashgod: yes, of course.

public class Test2 extends JPanel{
    JButton a = new JButton("A");

    Test2(){
        setFocusable(true);
        // Set layout to grid layout
        setLayout(new GridLayout(3, 3));
        // Add button
        //a.setEnabled(false);
        add(a);

        // Register key event which shifts it to the next cell when the right arrow is pressed
        addKeyListener(new KeyAdapter(){
            public void keyPressed(KeyEvent e){
                if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                    remove(a);
                    JButton b = new JButton("B");
                    //b.setEnabled(false);
                    add(b);
                    add(a);
                    validate();

                }
            }
        });
    }
}

Function of code snippet: JPanel receives key event, the left arrow key, to be precise, removes button 'a', and adds on a new button 'b', followed by the button 'a' every time. However, if you try and run the program, after you click on a button, it just stops listening to key events.

I've just paid some thought to it, could it have something to do with the lost focus in JPanel? If so, what particular methods should I pay attention to to restore the lost focus?

Thanks!

(btw, the setEnabled comments is my attempt at solving this problem, by simply disabling the button, but it still doesn't explain how to restore the lost focus to the JPanel if that's the problem at hand.)

Was it helpful?

Solution

not all Keys are accesible for KeyListener, part of them are registred as built-in short-cuts for JComponents, depends of JComponent's type and used Look and Feel, if you want to listening for Keys from keyboard, then you have to implements KeyBindings, Swing JComponents are designated to use this listener rather that KeyListener

working example for key A

import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test2 extends JPanel {

    private static final long serialVersionUID = 1L;
    private JButton a = new JButton("A");

    public Test2() {
        setFocusable(true);
        setLayout(new GridLayout(3, 3));
        a.setEnabled(false);
        add(a);
        addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_A) {
                    remove(a);
                    JButton b = new JButton("B");
                    add(b);
                    add(a);
                    revalidate();
                    repaint();
                }
            }
        });
    }

    public static void main(String... args) {
        JFrame frame = new JFrame("");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Test2());
        frame.pack();
        frame.setVisible(true);
    }
}

OTHER TIPS

We can keep the focus on the JPanel by just calling setFocusable(false) on each button:

button1.setFocusable(false); or button2.setFocusable(false);

etc

This will allow the JPanel, where the keyListeners are added, to keep the focus.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top