Section 12.8. From the Java Library: javax.swing.JComboBox


[Page 588 (continued)]

12.8. From the Java Library: javax.swing.JComboBox

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

Figure 12.28. A JComboBox responds to action events and item events.
(This item is displayed on page 589 in the print version)


java.sun.com/docs


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 stored in the box's internal state (Fig. 12.29). 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.

Figure 12.29. Using a JComboBox box.
(This item is displayed on page 589 in the print version)



[Page 589]

As Figure 12.28 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 a 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 (getSelected-Index()). 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 ItemEvents 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.


[Page 590]

12.8.1. A JComboBox Example

As a simple example, let's design an applet 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 patternswe'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[] = {"Sierpinski Gasket","Nested Boxes"}; 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 applet's init() method. In fact, that's how we will initialize the levels menu:

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


This loop would be placed in the applet's init() method. 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 applet as the ItemListener for both menusthat is, the applet is named as the object that will handle the events that occur in the JComboBoxes. Then we add the JComboBox component to the applet's window:

controls.add(levels);                    // Control panel for menus controls.add(patterns); getContentPane().add(controls, "North"); // Add the controls getContentPane().add(canvas, "Center");  // And the drawing panel levels.addItemListener(this);            // Register the menus with a listener patterns.addItemListener(this); 


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 applet 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 JComboBoxes:


[Page 591]

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 applet is a container, this will cause all of its components to be repainted as well.

Figure 12.30 illustrates the sequence of events that occurs when an item is selected from a JComboBox. The complete implementation for the applet is given in Figure 12.31.

Figure 12.30. This UML sequence diagram shows the interaction between the various objects included in the action of selecting an item from a JComboBox.


Figure 12.31. The RecursivePatterns applet.

import java.awt.*; import javax.swing.*; import java.awt.event.*; public class RecursivePatterns extends JApplet implements ItemListener  {   private String choices[] = {"Sierpinski Gasket", "Nested Boxes"};   private JComboBox patterns = new JComboBox(choices); // Pattern choices   private JComboBox levels = new JComboBox();          // Level choices   private Canvas canvas = new Canvas();                // Drawing panel   private JPanel controls = new JPanel(); 
[Page 592]
public void init() { for (int k=0; k < 10; k++) // Add 10 levels levels.addItem(k + "" ); patterns.setSelectedItem(choices[0]); // Initialize menus levels.setSelectedItem("4"); canvas.setBorder(BorderFactory.createTitledBorder("Drawing Canvas")); controls.add(levels); // Control panel for menus controls.add(patterns); getContentPane().add(controls,"North"); // Add controls getContentPane().add(canvas,"Center"); // Add drawing panel levels.addItemListener(this); // Register menus with listener patterns.addItemListener(this); setSize(canvas.WIDTH,canvas.HEIGHT+controls.getSize().width); } // init() public void itemStateChanged(ItemEvent e) { canvas.setPattern(patterns.getSelectedIndex(),levels.getSelectedIndex()); repaint(); // Repaint the applet } // itemStateChanged() } // RecursivePatterns class

The actual drawing of the fractal patterns is handled by the canvas JPanel component. Its design is shown in Figure 12.32, and its implementation is given in Figure 12.33. All of the drawing is done in the paintComponent() method. Because the canvas is contained within the applet, the paintComponent() method is called automatically whenever the applet repaints itself. Note 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.

Zero indexing


Figure 12.32. Design of a drawing Canvas class.



[Page 593]

Figure 12.33. The Canvas class is a drawing panel.

import javax.swing.*; import java.awt.*; public class Canvas extends JPanel {   private static final int GASKET = 0, BOXES = 1;   public static final int WIDTH=400, HEIGHT=400;   private final int HBOX=10, VBOX=50, BOXSIDE=200, BOXDELTA=10;   private final int gP1X = 10;  private final int gP1Y = 280; // Initial   private final int gP2X = 290; private final int gP2Y = 280; // gasket   private final int gP3X = 150; private final int gP3Y = 110; // points   private int pattern = 0 ;                                   // Current pattern   private int level = 4;                                      // Current level   public Canvas() {     setSize(WIDTH, HEIGHT);   }   public void setPattern(int pat, int lev) {     pattern = pat;     level = lev;   }     public void paintComponent(Graphics g) {         g.setColor(getBackground());   // Redraw the panel's background         g.drawRect(0, 0, WIDTH, HEIGHT);         g.setColor(getForeground());         switch (pattern) {         case GASKET:             drawGasket(g, level, gP1X, gP1Y, gP2X, gP2Y, gP3X, gP3Y);             break;         case BOXES:             drawBoxes(g, level, HBOX, VBOX, BOXSIDE, BOXDELTA );             break;         } // switch     } // paintComponent()    /*     * drawGasket()---recursively draws the Sierpinski     * gasket pattern, with points (p1X, p1Y), (p2X, p2Y), (p3X, p3Y)     * representing the vertices of its enclosing triangle.     * level (>=0) is the recursion parameter (base case: level 0)     */     private void drawGasket(Graphics g, int lev, int p1X, int p1Y,                    int p2X, int p2Y, int p3X, int p3Y) {         g.drawLine(p1X, p1Y, p2X, p2Y); // Draw a triangle         g.drawLine(p2X, p2Y, p3X, p3Y);         g.drawLine(p3X, p3Y, p1X, p1Y);         if (lev > 0) {                  // If more levels, draw 3 smaller gaskets             int q1X = (p1X + p2X) / 2;    int q1Y = (p1Y + p2Y) / 2;             int q2X = (p1X + p3X) / 2;    int q2Y = (p1Y + p3Y) / 2;             int q3X = (p2X + p3X) / 2;    int q3Y = (p2Y + p3Y) / 2;             drawGasket(g, lev - 1, p1X, p1Y, q1X, q1Y, q2X, q2Y);             drawGasket(g, lev - 1, p2X, p2Y, q1X, q1Y, q3X, q3Y);             drawGasket(g, lev - 1, p3X, p3Y, q2X, q2Y, q3X, q3Y);         }     } // drawGasket() 
[Page 594]
/* * drawBoxes()---recursively draws pattern of nested squares * with (locX, locY) the top left corner of outer the square and * side being the length square's side. * level (>= 0) is the recursion parameter (base case: level 0) * delta is used to adjust the length of the side. */ private void drawBoxes(Graphics g, int level, int locX, int locY, int side, int delta) { g.drawRect(locX, locY, side, side ); if (level > 0) { int newLocX = locX + delta; int newLocY = locY + delta; drawBoxes(g, level - 1, newLocX, newLocY, side - 2 * delta, delta); } } // drawBoxes() } // Canvas class




Java, Java, Java(c) Object-Orienting Problem Solving
Java, Java, Java, Object-Oriented Problem Solving (3rd Edition)
ISBN: 0131474340
EAN: 2147483647
Year: 2005
Pages: 275

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