When developing an application using object-oriented (OO) language such as C++ and Java, the developers frequently encounter one task, which is to extend the existing classes to provide more or customized functionalities to meet users’ requirements. From pure OO perspective, creating a subclass from an existing one (or interface), adding more functions or overriding existing functions in parent classes would achieve this goal. This task is with the big word in OO world, Inheritance. Object composition is another way of extending existing classes. But in real world things tend to be more complex, hence theory should be applied differently. That’s what developers will experience in Java world.
One of the well-know design patterns that is heavily applied in Java Swing is Model-View-Controller (MVC). To customize a Swing component, a developer must understand how MVC architect works. This article will demonstrate MVC in action by customizing JComboBox to change the default searching capability.
Java Swing is a collection of GUI components that are totally redesigned apart from Java AWT. The architecture of Swing is based on so called modified-MVC. The MVC is a design pattern originated from the pure object-oriented language small-talk. Basically it’s the separation of a GUI component’s data, appearance and function (action). In Java Swing architecture, the View and Controller of MVC are collapsed to be one GUI Manager of a component. That’s where the word ‘modified’ comes from. This concept can be well represented by one of business practice, outsourcing. That is whenever you instantiate a Swing component, you actually got a shell package. The life of the component is supported by a group of objects handling different organs of the component. The benefits of such design pattern are enormous, which is not the focus of this article.
For developers, to extend and customize the behavior of Swing component, obviously will not be as simple as extend the component itself. The developers will deal with the outsourcing parties of the component.
To allow developers communicating with the Swing component and providing extra functionalities, usually a set of interfaces are defined within the component. By implementing the interface, the developers can customize the component by plug the implementation. In this case, the inheritance of OO is more a mechanical tools than a methodology.
A Swing Combo Box is consisting of two parts. One part is a text field and another one is a drop down list. The text field can be set editable or non-editable.
By default, when the text field is set non-editable, the combo box can be searched by typing the first letter of the item in the list. If there are more than one item shares the same initial, the first one is always the selected one. In certain situation this default search is becoming useless. For example, when all the items in the list have the same prefix, the search becomes handicapped.
When a custom behavior is in demand, the touching of Swing MVC is inedible. Now, let’s take a look what JComboBox offers to extend the functionality.
Here are some methods in of JComboBox interesting us.
Model: setModel() to custom the data that the combo box represent.
View: setUI() and setRenderer() to custom the combo box look and feel.
Control: setEditor(), setKeySelectionManager() to custom editing and keyboard related functions.
A good design pattern book would explain all the benefit of such architect, if you catch an empty feeling when lost the powerful OO inherence. A recommendation is Design Pattern, by Erich Gamma …, and published by Addison Wesley.
This demo application has two combo boxes on it.
While typing, the combo box trying to locate the item the mach the typed string (not just the initial letter) from the first letter. Hit any non-character key will start a new search. For example, when you type ‘thi’, the selected item will be ‘this’, which is the first one matches the ‘thi’.
This type of searching is achived by providing the JComboBox a custom JComboBox.KeySelectionManager object.
The text field of JComboBox is set to be editable. After type a string, hit Enter key, the matched item will be selected and shown in the text field. The matching is same as the first type of search.
An Action Listener is added to the JComboBox to conduct the searching by response the Enter key.
Let’s work through the code to see how they are done.
* the drop down box for Searching while Typing.
* The drop down box for Search after Typing.
* visible after the main frame is visible.
Notice the plain Swing JComboBox is used to define the two combo box members. We are not customizing it by extending it.
This is the list of string we put into the combo box to do the test.
The first combo box, search while typing, has set to have a new JComboBox.KeySelectionManager instance. Be aware that KeySelectionManager is an interface defined as inner interface of JComboBox. MyKeyManager is an inner class defined in SearchableComboBox by implementing the interface.
Implementing Interfaces are the most important way of customizing Swing components.
* Searchs the data model based on the letter typed in.
* @param aKey the current typed in letter.
* @return the index of item selected.
In the method selectionForKey, any custom searching mechanism can be created and the JComboBox will take it use it. JComboBox only knows the interface, means it only deals with a type of object. The concrete function is delegated to the object that implements the interface.
The same approach has footprints all over Swing. To customize Swing, you basically replace some bolts and nuts. You won’t touch or rebuild the whole frame.
The second combo box is event driven searching.
//save the selection index from last search.
A method searchJCM is defined to conduct the search based on the string in the text field of the JComboBox object.
As you may see or feel, the first the approach is more flexible. Different searching algorisms can be easily plug-and-play. It’s the recommended method of customizing Swing components.