4

So when maintaining a large Java Swing application I have an issue: the arrow keys in the filename textfield of a sub-class derived from JFileChooser don't work.

If I just put this class into a tiny stand-alone Swing app with just a JFrame, the arrow keys (specifically left and right) will move around the cursor in the filename field just fine, but it won't work in the original application. I have checked all KeyListeners of all its containers, but couldn't find anything that captures the event. So the question is: is there any way to stop the IDE in debug mode (or any method to debug the issue without an IDE) upon a certain or all KeyPress event(s)?

Metaphox
  • 2,085
  • 2
  • 21
  • 34
  • Besides the excellent answer below, there is some other useful information here: https://stackoverflow.com/questions/3929932/how-does-java-dispatch-keyevents – Joshua Goldberg Nov 08 '19 at 17:17

1 Answers1

4

The way I would do this is put a breakpoint inside java\awt\Component.java. You should be able to find it in your JDK. This is the method which dispatches all events to the listeners you've registered:

protected void processKeyEvent(KeyEvent e) {
    KeyListener listener = keyListener;
    if (listener != null) {
        int id = e.getID();
        switch(id) {
          case KeyEvent.KEY_TYPED:
              listener.keyTyped(e);
              break;
          case KeyEvent.KEY_PRESSED:
              listener.keyPressed(e);
              break;
          case KeyEvent.KEY_RELEASED:
              listener.keyReleased(e);
              break;
        }
    }
}

The KeyListener variable in this case is a little bit un-intuitive if you have more than one listener. You might expect it to iterate over a list of listeners in the order they were added. If fact, it uses a composite object called an AWTEventMulticaster which is basically just a pair of listeners.

If you have two listeners the structure is simple:

AWTEventMulticaster
{
   first_listener_you_added;
   second_listener_you_added;
}

If you have three listeners, the structure uses nested Multicasters:

AWTEventMulticaster
{
   first_listener_you_added;
   AWTEventMulticaster
   {
       second_listener_you_added;
       third_listener_you_added;
   }
}

and so on...

By carefully tracing your application through from this point you should be able to find the point where the event is consumed.

Michael
  • 41,989
  • 11
  • 82
  • 128