## Section12.9From the Java Library: javax.swing.JComboBox

JComboBox is a Swing component that combines a text field and a drop-down list (Figure 12.9.1). It lets the user either type in a selection or choose a selection from a list that appears when the user requests it—a JComboBox's drop-down behavior is somewhat similar to a java.awt.Choice box.

A JComboBox can be used to represent a drop-down menu. When the user clicks on a JComboBox, a list of options drops down, and the user can select a particular option that is stored in the box's internal state (Figure 12.9.2).

The list of options associated with a JComboBox can be built beforehand and inserted into the component in a constructor, or items can be inserted one at a time by repeatedly using its addItem() method.

As Figure 12.9.1 shows, either an array or a vector of items can be passed to a constructor method to initialize the box's menu. The items stored in a JComboBox box are references to Objects, most commonly Strings that represent the name of the menu item. They are stored in the (zero indexed) order in which they are added. The addItem() method is used to add an individual Object to a JComboBox. By default, the first item added to a JComboBox will be the selected item until the user selects another item.

When the user makes a selection in a JComboBox, the item selected can be gotten either by its reference (getSelectedItem()) or by its position within the menu (getSelectedIndex()). There are also methods to setSelectedItem() and setSelectedIndex() that let you select an individual item either by its reference or its position. The addItemListener() method is used to designate some object as the listener for the ItemEvent s that are generated whenever the user selects a menu option. Alternatively, the addActionListener() method lets you handle action events, such as when the user types a value into the box.

### Subsection12.9.1A JComboBoxExample

As a simple example, let's design an graphical interface that can be used to display the fractal patterns we developed earlier. We want an interface that lets the user select from among the available patterns—we'll use the Sierpinski gasket and nested boxes for starters. In addition, the user should also be able to select different levels for the drawings, from 0 to 9. We want to present these options in two menus, with one JComboBox for each menu.

The first step is to declare and instantiate the JComboBoxes as instance variables:

private String items[] =
private JComboBox patterns = new JComboBox(items);
private JComboBox levels = new JComboBox();


Note that in this case we pass the constructor for the patterns menu an entire array of items. If we hadn't done it this way, we would add individual items to the combo box in the JFrame's constructor RecursivePatterns(). In fact, that's how we'll initialize the levels menu:

for (int k=0; k < 10; k++)   // Add 10 levels
levels.setSelectedItem("4"); // Select default level


This loop would be placed in the JFrame's constructor,  RecursivePatterns(). It adds strings representing levels 0 to 9 to the menu and initializes the box so that level four is showing as the default option.

Our next step is to designate the JFrame as the ItemListener for both menus—that is, the JFrame is named as the object that will handle the events that occur in the JComboBoxes. Then we add the JComboBox component to the JFrame:

controls.add(levels);    // Control panel for menus

getContentPane().add(canvas, "Center");   // And drawing panel



Note that we use a separate controls panel (a JPanel) for the two menus and a canvas panel (another JPanel) for the drawings.

The next step is to implement the itemStateChanged() method to handle the user's selections. Whenever the user selects an item from a JComboBox menu, an ItemEvent is generated. In order to handle these events, the program must implement the ItemListener interface, which consists of the single method itemStateChanged(). This method is invoked automatically whenever the user selects an item from one of the JComboBox es:

public void itemStateChanged(ItemEvent e) {
canvas.setPattern(patterns.getSelectedIndex(),
levels.getSelectedIndex());
repaint();
}


The itemStateChanged() method has the same general form as the actionPerformed() method, except that its parameter is an ItemEvent . For this example, the program uses the getSelectedIndex() method to get the selected pattern and the selected level by their respective item numbers within the menus. It then passes these values along to the canvas object, which takes care of the drawing. Finally, the method invokes the repaint() method. Because the JFrame is a container, this will cause all of its components to be repainted as well.

The complete implementation for the program is given in Listing 12.9.3.

The actual drawing of the fractal patterns is handled by the canvas JPanel component, whose design is shown in Figure 12.9.4 and whose implementation is given in Figure 12.9.5. All of the drawing is done in the paintComponent() method. Because the canvas is contained within the JFrame, the paintComponent() method is called automatically whenever the JFrame repaints itself. Notice how the switch statement uses the pattern that the user chose to call the corresponding drawing method. You can see from this switch statement that a JComboBox's items are zero indexed.

#### ExercisesSelf-study Exercises

##### 1.Recursive Patterns.
1. Write a revised drawBoxes() method that reduces the length of the side at each level by a fixed ratio of the length of the side, for example, 10 percent.

2. Add your revised method to the RecursivePatterns program as a third pattern.