This tutorial helps you building a JComboBox component in Java Swing with custom GUI renderer, rather than its default look and feel. Sometimes, it would be desirable to have a dropdown list like the following pictures:
or:
Looks very nice, right? Let’s see how we can build such components in Java Swing. Assuming we want to create a dropdown list that allows users to select a country, as shown in the first screenshot.
The renderer class must implement javax.swing.ListCellRenderer interface. It is used to render component’s GUI in normal state. For example, the following class, MyComboBoxRenderer – implements a simple renderer which is a JLabel:
As we can see, the renderer class has to override the method getListCellRendererComponent() which is defined by the interface ListCellRenderer. The method must return a subclass of Component class which is rendered as list item in the combo box. In the example above, it returns an instance of JLabel class, and results in a combo box looks like following:
1. How to create custom GUI for JCombobox
Generally, it is possible to provide a custom GUI implementation for Swing-based components by providing renderers and editors. For example:
1
2
3
| JComboBox comboBox = new JComboBox(); comboBox.setRenderer( new MyComboBoxRenderer()); comboBox.setEditor( new MyComboBoxEditor()); |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| package com.sjavaspot.swing.combobox import java.awt.Color; import java.awt.Component; import java.awt.Font; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; public class MyComboBoxRenderer extends JLabel implements ListCellRenderer { public MyComboBoxRenderer() { setOpaque( true ); setFont( new Font( "Arial" , Font.BOLD | Font.ITALIC, 14 )); setBackground(Color.BLUE); setForeground(Color.YELLOW); } @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { setText(value.toString()); return this ; } } |
On the other hand, the editor class must implement ComboBoxEditor interface or extends one of ComboBoxEditor’s implementing classes, such as BasicComboBoxEditor. It is used to render component’s GUI in edit state. For example, the following class, MyComboBoxEditor – implements a simple editor which is a JPanel containing a JLabel:
This editor class extends the BasicComboBoxEditor class and overrides the following three methods:
So far we understand the nuts and bolts of the renderer and editor for a JComboBox. Let’s see how the following nice-looking country combo box is implemented in the next sections:
NOTE: the combo box must be editable in order to use custom renderer and editor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| package com.sjavaspot.swing.combobox import java.awt.Color; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Font; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.plaf.basic.BasicComboBoxEditor; public class MyComboBoxEditor extends BasicComboBoxEditor { private JLabel label = new JLabel(); private JPanel panel = new JPanel(); private Object selectedItem; public MyComboBoxEditor() { label.setOpaque( false ); label.setFont( new Font( "Arial" , Font.BOLD, 14 )); label.setForeground(Color.BLACK); panel.setLayout( new FlowLayout(FlowLayout.LEFT, 5 , 2 )); panel.add(label); panel.setBackground(Color.GREEN); } public Component getEditorComponent() { return this .panel; } public Object getItem() { return "[" + this .selectedItem.toString() + "]" ; } public void setItem(Object item) { this .selectedItem = item; label.setText(item.toString()); } } |
- Component getEditorComponent(): returns a subclass object of Component class which is used to render the component in edit state. In the example above, the editor is a JPanel.
- setItem(Object): this method is called whenever an item is selected in the dropdown list. It is for the editor has to render the component based on the item passed. In the example above, it shows a label with green background and bold font.
- Object getItem(): returns the selected item in the dropdown list. This method is called by the JComboBox’s getSelectedItem() method.
1
| comboBox.setEditable( true ); |
2. Code renderer class for JComboBox
Code of the renderer class is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| package com.sjavaspot.swing.combobox import java.awt.Color; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; /** * Customer renderer for JComboBox * @author www.sjavaspot.com * */ public class CountryItemRenderer extends JPanel implements ListCellRenderer { private JLabel labelItem = new JLabel(); public CountryItemRenderer() { setLayout( new GridBagLayout()); GridBagConstraints constraints = new GridBagConstraints(); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.weightx = 1.0 ; constraints.insets = new Insets( 2 , 2 , 2 , 2 ); labelItem.setOpaque( true ); labelItem.setHorizontalAlignment(JLabel.LEFT); add(labelItem, constraints); setBackground(Color.LIGHT_GRAY); } @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { String[] countryItem = (String[]) value; // set country name labelItem.setText(countryItem[ 0 ]); // set country flag labelItem.setIcon( new ImageIcon(countryItem[ 1 ])); if (isSelected) { labelItem.setBackground(Color.BLUE); labelItem.setForeground(Color.YELLOW); } else { labelItem.setForeground(Color.BLACK); labelItem.setBackground(Color.LIGHT_GRAY); } return this ; } } |
3. Code editor class for JComboBox
The editor class is implemented as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| package com.sjavaspot.swing.combobox import java.awt.Color; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.plaf.basic.BasicComboBoxEditor; /** * Editor for JComboBox * @author wwww.sjavaspot.com * */ public class CountryItemEditor extends BasicComboBoxEditor { private JPanel panel = new JPanel(); private JLabel labelItem = new JLabel(); private String selectedValue; public CountryItemEditor() { panel.setLayout( new GridBagLayout()); GridBagConstraints constraints = new GridBagConstraints(); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.weightx = 1.0 ; constraints.insets = new Insets( 2 , 5 , 2 , 2 ); labelItem.setOpaque( false ); labelItem.setHorizontalAlignment(JLabel.LEFT); labelItem.setForeground(Color.WHITE); panel.add(labelItem, constraints); panel.setBackground(Color.BLUE); } public Component getEditorComponent() { return this .panel; } public Object getItem() { return this .selectedValue; } public void setItem(Object item) { if (item == null ) { return ; } String[] countryItem = (String[]) item; selectedValue = countryItem[ 0 ]; labelItem.setText(selectedValue); labelItem.setIcon( new ImageIcon(countryItem[ 1 ])); } } |
4. Code custom combo box class
We implement a custom class that extends from JComboBox as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| package com.sjavaspot.swing.combobox ;import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; /** * A custom combo box with its own renderer and editor. * @author wwww.sjavaspot.com * */ public class CountryComboBox extends JComboBox { private DefaultComboBoxModel model; public CountryComboBox() { model = new DefaultComboBoxModel(); setModel(model); setRenderer( new CountryItemRenderer()); setEditor( new CountryItemEditor()); } /** * Add an array items to this combo box. * Each item is an array of two String elements: * - first element is country name. * - second element is path of an image file for country flag. * @param items */ public void addItems(String[][] items) { for (String[] anItem : items) { model.addElement(anItem); } } } |
This combo box uses the renderer class and editor class shown above. In addition, it uses a DefaultComboBoxModel to hold items. The addItems(String[][]) method is for adding an array of items to the drop down list. Each item is also an array in which the first item is country name and the second is path of an image file represents country flag. You can get the complete code here
No comments:
Post a Comment