1

I have two JPanels inside another JPanel. One of them has a JTextField inside, another few JButtons. I want focus to be set on the JTextField every time user starts typing (even when one of the buttons has focus at the moment).

clay_golem
  • 37
  • 1
  • 4

2 Answers2

1

You need to attach a KeyListener to all controls in your JPanel, with a reference to the JTextField you want to focus like so:

panel.addKeyListener(new KeyPressedListener(yourTextField));
button1.addKeyListener(new KeyPressedListener(yourTextField));
button2.addKeyListener(new KeyPressedListener(yourTextField));

class KeyPressedListener implements KeyListener
{
    private JTextField textFieldToFocus;

    public KeyPressedListener(JTextField textFieldToFocus)
    {
         this.textFieldToFocus = textFieldToFocus;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        textFieldToFocus.requestFocus();
    }
}
mbdavis
  • 3,861
  • 2
  • 22
  • 42
  • Now add 100 more components, across multiple containers, to the picture, this quickly becomes an impractical solution – MadProgrammer Apr 07 '15 at 22:24
  • @MadProgrammer true, this is assuming its only a few controls as he said. your method looks a lot better! – mbdavis Apr 07 '15 at 22:36
  • It's possible that this will meet the OP's needs, who knows, but my first thought was it won't scale, but that has more to do with my experience then anything else ;) – MadProgrammer Apr 07 '15 at 22:44
1

KeyListener won't work, because in order for it to trigger key events, the component it is registered to must be focusable AND have focus, this means you'd have to attach a KeyListener to EVERY component that might be visible on the screen, this is obviously not a practical idea.

Instead, you could use a AWTEventListener which allows you to register a listener that will notify you of all the events been processed through the event queue.

The registration process allows you to specify the events your are interested, so you don't need to constantly try and filter out events which your not interested in

For example. Now, you can automatically focus the textField when a key is triggered, but you should check to see if the event was triggered by the text field and ignore it if it was

One of the other things you would be need to do is re-dispatch the key event to the text field when it isn't focused, otherwise the field will not show the character which triggered it...

Something like...

if (Character.isLetterOrDigit(e.getKeyChar())) {
    filterField.setText(null);
    filterField.requestFocusInWindow();
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            filterField.dispatchEvent(e);
        }
    });
}

as an example

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366