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.

Thursday, October 2, 2008

trashing code

Did you see much software having features removed in newer releases, cause I can't actually name a single one. Imagine the product management board saying Hey, customers are not using this feature, let's trash it.

I am not commenting on their behavior, and for good reasons probably, they prefer other methods of "removing" features. One is hiding them from the user by offering a basic vs an advanced interface, or grouping some features under an Advanced menu item, or offering a More things to do step. This way, what they and the GUI designers are doing is protecting the user from the ever increasing GUI complexity, enable them to do things as fast as possible.

In this context, I suggest that you, yes you, the developer in the cube right behind the R3 pole, start thinking about protecting yourself from the ever growing complexity, which we feel both when reading and writing code. A good way to do this is fight back: start controlling the size of the code base.

That being said, this morning I am particularly happy because I see my project fellows throwing away code: today it was a draw, 3 classes added, 3 removed.

Before starting to read IT literature, I thought I was weird feeling this way about throwing away code. But I see there are a lot others feeling the same thing, and they can express the idea much better than me.

So start feeling happy when code gets deleted, it is a sign of healthy code while more features are added to the product.