Search code examples
javaswingjtextfieldkeyevent

Waiting for JTextField "SPACE" event


I have a JPanel with a JTextField and I'd like to implement waitForTextFieldSpace. I think making a custom JTextField would be the most elegant solution, but I'm not entirely sure.

public class MyPanel {
   JTextField textField;

   //...constructor, methods, etc

   public void waitForTextFieldSpace() {
      //...don't return until the user has pressed space in the text field
   }
}

I do have some code that has a JFrame wait for the space bar. But I'm not sure how to do the text field task above.

public void waitForKey(final int key) {
        final CountDownLatch latch = new CountDownLatch(1);
        KeyEventDispatcher dispatcher = new KeyEventDispatcher() {
            public boolean dispatchKeyEvent(KeyEvent e) {
                if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == key) {
                    latch.countDown();
                }
                return false;
            }
        };
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
        try {
            //current thread waits here until countDown() is called (see a few lines above)
            latch.await();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }  
        KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);

    }

Solution

  • The correct solution is to create a custom JTextField as follows

    public class MyTextField extends JTextField {
    
        private static final long serialVersionUID = 1833734152463502703L;
    
        public MyTextField() {
    
        }
    
        public void waitForKey(final int key) {
            final CountDownLatch latch = new CountDownLatch(1);
            KeyEventDispatcher dispatcher = new KeyEventDispatcher() {
                public boolean dispatchKeyEvent(KeyEvent e) {
                    if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == key) {
                        latch.countDown();
                    }
                    return false;
                }
            };
            KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
            try {
                //current thread waits here until countDown() is called (see a few lines above)
                latch.await();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }  
            KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
    
        }
    
    }
    

    and then in the original method, just invoke waitForKey() on the MyTextField object