Creating Interactive GUIs with Swing's MVC Architecture
Part 1: Model-View-Controller and Swing
Many GUI-based applications, client interfaces, and widget toolkits use the Model-View-Controller (MVC) architecture as a primary design pattern to present, manipulate, and store data for the end users. Java's Swing toolkit is no exception. Every visual component in Swing follows the MVC pattern to achieve its task. Model-View-Controller was build into Swing from the very beginning. In this article, I'll show how model-view-controller architecture is intertwined with Swing and how its robustness and strengths can be used to create extremely flexible and powerful graphical user interfaces that require minimal effort to modify once all components are in place.
This material is split in to two articles: This part describes the underlying implementation of Model-View-Controller in Swing and the second part demonstrates a concrete example of the MVC pattern's strength by showing how use three fundamental mechanisms in Java to alter data presentation at run time without changing the correlating model. But, so you don't think that I left all the good stuff for last, the first part of this article will come with fully working code that you can apply to an enterprise level UI project, with minimal changes.
Swing and MVC Design
In a commercial application, there are often requirements to have a table of information populated from a database, or some other real-time data source. Constant revising or requesting data on every change to its presentation (such as a sort or filter) would be extremely expansive and prone to performance bottlenecks. A great number of different caching techniques have been devised to improve performance in these cases, but there is a much simpler way to populate table once, show it, and then modify the presentation only, without touching the underling data. This technique can be applied to any visual components, including lists, drop-downs, and trees. And those UI components that don't have a lot of data, such as buttons, can still benefit from the ability to change their 'look and feel' without actually changing their functionality.
Well, as it turns out, Model-View-Controller in Swing does just that! It decouples presentation from data and from operation on that data. The controller is actually collapsed into a delegate object and is not truly separated from view or is not a separate class; this is why MVC in Swing is sometimes called "separable model architecture." The designers of Swing did this because it was "difficult to write a generic controller that didn't know specifics about the [particular] view."
All graphical components in Swing, and I do mean all, follow Model-View-Controller architecture. Therefore, according to the Swing specification and package structure, every component has a presentation class, model class, and a public interface. There is a separation, hoverer, between a GUI-based state model and an application-specific data model. The application-specific model is usually a model dealing with or containing real user data, such as a table, list or text area. A GUI state model is usually a model that does not relate directly to the user data, such as model of a button or a 'progress slider' component. In this article, I'll concentrate on application-specific data models.
If you've superficially used Swing to create basic Java GUIs or used any IDE to do it for you, you probably did not even notice that there is a separation between visual components and their data models. That is because Swing will install a default model for every component that you use. For the developer, there is no sense in creating a new model for every Button on the screen and then assign it to the button. The same goes for the complex components, such as Tables. Just creating one and adding text to it works fine and does not require explicit model object creation. However, the existence of a separable model in Swing allows programmers to do much more advanced GUI development, and was added from the initial design of Swing for a very important reason!
The controller, as I've mentioned, is not clearly apparent and is not used as in traditional MVC design pattern, but it does exist. The View layer of the MVC in Swing is objects used to render (or show) components on the screen; all visual components from Buttons to Sliders to Text Areas are part of the view layer and therefore have presentation classes. The way to truly utilize MVC in Swing is to explicitly install a new model object or chains of them. Several presentation classes may use the same Model class to contain the data they are presenting. They don't even have to be of the same type! What I mean is that you can create multiple components, such as text area boxes, and place them in different parts of your application. All of these text areas can have one model object associated with them. Any time one text area is updated—by user typing or deleting text, for example—all other text areas will reflect that change and show same text! Here is sample code that creates a model Object and two View objects, and installs a model into them. By comparison, if you create a View object with a default constructor, a default model would be used.
Document doc = new DefaultStyledDocument(); // MODEL object JTextArea ta1 = new JTextArea(doc); // VIEW object 1 JTextArea ta2 = new JTextArea(doc); // VIEW object 1
But wait, that is not all. You can have one model object assigned to view objects of different types, such as JTextArea and JTextField and they will both use it. For example, this code is legal:
Document doc = new DefaultStyledDocument(); // MODEL object JTextArea ta = new JTextArea(doc); // VIEW object 1 JTextField tf = new JTextField(doc, "Name", 1); // VIEW object 2