I l@ve RuBoard |
![]() ![]() |
7.6 Combo BoxesA combo box component is actually a combination of a Swing list (embedded in a pop-up window) and a text field. Because combo boxes contain a list, many of the classes discussed in the first part of this chapter are used here as well. Unlike lists, a combo box allows the user only one selection at a time, which is usually copied into an editable component at the top, such as a text field. The user can also manually enter a selection (which does not need to be on the list). Figure 7-10 shows a high-level class diagram for Swing's combo box classes. Figure 7-10. Swing combo box class diagram![]() Like lists, the combo box component uses a data model to track its list data; the model is called ComboBoxModel. 7.6.1 The ComboBoxModel InterfaceThe ComboBoxModel interface extends the ListModel interface and is used as the primary model for combo box data. It adds two methods to the interface, setSelectedItem( ) and getSelectedItem( ), thus eliminating the need for a separate selection model. Since a JComboBox allows only one selected item at a time, the selection "model" is trivial and is collapsed into these two methods. Because the data of the ComboBoxModel is stored in an internal list, the ComboBoxModel also reuses the ListDataEvent to report changes in the model state. However, with the addition of methods to monitor the current selection, the model is now obligated to report changes in the selection as well, which it does by firing a modification ListDataEvent with both endpoints as -1. Again, you should always query the event source to determine the resulting change in the elements. You can create your own ComboBoxModel or use the default provided with the JComboBox class. The default model is an inner class of JComboBox. If you need to create your own, it is (as before) a good idea to extend the AbstractListModel class and go from there. 7.6.1.1 PropertyTable 7-11 shows the property defined by the ComboBoxModel interface. The selected-Item property lets you set or retrieve the currently selected object.
7.6.1.2 EventsThe ComboBoxModel interface reuses the ListDataEvent to indicate that the selection or the contents of the list has changed. No new event-related methods are added to the ComboBoxModel interface. 7.6.2 The MutableComboBoxModel InterfaceIn addition to the ComboBoxModel, which supports unchanging lists of choices, Swing defines MutableComboBoxModel. This model, which extends the ComboBoxModel interface, adds four new methods to support changes to the list:
A data model that implements the MutableComboBoxModel interface also implements ComboBoxModel and ListModel, which gives the model the ability to add, remove, and retrieve elements; set a selection; and support change listeners. 7.6.3 The DefaultComboBoxModel ClassIf you're getting lost with all these interfaces, don't despair: Swing provides a DefaultComboBoxModel that implements each of these interfaces. This probably works in almost any situation where you'd want to use a combo box. Table 7-12 shows the properties of the DefaultComboBoxModel class. The indexed elementAt property allows you to retrieve any particular element in the list. The selectedItem property points to the currently selected item in the model. Note that the setSelectedItem( ) method fires a modification ListDataEvent, specifying both endpoints of the "change" as -1 to indicate that the selection has changed. Finally, the read-only size property lets you find out the number of elements in the vector.
7.6.3.1 Constructors
7.6.3.2 Methods
7.6.3.3 EventThe DefaultComboBoxModel interface reuses the ListDataEvent to indicate that the contents of the model or its selection have changed. See Table 7-13.
Because it extends AbstractListModel, DefaultComboBoxModel provides all the listener-registration methods described earlier in this chapter: addListDataListener( ), removeListDataListener( ), getListeners( ) (since SDK 1.3), and getListDataListeners( ) (since SDK 1.4). 7.6.4 ComboBoxEditorComboBoxEditor is an interface that defines a component used for editing in the combo box. By default, JComboBox uses a text field for its editor. However, you can create your own combo box editor by implementing the methods of this interface. Creating your own combo box editor takes a bit of imagination. You might notice that the methods are heavily biased toward text editing. This is not a coincidence since most of the editable components in Swing deal with text. However, there is nothing to prevent you from mixing various components together, including some of your own invention, and using the editor interface to specify how they react. 7.6.4.1 PropertiesThe ComboBoxEditor interface defines the two properties shown in Table 7-14. The editorComponent can be used to edit the contents of a field in the combo box. The getEditorComponent( ) accessor is typically called once, when the combo box is first displayed. You would implement this method to return the component you want to use for editing.
The item property is the object being edited. The setItem( ) mutator lets the editor know which item is being edited; it is called after the user selects an item from the list or completes an edit (e.g., by pressing Enter in a text field). The getItem( ) accessor returns the item currently being edited. 7.6.4.2 EventsThe ComboBoxEditor interface uses an ActionListener to indicate that the user has finished modifying the item in the ComboBoxEditor. For example, the default text editor of the combo box component fires this event after the user finishes typing in the text box and presses Enter. After the editing has been completed, the combo box generally calls setItem( ) to ensure that the results are set correctly in the editor.
7.6.4.3 Method7.6.5 Implementing a Custom EditorThe following example shows a simple custom editor for a combo box: // ComboBoxEditorExample.java // import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; public class ComboBoxEditorExample implements ComboBoxEditor { Map map; ImagePanel panel; ImageIcon questionIcon; public ComboBoxEditorExample(Map m, BookEntry defaultChoice) { map = m; panel = new ImagePanel(defaultChoice); questionIcon = new ImageIcon("question.gif"); } public void setItem(Object anObject) { if (anObject != null) { panel.setText(anObject.toString( )); BookEntry entry = (BookEntry)map.get(anObject.toString( )); if (entry != null) panel.setIcon(entry.getImage( )); else panel.setIcon(questionIcon); } } public Component getEditorComponent( ) { return panel; } public Object getItem( ) { return panel.getText( ); } public void selectAll( ) { panel.selectAll( ); } public void addActionListener(ActionListener l) { panel.addActionListener(l); } public void removeActionListener(ActionListener l) { panel.removeActionListener(l); } // We create our own inner class to set and repaint the image and text. class ImagePanel extends JPanel { JLabel imageIconLabel; JTextField textField; public ImagePanel(BookEntry initialEntry) { setLayout(new BorderLayout( )); imageIconLabel = new JLabel(initialEntry.getImage( )); imageIconLabel.setBorder(new BevelBorder(BevelBorder.RAISED)); textField = new JTextField(initialEntry.getTitle( )); textField.setColumns(45); textField.setBorder(new BevelBorder(BevelBorder.LOWERED)); add(imageIconLabel, BorderLayout.WEST); add(textField, BorderLayout.EAST); } public void setText(String s) { textField.setText(s); } public String getText( ) { return (textField.getText( )); } public void setIcon(Icon i) { imageIconLabel.setIcon(i); repaint( ); } public void selectAll( ) { textField.selectAll( ); } public void addActionListener(ActionListener l) { textField.addActionListener(l); } public void removeActionListener(ActionListener l) { textField.removeActionListener(l); } } } This example is tightly coupled with the example for the JComboBox class (later in the chapter). However, the source is not hard to understand. When the combo box is initialized, Swing calls getEditorComponent( ) to position and paint the combo box editor at the top of the JComboBox component. This is our inner class, and essentially consists of a JPanel with both the name of a book and its cover image. The user is allowed to interact freely with the text field. Whenever the user selects a list element or completes an edit in the text field, the setItem( ) method is called to update the book icon. If an icon cannot be found for the text, a question mark is displayed. Whenever the editor needs to retrieve the currently edited object, it makes a call to getItem( ). Note that our addActionListener( ) and removeActionListener( ) methods pass the listener to the JTextField defined in the editor. |
I l@ve RuBoard |
![]() ![]() |