Posted by
alexfromsun on September 27, 2007 at 7:03 AM PDT
One of the big part of my work is fixing bugs in Swing but not all of them are to be fixed, some of them are closed because they describe the situations when someone uses Swing in undocumented way or trying to make Swing do something which it doesn't support.
My favourite example is so-called "Blocking GlassPane". If you file a bug with a description that you implemented a GlassPane to block your frame and it doesn't work, most likely it will immediately be closed as "not a bug". The reason is simple - glassPane is an internal feature of Swing and the library may use wherever it is necessary, for example currently we make it visible during resizing of internal frames to show a correct mouse cursor above any existing components.
Swing does it well if you just paint something on a GlassPane but when your GlassPane affects the processing of events it becomes what I call a "hack". There are many definitions what a "hack" is, either positive or negative, but I want to give a definition what I mean by this word
Hack is an approach when you use something in an unexpected way
Hacks don't have to be alway good or bad. Some of them are creative and effective, some of them are just creative, but they are always different from recommended or well-known solutions.
Going back to Swing I want to mention the main feature of a code which uses hacks:
If you use recommended techniques and something doesn't work as it should
Swing team is to be blame.
If you use a hack and something doesn't work - it is you to be blame.
Hacks usually work well for a presentation or a blog entry, but very few of them work as good and stable as the core library code. When you think it is good enough, someone else finds a problem whith your code and when you fix it, another issue appears so when you fix the "last" problem you know enough to write another valid test case which will be broken with your code.
Even if you are pretty sure that your hack works well on your computer, there usually no guarantee that it doesn't fail for another OS or with some custom components which use similar hack.
The "Blocking GlassPane" is an interesting example because it is a well-known hack which has never worked well. It is easy to put a fancy animation to a GlassPane and add an empty MouseListener to block the MouseEvents but people tend to forget about KeyBoard events and it is usually possible to type something in a TextField under a Blocking GlassPane.
I already blogged about this issue and offered some solutions to make this hack more robust however a month ago I got a message from one of my readers, he told me that my improved Blocking Glasspane fails to block the menu accelerators, so if you use Alt+MenuShortCut the menu will appear.
Problems like that is a usual thing when you use hacks. The most straightforward fix for this particular problem would be to disable frame's JMenuBar before showing GlassPane and enabling it again when the GlassPane is gone, but don't ask me how give user a chance to interrupt the time-consuming operation which blocks his frame or how to ignore keyboards actions for other components.
Modal dialog is the only recommended solution to block a top level frame
During my work on JXTransformer I used any kind of hacks to make transformed components work as well as usual ones. I managed to make it work for unsigned applet however I used some fishy techniques which I can hardly recommend. And again I realized that it might work for the most usual cases but there will always be some cases when transformed components behave incorrectly and the only right fix is to change the Swing itself to support AffineTransform for JComponents.
After that I added a special note that JXTransformer has several known limitations and decided that my next project will use only recommended techniques which always work well.
That's the reason why I don't use any hacks in JXLayer component. When I started this project it was tempting to add some creative hacks to implement some unique features but I keep following the "no hacks rule" because I don't want to be blame if JXLayer wouldn't work for your project.
When hacks are welcome
If you think that I don't use hacks at all, it's not true. There are some situations where hacks (even the dirty ones) are welcome, I am talking about testing and debugging. Let's say you need to find a cause of a bug, and in this case all means which may help are good (until they are not a part of production code).
On SwingHelper project you can find a CheckThreadViolationRepaintManager which helps finding a Event Dispatch Thread violation in Swing applications as well asEventDispatchThreadHangMonitor to catch time-consuming tasks on Event Dispatch Thread.
I would hardly use custom RepaintManager or EventQueue for my components, but they work very well when it comes to debugging.
Testing is a similar story, when I have a choice between a manual regression test with no hacks and automated one with hacks, I always choose the last one, just because manual tests don't have much sense
Conclusion
I am a realist and I know that unfortunately it is almost impossible to make a big project without any hacks. The only recommendation I can give for this matter is do not use hacks just because you know them, try to follow the documented patterns as often as possible and you code will be more reliable
To be continued...