# 9

## JCComboBox

Introduction · Sample Program Code · Setting Combobox Style

Combobox Appearance · Combobox Sizing · Events

Property Listing · Example Program

### Introduction

A combobox is a standard GUI component common to most window systems. A combobox is essentially a control that combines a text box with a list box. It allows users to perform operations like typing and pasting information, and it also provides a list of possible choices that a user can select from.

`JCComboBox` is essentially a combination of two other JClass BWT components: `JCTextField` and `JCArrowButton` . `JCCombobox` comes in two basic forms: a permanent drop-down list that contains an editable field, and an uneditable drop-down list that appears only when the user presses an arrow button next to the text field. This latter is commonly called a "drop-down" combobox.

While a combobox (called `Choice` ) is provided within the AWT of the JDK 1.1, a peer of the MS-Windows combobox is used, restricting its use to that platform. `JCComboBox` provides this functionality across all platforms.

#### Behavior

`JCComboBox` behaves in the following way:

- as text is typed into the text field, the list scrolls to the nearest match
- when a user clicks an item within a combobox, the selected item is highlighted and appears in the text field

#### Keyboard Traversal

If an item is clicked or RETURN is hit, the item is copied to the text field. If the arrow button is pressed (using CTRL-DOWN) and released on a drop-down combobox, the list appears and persists until the user clicks an item inside it, hits ENTER, clicks outside the list, or presses ESCAPE.

The following illustration displays all of the most common ways users interact with combobox components.

#####

##### combobox user interactions

### Sample Program Code

The following code shows how a `JCComboBox can be incorporated into a program:`

    package jclass.bwt.examples;
    import jclass.bwt.BWTEnum;
    import jclass.bwt.JCComboBox;
    import jclass.bwt.JCGridLayout;
    import jclass.bwt.JCGroupBox;
    import jclass.bwt.JCLabel;
    import jclass.contrib.ContribFrame;
    import jclass.util.JCUtilConverter;
    import java.awt.*;
    import jclass.bwt.JCActionEvent;
    import jclass.bwt.JCActionListener;
    import jclass.bwt.JCItemEvent;
    import jclass.bwt.JCItemListener;

    /**
     * This example demonstrates various types of JCComboBoxes and events
     */
    public class comboBox extends java.applet.Applet
    implements JCActionListener, JCItemListener {

    JCLabel label;
    static int font_style_values[] = {
    	Font.PLAIN, Font.BOLD, Font.ITALIC,
    };
    static String font_style_names[] = {
    	"plain", "bold", "italic",
    };
    static String font_size_names[] = {
    	"12", "14", "15", "20", "30", "40"
    };
    static String color_names[] = {
    	"Black", "Blue", "Cyan", "DarkGray", "Gray", "Green", "LightGray",
    	"LightBlue", "Magenta", "Orange", "Pink", "Red", "Yellow",
    };

    JCComboBox names, styles, sizes, colors;

    // ItemListener method
    public void itemStateChanged(JCItemEvent ev) {
    	if (ev.getStateChange() == JCItemEvent.DESELECTED) return;
    	JCComboBox box = (JCComboBox) ev.getSource();
    	setLabel(box, box.getSelectedItem(), box.getSelectedIndex());
    }

    // ActionListener method
    public void actionPerformed(JCActionEvent ev) {
    	JCComboBox box = (JCComboBox) ev.getSource();
    	setLabel(box, box.getText(), BWTEnum.NOVALUE);
    }

    void setLabel(JCComboBox box, String value, int row) {
    	Font font = label.getFont();
    	if (box.getName() .equals("names"))
    		font = new Font(value, font.getStyle(), font.getSize());
    	else if (box.getName() .equals("styles"))
    		font = new Font(font.getName(), font_style_values[row], font.getSize());
    	else if (box.getName() .equals("sizes"))
    		font = new Font(font.getName(), font.getStyle(), Integer.parseInt(value));
    	else if (box.getName() .equals("colors")) {
    		Color c = JCUtilConverter.toColor(value);
    		if (c != null)
    			label.setForeground(c);
    		else
    			box.getTextField().beep();
    	}

    	label.setFont(font);
    }

    public void init() {
    	setBackground(Color.lightGray);
        String font_names[] = getToolkit().getFontList();
    	setLayout(new JCGridLayout(BWTEnum.VARIABLE, 1, 10, 10));

    	Panel panel = new Panel();
    	panel.setLayout(new JCGridLayout(1, 3, 10, 10));
    	add(panel);

    	names = new JCComboBox(font_names, "names");
    	names.setStyle(BWTEnum.COMBOBOX_SIMPLE);
    	names.getTextField().setColumns(10);
    	names.addActionListener(this);
    	names.addItemListener(this);

    	JCGroupBox box = new JCGroupBox("Name");
    	box.add(names);
    	panel.add(box);

    	styles = new JCComboBox(font_style_names, "styles");
    	styles.setStyle(BWTEnum.COMBOBOX_SIMPLE);
    	styles.getTextField().setColumns(10);
    	styles.getTextField().setEditable(false);
    	styles.getTextField().setShowCursorPosition(false);
    	styles.addActionListener(this);
    	styles.addItemListener(this);

    	box = new JCGroupBox("Style");
    	box.add(styles);
    	panel.add(box);

    	sizes = new JCComboBox(font_size_names, "sizes");
    	sizes.setStyle(BWTEnum.COMBOBOX_SIMPLE);
    	sizes.getTextField().setColumns(5);
    	sizes.addActionListener(this);
    	sizes.addItemListener(this);

    	box = new JCGroupBox("Size");
    	box.add(sizes);
    	panel.add(box);

    	panel = new Panel();
    	panel.setLayout(new JCGridLayout(1, 3, 10, 10));
    	add(panel);

    	colors = new JCComboBox(color_names, "colors");
    	colors.getTextField().setColumns(10);
    	colors.addActionListener(this);
    	colors.addItemListener(this);
    	panel.add(colors);

    	label = new JCLabel("Sample text");
    	label.setBackground(Color.white);
    	label.setPreferredSize(200, BWTEnum.NOVALUE);
    	panel.add(label);
    }

    public void start() {
    	super.start();

    	// Select the items in each list which match the current font.
    	names.select(getFont().getName());
    	sizes.select(""+getFont().getSize());
    	int style = getFont().getStyle();
    	if (style < font_style_names.length)
    		styles.select(font_style_names[style]);
    	if (label.getForeground() .equals(Color.black))
    		colors.select("Black");
    }

    public static void main(String args[]) {
    	ContribFrame frame = new ContribFrame("ComboBox");
    	comboBox s = new comboBox();

    	s.init();
    	frame.add(s);
    	frame.pack();
    	frame.show();

    	s.start();
    }
    }

When this program is compiled and run, the following appears:

#####

##### A program incorporating several JCComboBoxes

When a drop-down combobox component is created, two child components are also created: a Text component, called the text field, which contains the currently selected item, and an arrow component that the user clicks on to change the current item. When the combobox first appears, the text field is empty, since the end-user has not yet selected an item.

This sample code is incorporated into the example file `comboBox.class` provided with JClass BWT. For information on how to run this program, see the " Example Program" section at the end of this chapter.

### Setting Combobox Style

The `Style` property sets the type of combobox that is displayed. It determines whether a list is always displayed and whether the text field is editable. If the list is hidden, it can be displayed by pressing the arrow button or hitting the down or up arrow key. Style can take one of the following three values: `COMBOBOX_SIMPLE`, `COMBOBOX_DROPDOWN` and `COMBOBOX_DROPDOWN_LIST`. `COMBOBOX_SIMPLE` always displays the list and the text field is editable. The other two values set up two different types of drop-down comboboxes: `COMBOBOX_DROPDOWN` (default) displays a drop-down whose text field is editable, and `COMBOBOX_DROPDOWN_LIST` displays a drop-down list whose text field is uneditable.

### Combobox Appearance

There are several properties which can be used to customize the display of a `JCComboBox`. The `Background` and `Foreground` properties can be used to set the color of the background and text/foreground elements of a `JCComboBox`. `Foreground` not only sets the color of any alphanumeric characters contained in the text field, but also of the arrow buttons and of the cursor within the text field.

The display of fonts within a `JCComboBox` is controlled by the `Font` property. For a listing of available fonts, see Appendix A: Colors and Fonts.

### Combobox Sizing

The size of a `JCComboBox` can be set using the `PreferredSize` property, which sets the container's preferred size. If either dimension is set to `NOVALUE`, it is calculated by the subclass.

The individual `PreferredWidth` and `PreferredHeight` methods each deal with the subclass' preferred width (default: 100). The subclass should not include the inset sizes in its calculation, as these are added by `JCComboBox`.

The display of the text field contained within a `JCComboBox` is controlled by the `VisibleRows` and `Columns` properties. `VisbleRows` takes an integer value equal to the number of rows to be displayed. If `VisibleRows` is set to 0 (default), the list attempts to resize itself so that four of its items are visible. The `Columns` property sets the width of a text field as a number of "en" spaces (i.e. spaces defined by the capital letter "N").

### Events

A class can be notified when the user presses the ENTER key within a `JCComboBox` by implementing the `JCActionListener` interface and registering itself with the combobox, as the following code demonstrates via `addActionListener`:

    public interface JCActionListener {
            public void actionPerformed(JCActionEvent e);
    }
    public class JCActionEvent {
            // Returns the component where the event originated.
            public Object getSource()
            // Returns the event type: ACTION_PERFORMED.
            public int getId()
    }
    A class can be notified when the user selects an item in the list by implementing the JCItemListener interface and registering itself with the comboBox via addItemListener:
    public interface JCItemListener {
            public void itemStateChanged(JCItemEvent e);
    }
    public class JCItemEvent {
            // Returns the component where the event originated.
            public Object getSource()
            // Returns the event type: ITEM_STATE_CHANGED.
            public int getId()
            // Returns the item where the event occurred.
            public Object getItem()
            // Returns the state change type which generated the event: SELECTED or DESELECTED
            public int getStateChange()
    }

A class can be notified before the list is displayed, and after the user has made a selection, by implementing the `JCComboBoxListener` interface and registering itself with the combobox via `addComboBoxListener`, as in the following example:

    public interface JCComboBoxListener {
            // Invoked before the list is displayed. The event's values can be modified via its setValue method.
            public void comboBoxListDisplayBegin(JCComboBoxEvent e);
            // Invoked after the user has made a selection. Any changes made to the event   are ignored.
    public void comboBoxListDisplayEnd(JCComboBoxEvent e);
    }
    public class JCComboBoxEvent {
            // Returns the component where the event originated.
            public Object getSource()
            // Returns the event type: ACTION_PERFORMED.
            public int getId()
            // Gets the value that will be copied to the text field.
            public Object getValue()
            // Sets the value that will be copied to the text field.
            public void setValue(Object v)
    }

### Property Listing

The following is a listing of available properties for `JCComboBox.`

#### jclass.bwt.JCComboBox

#####

Name | Method | Inherited from
--- | --- | ---
`Background` | `setBackground` | `jclass.bwt.JCContainer`
`DoubleBuffer` | `setDoubleBuffer` | `jclass.bwt.JCContainer`
`Font` | `setFont` | `jclass.bwt.JCContainer`
`Foreground` | `setForeground` | `jclass.bwt.JCContainer`
`Items` | `setItems` | `jclass.bwt.JCComboBox`
`Insets` | `setInsets` | `jclass.bwt.JCContainer`
`PreferredSize` | `setPreferredSize` | `jclass.bwt.JCContainer`
`Style` | `setStyle` | `jclass.bwt.JCComboBox`
`Text` | `setText` | `jclass.bwt.JCComboBox`
`UserData` | `setUserData` | `jclass.bwt.JCContainer`
`VisibleRows` | `setVisibleRows` | `jclass.bwt.JCComboBox`

### Example Program

Demonstration programs and example code containing `JCComboBox` come with JClass BWT. The examples can be viewed in applet form by launching index.html within the /jclass/bwt/examples directory.combobox.class can also be run as a stand-alone Java application from the command prompt by typing:

         java jclass.bwt.examples.comboBox