An introduction to the problem
The Java Foundation Classes and Swing are the basis for building rich client applications. The problem is that Swing is basically a bunch of UI components without a framework to assist in building an application. Frames, panels and other components can be visually added and tied together with listeners, but how these building blocks are combined to solve a user's problem is left up to the developer. The developer needs a framework to jump start the effort required to build a complex Swing application. This is where JuiPiter can help.
JuiPiter was designed to obey the rules encoded into Swing by the designers at Sun. Swing has a single threaded process on which all UI events must occur. After a Swing component is displayed, the component may not be accessed except via the Swing event thread. Another rule requires long-lived processes to occur in a separate thread to ensure good UI responsiveness by allowing the user to continue interacting with the UI while the process is running. Few Swing developers follow these basic rules as the rules are not enforced or assisted by a framework.
What is JuiPiter?
JuiPiter provides a mechanism to separate Swing tasks from long running non-UI tasks. The core of the JuiPiter mechanism is the Window Logic Decoupler. The decoupler, in addition to memory management and externalized strings, adds a single local Thread (non-Swing) per window that acts as the delegate. The single thread aspect solves the multi-Thread concurrency management that the developer must handle is using other options, i.e., SwingWorkerThread, FoxTrot, Spin.
All Swing and delegate tasks communicate through a message passing, publish and subscribe mechanism. Each task publishes messages through the decoupler. The use of queues allows the tasks to communicate without specific synchronization. There is one set of queues and a delegate thread for each Window, though a way to pass messages between Windows has been implemented. Along with this simple messaging infrastructure, JuiPiter also includes a number of Swing component helper classes and an extensive sample application, similar to the SwingSet, that demonstrates all the aspects of the JuiPiter framework. JuiPiter is designed in layers so that some developers may use just the messaging foundation while others will also use the component helpers and utility classes.
How does JuiPiter work?
JuiPiter was created as part of a larger business application. While nothing in JuiPiter constrains its usage to business apps, a standard information management application makes a good example for explaining how JuiPiter works. Say a complex Swing UI is used to drive server-based business processes. For example, when a user clicks a button, some business process is fired and eventually returns results to be displayed. In JuiPiter, the button publishes a message to the decoupler and returns control to the user, after changing the cursor to an hour glass. The business task receives the message from the delegate, builds the results and publishes a results message to the decoupler. The Swing component, which registered its interest in the results message, receives the results, displays the contents of the message and removes the hour glass cursor.
This is a high-level description of what happens inside JuiPiter, the missing pieces involve how the multiple threads are handled. Given that Swing components must be accessed via the Swing event thread, and long tasks must be processed on the delegate thread, the decoupler manages which thread handles each task. The developer does not need to be know how the threads are synchronized, and the developer's code does not need to be concerned with synchronization. All the developer does is dispatch messages and register subscribers for these messages. It is basically method calls between objects, but through an intermediary that resolves any threading issues.