The JComboBox class is a graphical component that allows you to select an item from a drop-down list. After the selection, only the selected item is displayed. The remaining items are displayed in a pop-up window when the list is opened. Usually, ComboBox elements are strings, but they can be any displayable objects. By default, ComboBox items are uneditable.

Creating a JComboBox component

JComboBox is a generic class declared like this: JComboBox<E>, where E represents the type of items in the list box. Let’s start by creating a JComboBox component. It offers several ways to create and add elements.

JComboBox() creates an empty combo box. Then, you can add items to it using the addItem(E item) method.

JComboBox<String> comboBox = new JComboBox<>();
comboBox.addItem("Corgi");
comboBox.addItem("Dog");
comboBox.addItem("Hound");
comboBox.addItem("Lapdog");

There is another way to create an instance. JComboBox(ComboBoxModel<E> model) creates a JComboBox that uses the ComboBoxModel model. The properties of the JComboBox model are defined by the ComboBoxModel<E> interface which is implemented by DefaultComboBoxModel<E> standard class.

DefaultComboBoxModel<String> comboBoxModel = new DefaultComboBoxModel<>();
String[] dogsStr = { "Corgi", "Dog", "Hound", "Lapdog" };
for (String dog : dogsStr) {
    comboBoxModel.addElement(dog);
}
JComboBox comboBox = new JComboBox(comboBoxModel);

It is possible to create JComboBox from an array using the JComboBox(E[] items) constructor.

String[] dogsStr = { "Corgi", "Dog", "Hound", "Lapdog" };
JComboBox comboBox = new JComboBox(dogsStr);

Uneditable JComboBox

The uneditable ComboBox allows you to select values from a list but doesn’t support updates. Let’s create a combo box based on an array of strings representing different countries: "Ethiopia", "Turkey", "Greece", "Iraq", "Serbia", "Colombia".

import javax.swing.*;
import java.awt.*;

class Country {
    private final static String[] COUNTRIES = { "Ethiopia", "Turkey", "Greece", "Iraq", "Serbia", "Colombia" };

    public void start() {
        JFrame frame = createFrame();

        JComboBox<String> comboBox = createComboBox();
        frame.add(comboBox);

        frame.setVisible(true);
    }

    private JFrame createFrame() {
        JFrame frame = new JFrame("Country");
        frame.setLayout(new FlowLayout());
        frame.setSize(300, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        return frame;
    }

    private JComboBox<String> createComboBox() {
        DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(COUNTRIES);
        JComboBox<String> comboBox = new JComboBox<>(model);
        comboBox.setSelectedIndex(0); // choose the default option

        return comboBox;
    }
}

class CountryDemo {
    public static void main(String[] args) {
        Country country = new Country();
        country.start();
    }
}

Detect combo box value changes

Sometimes, we may want to perform some actions after a user has selected a combo box option. It is pretty simple: you just need to register a listener:

comboBox.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        System.out.println("Combobox value was changed");
    }
});

We can simplify the same piece of code by using a lambda expression:

comboBox.addActionListener(actionEvent -> System.out.println("Combobox value was changed"));

Now let’s rewrite the example by displaying the capital city of the selected country. Here we have created an array of capitals put in the same order as the countries. To display the capital in the interface, we use JLabel:

import javax.swing.*;
import java.awt.*;

class CountryCapital {
    private final static String[] COUNTRIES = { "Ethiopia", "Turkey", "Greece", "Iraq", "Serbia", "Colombia" };
    private final static String[] CAPITALS = { "Addis Ababa", "Ankara", "Athens", "Baghdad", "Belgrade", "Bogota" };

    public void start() {
        JFrame frame = createFrame();

        JComboBox<String> comboBox = createComboBox();
        frame.add(comboBox);

        JLabel label = createLabel(comboBox.getSelectedIndex());
        frame.add(label);

        comboBox.addActionListener(actionEvent -> label.setText(CAPITALS[comboBox.getSelectedIndex()]));

        frame.setVisible(true);
    }

    private JFrame createFrame() {
        JFrame frame = new JFrame("Country and Capital");
        frame.setLayout(new FlowLayout());
        frame.setSize(300, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        return frame;
    }

    private JComboBox<String> createComboBox() {
        DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(COUNTRIES);
        JComboBox<String> comboBox = new JComboBox<>(model);
        comboBox.setSelectedIndex(0); // choose the default option

        return comboBox;
    }

    private JLabel createLabel(int selectedIndex) {
        JLabel label = new JLabel();
        label.setText(CAPITALS[selectedIndex]);
        label.setHorizontalAlignment(SwingConstants.CENTER);

        return label;
    }
}

class CountryCapitalDemo {
    public static void main(String[] args) {
        CountryCapital countryCapital = new CountryCapital();
        countryCapital.start();
    }
}

Editable JComboBox

Imagine that you need to write a program that displays the date and time as a combo box. In the drop-down list, you can select the date and time formatting option. If we stopped there, it would be an uneditable combo box. But we will add the possibility to edit formatting options and remember new options in the combo box list.

Our editable combo box may look like this:

The picture shows that the editor window is active. We can edit the value of combo box elements in place. To activate this feature, use a setter method:

comboBox.setEditable(true);

In the example below, to make the program display the current time we use the Timer class. It invokes updating of representing time every second. This way, you can see the updates in real time. Another class SimpleDateFormat helps to display the current date in a convenient human-readable format.

By registering a listener, we can detect edit changes of list items. To distinguish one combo box edit event from another use the actionEvent.getActionCommand() method. If there is an edit event, the returned value is "comboBoxEdited". In the example below, we add an updated item as a new element to the list.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class TimeFormatting {
    private static final String[] DATE_TIME_PATTERNS = {
            "dd.MM.yyyy HH:mm:ss",
            "dd.MM.yyyy, EEEE, HH:mm:ss",
            "yyyy MMMMM dd GGG hh:mm:ss aaa",
    };

    public void start() {
        JFrame frame = createFrame();

        JComboBox<String> comboBox = createComboBox();
        frame.add(comboBox);

        JLabel label = createLabel();
        frame.add(label);

        comboBox.addActionListener(actionEvent -> onComboBoxChanged(comboBox, actionEvent));

        // Timer periodically (with the interval of 1 sec) updates the current time
        Timer timer = new Timer(1000, actionEvent -> updateCurrentTime(label, comboBox));
        timer.start();

        frame.setVisible(true);
    }

    private JFrame createFrame() {
        JFrame frame = new JFrame("Current date and time");
        frame.setLayout(new FlowLayout());
        frame.setSize(300, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        return frame;
    }

    private JComboBox<String> createComboBox() {
        DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(DATE_TIME_PATTERNS);
        JComboBox<String> comboBox = new JComboBox<>(model);
        comboBox.setEditable(true);

        return comboBox;
    }

    private JLabel createLabel() {
        JLabel label = new JLabel();
        label.setHorizontalAlignment(JLabel.CENTER);

        return label;
    }

    private void onComboBoxChanged(JComboBox<String> comboBox, ActionEvent actionEvent) {
        // Getting the command that the combo box generates
        String command = actionEvent.getActionCommand();
        // Detecting whether the action command is "comboBoxEdited"
        if ("comboBoxEdited".equals(command)) {
            // If the item has been changed
            if (comboBox.getSelectedIndex() == -1) {
                // Getting the value of the changed element
                String newValue = (String) comboBox.getSelectedItem();
                // Adding a new item to the list
                comboBox.addItem(newValue);
            }
        }
    }

    private void updateCurrentTime(JLabel label, JComboBox<String> comboBox) {
        // Get the selected time format from the combo box
        String selectedFormat = (String) comboBox.getSelectedItem();
        if (selectedFormat != null) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(selectedFormat, Locale.US);
            String currentTimeFormatted = dateFormat.format(new Date());
            label.setText(currentTimeFormatted);
        }
    }
}

class TimeFormattingDemo {
    public static void main(String[] args) {
        TimeFormatting timeFormatting = new TimeFormatting();
        timeFormatting.start();
    }
}

Editable combo box is perfectly suitable for cases when a user needs to extend given options. Depending on the case, you can add an action listener which helps to store modified options as well. As a result, the combo box will show such modified options next time.

Conclusion

JComboBox is a Swing graphic component that allows us to select an item from a drop-down list. It can be editable and uneditable. The uneditable combo box is created by default and only allows us to select from a list, whereas the editable combo box allows us to edit the contents of the list. It is also possible to detect changes and other events, such as selecting or editing an item from a list by registering a listener implementing the ActionListener class. To simplify the listener code, use a lambda expression.

Leave a Reply

Your email address will not be published.