This article covers a handy bit of logic to stabilize Java/Swing components that otherwise have annoying grow/shrink behavior. The (perceived) problem occurs when a Java/Swing application uses layout managers that obey internal components’ desired sizes. The layout shifts to accommodate internal components as they grow/shrink, which can cause much distress to the end user (at least it does to me). Read the rest of this entry »
Archive for the tag: Swing
This article presents a simple programming technique for ensuring Java Swing tasks are executed on the proper thread, while avoiding unnecessary delayed invocation. Read the rest of this entry »
Swing Hangs on Thread, Old Timers to Blame, Factory Fixes
Potential RPG Tags: design patterns, Java, programming, Swing2 Comments »
Elderly swing-set factory employees using thread instead of chains forces product recall?
No. Why would you think that?
This article describes how the javax.swing.Timer utility can cause your Swing application to hang at shutdown, and how to fix it.
The Timer utility is useful for repeating tasks on the Swing/AWT thread. They’re handy enough to create in many places throughout GUI code. However, each one that remains active keeps the AWT thread alive, which prevents clean application shutdown (without resorting to System.exit()). Lacing the code with Timer instances makes it difficult to track them all down and stop them when the application is supposed to exit.
To correct the situation for the MMORPG client, I created a simple factory class with a create(..) method for producing Timer instances. The factory maintains a reference to every Timer created. At application shutdown, the factory’s stop() method is called, which tells each Timer to stop(). After replacing all Timer constructor calls with the factory’s create(..) method, the MMORPG client exits cleanly.
There are a few caveats. For one, you must be certain it is safe to stop Timers in this way (a Timer may be carrying out some critical pre-shutdown operation). In general, I only use Timers for GUI-related activities, and not to drive application logic. Another weakness is that the factory cannot guarantee the Timers will not be restarted, or that more timers will not be created, after stopping the factory. This could be guarded with a more sophisticated design, such as a TimerProxy class to prevent post-shutdown starting, refusing to create new timers after shutdown, or an isStopped() method for GUI code to query.
For the MMORPG client, this simple factory pattern is sufficient to untie Timers from the AWT thread, allowing clean shutdown without resorting to System.exit().
