This discussion is archived
2 Replies Latest reply: Jul 2, 2010 3:48 AM by 800413 RSS

Keylistener not working. Need to loose focus on main window, and reapply it

800413 Newbie
Currently Being Moderated
dear forum users.
Im having a bit of a problem with a keylistener.
To get it to work, i have to take focus away from the window (JFrame), and then back again..

My KeyListener:
public class KeyBinder implements KeyListener {
    private Map<Integer,CustomKeyEvent> keys = new HashMap<Integer,CustomKeyEvent>();
    

    public void keyReleased(KeyEvent e) {
        if (keys.containsKey(e.getKeyCode())) {
            keys.get(e.getKeyCode()).keyReleased(this);
        }
    }
    public void keyTyped(KeyEvent e) {
        if (keys.containsKey(e.getKeyCode())) {
            keys.get(e.getKeyCode()).keyTyped(this);
        }
    }
    public void keyPressed(KeyEvent e) {
        if (keys.containsKey(e.getKeyCode())) {
            keys.get(e.getKeyCode()).keyPressed(this);
        }
    }
I have also tried to just add a System.out.println in the beginning of keyPressed.. And no event is fired.

My JFrame:
    public JFrame_Main(String title, Dimension size) {
        super(title);
        setSize(size);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setFocusable(false);
    }
My Panel that should get focus:
public class JPanel_GameStarted_PlayingField extends JPanel implements TimerInterface {
    private Timer timer;
    public JPanel_GameStarted_PlayingField() {
        addKeyListener(Information.getKeyBinder());
        setVisible(false);
        setSize(Information.getMainFrame().getSize().width - 8, Information.getMainFrame().getSize().height - 50);
        setLocation(0,0);
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        addMouseListener(new CustomMouseListener(Information.getGameController().getSelf()));
        
        timer = new Timer();

        timer.scheduleAtFixedRate(new ExtendedTimerTask(this), 0, 20);
        setFocusable(true);
        setVisible(true);
        requestFocus();
    }
The strange thing is, the mouselistener works fine..
Anyone know what might be wrong?
  • 1. Re: Keylistener not working. Need to loose focus on main window, and reapply it
    843807 Newbie
    Currently Being Moderated
    You should really post an SSCCE, otherwise all anybody can do is just guess at what might be causing your problem.

    That said, some things to consider:

    1. Use requestFocusInWindow() not requestFocus(). According to its Javadoc, the latter's use is discouraged in favor of the former.
    2. Do all UI-related stuff, including widget instantiation (and focus requests), on the EDT. Failure to do so may result in problems such as what you're seeing.
    3. Make sure your panel is "displayable, focusable, visible and all of its ancestors (with the exception of the top-level Window) must be visible", otherwise the focus request will likely not be granted.

    If you do all of the above, and still have problems, post an SSCCE.
  • 2. Re: Keylistener not working. Need to loose focus on main window, and reapply it
    800413 Newbie
    Currently Being Moderated
    tried all of the things u said.

    Changed to requestFocusInWindow().
    And added:
            try {
                EventQueue.invokeAndWait(new Runnable() {
                    public void run() {
                        Information.getComponentInitiator().showPlayingField();
                    }
                });
            } catch(Exception e) {
                e.printStackTrace();
            }
    On the part that initiates the panel that should get focus.. tried with SwingUtilities.invokeAndWait aswell..

    Also, the correct panels are focusable, visible and displayable..

    Any other ideas?


    EDIT:
    Found a solution.
        public void showPlayingField() {
           try {
                EventQueue.invokeAndWait(new Runnable() {
                    public void run() {
                        JPanel_GameStarted_PlayingField playingField = new JPanel_GameStarted_PlayingField();
                        Information.getMainFrame().addComponent(playingField,0);
                        playingField.requestFocusInWindow();
                    }
                });
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    Swapped the invokeAndWait to the method showPlayingField, and called the requestFocusInWindow after the panel had been added to the jframe.

    Edited by: Lgeee on Jul 2, 2010 3:46 AM