Tuesday, October 21, 2008

debugging swing

... they say debugging code can take more than the writing itself ...

One of the problem I faced when I joined my actual project, with its GUI module having ~2230 java files was finding out which handlers were being invoked in response to a GUI event. Now that I know the project conventions and where the different types of classes go, it's easier, still from time to time I have this difficulty. My team mates have it too, so here is a tip to find out what piece of code is called to handle a particular event:
  • set your debugger to step into the JDK classes, for IntelliJ the setting is here File / Settings / Debugger / Stepping.
  • to catch mouse events (most common) set your breakpoints in java.awt.Component#processMouseEvent (you'd want to avoid catching MouseEvent.MOUSE_ENTERED and MouseEvent.MOUSE_EXITED)
  • when the execution flow reaches your breakpoint, look at the this variable, it will show you the type of the clicked component. Indeed, it won't help finding out that you clicked a JButton, but you can always go up the containment hierarchy until you find a custom component (very often a derived panel XxxMyFeaturePanel) so you'll know what corner of the code base you are in. Do this by evaluating expressions like this.parent.parent.parent
  • if you want to debug the actual handler being invoked, locate the handler of interest mainly in this.listenerList, this.mouseListener and set a breakpoint in there, most often you'll be interested in an application-specific handler as opposed to a JDK handler
  • for components that feature selection (like JTable), the selection listener will be on the table's selection model, so check ((JTable) this).getSelectionModel().listenerList
Here is a screenshot with the above technique: breakpoint in java.awt.Component, the this reference is a StripedJTable that is contained in a ConfigBackupPanel.



If you are interested in debugging deeper through the JDK sources, make sure you get a JDK compiled with debug info, otherwise you won't see valuable info like variable values. You can find instructions here on how to build a rt.jar with debugging info. (The author uses the GNU utilities for Windows to find all java files in the JDK but you can do the same thing with the built-in Windows command dir <path_to_jdk_src_dir>\*.java /b /s). Also you might need to copy rt.jar to a temp location and include it from there in the classpath when compiling.

1 comment:

Anonymous said...

Do you have copy writer for so good articles? If so please give me contacts, because this really rocks! :)