7.6 Combo Boxes


A 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
figs/swng2.0710.gif

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 Interface

The 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 Property

Table 7-11 shows the property defined by the ComboBoxModel interface. The selected-Item property lets you set or retrieve the currently selected object.

Table 7-11. ComboBoxModel property

Property

Data type

get

is

set

Default value

selectedItem

Object

·

 

·

 

See also properties of the ListModel interface (Table 7-1).

7.6.1.2 Events

The 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 Interface

In 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:

public abstract void addElement(Object obj)

Add a specific element to the data model.

public abstract void removeElement(Object obj)

Remove a specific element from the data model.

public abstract void insertElementAt(Object obj, int index)

Insert a specific element at the given index.

public abstract void removeElementAt(int index)

Delete a specific element from 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 Class

If 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.

Table 7-12. DefaultComboBoxModel properties

Property

Data type

get

is

set

Default value

elementAt

Object

·

   

null

selectedItemo

Object

·

 

·

null

size

int

·

   

0

ooverridden

7.6.3.1 Constructors
public DefaultComboBoxModel( )
public DefaultComboBoxModel(Object items[])
public DefaultComboBoxModel(Vector v)

Create a default combo box model, perhaps using an array or vector to initialize the data model. In the first case, an empty model is created. In the second, the objects in the items variable are copied into a new model. In the third case, an existing vector is installed into the model.

7.6.3.2 Methods
public void addElement(Object obj)

Add a specific element to the data model, firing a ListDataEvent that describes the addition.

public void removeElement(Object obj)

Remove a specific element from the data model, firing a ListDataEvent that describes the removal.

public void removeAllElements( )

Remove all elements from the data model, firing a ListDataEvent that describes the removal.

public void insertElementAt(Object obj, int index)

Insert an element at the specified index, firing a ListDataEvent that describes the insertion.

public void removeElementAt(int index)

Delete a specific element from the list, firing a ListDataEvent that describes the removal.

public int getIndexOf(Object obj)

Return the index of the object referenced by the variable obj, or -1 if it's not found.

7.6.3.3 Event

The DefaultComboBoxModel interface reuses the ListDataEvent to indicate that the contents of the model or its selection have changed. See Table 7-13.

Table 7-13. DefaultComboBoxModel event

Event

Description

ListDataEvent

Indicates that a change in the contents of the combo box model has occurred (which includes the current selection)

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 ComboBoxEditor

ComboBoxEditor 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 Properties

The 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.

Table 7-14. ComboBoxEditor properties

Property

Data type

get

is

set

Default value

editorComponent

Component

·

     

item

Object

·

 

·

 

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 Events

The 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.

public abstract void addActionListener(ActionListener l)
public abstract void removeActionListener(ActionListener l)

Add or remove a specific listener interested in receiving ActionEvents concerning the item currently being edited.

7.6.4.3 Method
public abstract void selectAll( )

Select all content within the editable region.

7.6.5 Implementing a Custom Editor

The 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.



Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net