Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - How to show an input dialog having a dropdown list with an icon for each item?

I am using this Java code in my swing application to show an input dialog that has a drop-down selection list so a user can select an item from that list :

String[] carModelsArray = { "Honda", "Mitsubishi", "Toyota" };
String selectedValue = (String)JOptionPane.showInputDialog( null, "Select a car model from the list below:", "Car model...",
                                        JOptionPane.QUESTION_MESSAGE, 
                                        null, 
                                        carModelsArray,
                                        carModelsArray[ 0 ] );

This code works fine, but i was wondering if i can also add an icon for each item in the selection list, so the drop-down selection list would appear like this :

enter image description here

I have tried to set the items in this list as JLabel items, but the JLabel objects were all converted to String values when rendered inside the drop-down list as if it calls the JLabel.toString() method for each item in the list to get its value.

So is there a way to accomplish this ?

like image 639
Brad Avatar asked Sep 18 '25 00:09

Brad


2 Answers

Short answer, not the way you're doing it. Long answer, something more like...

enter image description here

import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.kaizen.icons.AddIcon;
import org.kaizen.icons.DeleteIcon01;
import org.kaizen.icons.DeleteIcon02;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                DefaultComboBoxModel model = new DefaultComboBoxModel<Car>();
                model.addElement(new Car(new AddIcon(16, 16), "Honda"));
                model.addElement(new Car(new DeleteIcon01(16, 16), "Mitsubishi"));
                model.addElement(new Car(new DeleteIcon02(16, 16), "Tyota"));

                JComboBox cb = new JComboBox(model);
                cb.setRenderer(new CarListCellRenderer());

                int result = JOptionPane.showConfirmDialog(null, cb, "Select a car model from the list below", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
                if (result == JOptionPane.OK_OPTION) {
                    Car car = (Car) cb.getSelectedItem();
                }

            }
        });
    }

    public static class CarListCellRenderer extends DefaultListCellRenderer {

        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            System.out.println(value);
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (value instanceof Car) {
                Car car = (Car) value;
                setIcon(car.getIcon());
                setText(car.getText());
            } else {
                setIcon(null);
            }
            return this;
        }

    }

    public static class Car {

        private Icon icon;
        private String text;

        public Car(Icon icon, String text) {
            this.icon = icon;
            this.text = text;
        }

        public Icon getIcon() {
            return icon;
        }

        public String getText() {
            return text;
        }

    }

}

Essentially, you need to take control over the combobox and provide your own custom ListCellRedender which can provide the output you desire...

like image 129
MadProgrammer Avatar answered Sep 19 '25 15:09

MadProgrammer


Thanks to MadProgrammer for his helpful answer, i was able to use his idea to find a solution for this. Here is how the final result looks like :

enter image description here

And here is the code i have used :

public class MyClass extends JFrame {
    private JComboBox inputComboBox = null;

    private void button6ActionPerformed() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JPanel inputPanel = createPanel();

                int result = JOptionPane.showConfirmDialog(null, inputPanel, "Car model...", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
                if (result == JOptionPane.OK_OPTION) {
                    System.out.println( (String)inputComboBox.getSelectedItem() );
                }
            }
        });   
    }

    private JPanel createPanel() {
        CellConstraints cc = new CellConstraints();

        //1. Create JPanel :
            JPanel inputPanel = new JPanel();
            inputPanel.setLayout(new FormLayout(
                new ColumnSpec[] {
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13)),
                    FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                    new ColumnSpec(Sizes.dluX(13))
                },
                new RowSpec[] {
                    new RowSpec(Sizes.dluY(13)),
                    FormFactory.LINE_GAP_ROWSPEC,
                    new RowSpec(Sizes.dluY(13)),
                    FormFactory.LINE_GAP_ROWSPEC,
                    new RowSpec(Sizes.dluY(13))
                }));

        //2. Create JLabel :
            JLabel inputLabel = new JLabel( "Select a car model from the list below :" );
            inputPanel.add( inputLabel, cc.xywh( 1, 1, 15, 1 ) );

        //3. Create ComboBox :
            DefaultComboBoxModel model = new DefaultComboBoxModel();
            model.addElement("Honda");
            model.addElement("Mitsubishi");
            model.addElement("Toyota");

            inputComboBox = new JComboBox( model );
            inputComboBox.setRenderer( new ComboBoxRenderer() );

            inputPanel.add( inputComboBox, cc.xywh(1, 3, 10, 2 ) );

         return inputPanel;
    }
}

class ComboBoxRenderer extends JLabel implements ListCellRenderer { 
    public Component getListCellRendererComponent(
                    JList list,
                    Object selectedCarModel,
                    int selectedModelIndex,
                    boolean isSelected,
                    boolean cellHasFocus) {
        //1. Set the list item text, icon & styling properties :
            String carModel = (String)selectedCarModel;
            String iconPath = "/images/" + carModel.toLowerCase() + ".png";  // The icon file should have the same name of the car model.
            URL iconURL = getClass().getResource( iconPath );

            setText( carModel );
            setIcon( new ImageIcon( iconURL ) );
            setPreferredSize( new Dimension( list.getWidth(), 30 ) );

        //2. Set the selected/deselected list item selection colors : 
            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

        return this;
    }
}
like image 28
Brad Avatar answered Sep 19 '25 16:09

Brad