GUI COMPONENTS

Posted By on November 7, 2014


Download PDF
Frame Layout Managers
Swing Class

A user can click a button (or a menu item) to trigger a specific action. Swing supports mouse-less operations, where user could use a keyboard short-cut (called mnemonic) to activate the action.

Buttons and menu-items are inherited from AbstractButton, as shown in the class diagram.

You could place a text string (called button’s label) as well as an icon on the button. You could use different icons for different button states: defaultIcon, disabledIcon, pressedIcon, selectedIcon, rolloverIcon, disabledSelectedIcon, rolloverSelectedIcon. The defaultIcon can be set via the constructor or setIcon() method. The other icons can be set via setXxxIcon() methods. You can set the alignment of text and button via setHorizontalAlignment() and setVerticalAlignment() methods. You can set the position of the text relative to the icon via setHorizontalTextPosition() and setVerticalTextPosition().

Swing supports many type of buttons.

Command Buttons: JButton

Click to fires an ActionEvent to all its registered ActionListeners.

Toggle Buttons: JRadioButton, JCheckBox, JToggleButton

Toggle buttons are two-state buttons: SELECTED or DESELECTED.

For radio button, you can choose none or one among the group. JRadioButtons are typically added into a ButtonGroup to ensure exclusive selection. JRadioButton fires ItemEvent to its ItemListeners. It also fires ActionEvent to its ActionListeners. Both ItemEvent and ActionEvent can be used.

For checkboxes, you can choose none or more among the group. JCheckBoxes fire ItemEvent as well as ActionEvent. We typically use ItemEvent as we may need to distinguish between item-states of SELECTED and DESELECTED.

The ItemListner (of ItemEvent) declares one abstract method itemStateChanged(ItemEvent e).

JComboBox

JComboBox can be used to provide a drop-down menu. It supports single-selection and multiple-selection. JComboBox receives a Object array (typically a String array), which provides the items in the drop-down list. JComboBox fires ItemEvent. We could use JComboBox‘s getSelectedIndex() to get the index of the selected item; or getSelectedItem() to get the selected Object. JComboBox also fires ActionEvent.

Example on JButton, JRadioButton and JComboBox

Swing_CounterRadioCombo.png

In this example, we shall modify our counter application to include two radio buttons for specifying counting up/down, and a combo-box to select the count-step size.

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/** Counter with JRadioButton and JComboBox */
@SuppressWarnings("serial")
public class SwingCounterRadioCombo extends JFrame {
   private JTextField tfCount;
   private int count = 0;  // counter's value
   private boolean countingUp = true; // counting up or down
   private int step = 1;   // increment step size

   /** Constructor to setup the UI */
   public SwingCounterRadioCombo () {
      Container cp = getContentPane();
      cp.setLayout(new FlowLayout());

      // Create JLabel and JTextField
      cp.add(new JLabel("Counter:"));
      tfCount = new JTextField("0", 5);
      tfCount.setEditable(false);
      tfCount.setHorizontalAlignment(JTextField.RIGHT);
      cp.add(tfCount);

      // Create JRadioButton for counting up and down
      JRadioButton rbUp = new JRadioButton("Up", true);
      rbUp.setMnemonic(KeyEvent.VK_U);
      cp.add(rbUp);
      rbUp.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            countingUp = true;
         }
      });
      JRadioButton rbDown = new JRadioButton("Down", true);
      rbDown.setMnemonic(KeyEvent.VK_D);
      cp.add(rbDown);
      rbDown.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            countingUp = false;
         }
      });
      // Setup a ButtonGroup to ensure exclusive selection
      ButtonGroup btnGp = new ButtonGroup();
      btnGp.add(rbUp);
      btnGp.add(rbDown);

      // Create JComboBox for setting the count step size
      add(new JLabel("Step:"));
      final Integer[] steps = {1, 2, 3, 4, 5};  // auto-upcast
      final JComboBox<Integer> comboCount = new JComboBox<Integer>(steps);
      comboCount.setPreferredSize(new Dimension(60, 20));
      cp.add(comboCount);
      comboCount.addItemListener(new ItemListener() {
         @Override
         public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
               step = (Integer)comboCount.getSelectedItem();
            }
         }
      });

      // Create JButton for "Count"
      JButton btnCount = new JButton("Count");
      btnCount.setMnemonic(KeyEvent.VK_C);
      cp.add(btnCount);
      btnCount.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            if (countingUp) {
               count += step;
            } else {
               count -= step;
            }
            tfCount.setText(count + "");
         }
      });

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setTitle("Swing Counter with RadioButton & ComboBox");
      setSize(480, 100);
      setVisible(true);
   }

   /** The entry main() method */
   public static void main(String[] args) {
      // Run the GUI codes in the Event-Dispatching thread for thread-safety
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            new SwingCounterRadioCombo(); // Let the constructor do the job
         }
      });
   }
}
Example on JRadioButton, JCheckBox and JComboBox

Swing_ButtonComboBoxDemo.png

In this example, we have two groups of radio buttons: one group to set the horizontal alignment of the JLabel, and processed via ItemEvent; another group sets the vertical alignment and processed via ActionEvent.

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.swing.*;

/** Test JRadioButton, JCheckBox and JComboBox */
@SuppressWarnings("serial")
public class ButtonComboBoxDemo extends JFrame {
   // private variables of GUI components
   private JLabel lblForTest;
   private String imgCrossFilename = "images/cross.gif";
   private String lblText = "Cross";
   private Icon iconCross;

   private JRadioButton rbLeft, rbCenter, rbRight, rbTop, rbMiddle, rbBottom;
   private JCheckBox cbText, cbIcon;
   private JComboBox<String> comboColor;

   /** Constructor to setup the UI components */
   public ButtonComboBoxDemo() {
      // Create a JLabel with text and icon for manipulation
      URL imgURL = getClass().getClassLoader().getResource(imgCrossFilename);
      if (imgURL != null) {
         iconCross = new ImageIcon(imgURL);
      } else {
         System.err.println("Couldn't find file: " + imgCrossFilename);
      }
      lblForTest = new JLabel(lblText, iconCross, SwingConstants.CENTER);
      lblForTest.setOpaque(true);
      lblForTest.setBackground(new Color(204, 238, 241));
      lblForTest.setForeground(Color.RED);
      lblForTest.setFont(new Font(Font.SANS_SERIF, Font.ITALIC, 18));

      // Create radio buttons for setting horizontal alignment of the JLabel
      rbLeft = new JRadioButton("Left");
      rbLeft.setMnemonic(KeyEvent.VK_L);
      rbCenter = new JRadioButton("Center", true);  // selected
      rbCenter.setMnemonic(KeyEvent.VK_C);
      rbRight = new JRadioButton("Right");
      rbRight.setMnemonic(KeyEvent.VK_R);
      // Put the radio buttons into a ButtonGroup to ensure exclusive selection
      ButtonGroup btnGroupH = new ButtonGroup();
      btnGroupH.add(rbLeft);
      btnGroupH.add(rbRight);
      btnGroupH.add(rbCenter);
      // Set up a JPanel to hold all radio buttons
      JPanel pnlRbtnH = new JPanel(new GridLayout(1, 0)); // single row
      pnlRbtnH.add(rbLeft);
      pnlRbtnH.add(rbCenter);
      pnlRbtnH.add(rbRight);
      pnlRbtnH.setBorder(BorderFactory.createTitledBorder("Horizontal Alignment"));

      // A ItemListener for all Radio buttons
      ItemListener listener = new ItemListener() {
         @Override
         public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
               if (e.getSource() == rbLeft) {
                  lblForTest.setHorizontalAlignment(SwingConstants.LEFT);
               } else if (e.getSource() == rbCenter) {
                  lblForTest.setHorizontalAlignment(SwingConstants.CENTER);
               } else if (e.getSource() == rbRight) {
                  lblForTest.setHorizontalAlignment(SwingConstants.RIGHT);
               }
            }
         }
      };
      rbLeft.addItemListener(listener);
      rbCenter.addItemListener(listener);
      rbRight.addItemListener(listener);

      // Create radio buttons for setting vertical alignment of the JLabel
      rbTop = new JRadioButton("Top");
      rbTop.setMnemonic(KeyEvent.VK_T);
      rbMiddle = new JRadioButton("Middle", true);  // selected
      rbMiddle.setMnemonic(KeyEvent.VK_M);
      rbBottom = new JRadioButton("Bottom");
      rbBottom.setMnemonic(KeyEvent.VK_B);
      // Put the radio buttons into a ButtonGroup to ensure exclusive selection
      ButtonGroup btnGroupV = new ButtonGroup();
      btnGroupV.add(rbTop);
      btnGroupV.add(rbMiddle);
      btnGroupV.add(rbBottom);
      // Set up a JPanel to hold all radio buttons
      JPanel pnlRbtnV = new JPanel(new GridLayout(1, 0)); // single row
      pnlRbtnV.add(rbTop);
      pnlRbtnV.add(rbMiddle);
      pnlRbtnV.add(rbBottom);
      pnlRbtnV.setBorder(BorderFactory.createTitledBorder("Vertical Alignment"));

      // Radio buttons also fire ActionEvent
      rbTop.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            lblForTest.setVerticalAlignment(SwingConstants.TOP);
         }
      });
      rbMiddle.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            lblForTest.setVerticalAlignment(SwingConstants.CENTER);
         }
      });
      rbBottom.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            lblForTest.setVerticalAlignment(SwingConstants.BOTTOM);
         }
      });

      // Create checkboxes for selecting text, icon, or both, or none
      cbText = new JCheckBox("Text", true);  // selected
      cbText.setMnemonic(KeyEvent.VK_T);
      cbIcon = new JCheckBox("Icon", true);  // selected
      cbIcon.setMnemonic(KeyEvent.VK_I);
      cbIcon.setSelected(true);
      // Set up a JPanel to hold all checkboxes
      JPanel pnlCbox = new JPanel(new GridLayout(0, 1)); // single column
      pnlCbox.add(cbText);
      pnlCbox.add(cbIcon);
      // Checkboxes fire ItemEvent. Use an anonymous inner class as ItemListener
      cbText.addItemListener(new ItemListener() {
         @Override
         public void itemStateChanged(ItemEvent e) {
            // Need to handle both SELECTED and DESELECTED
            if (e.getStateChange() == ItemEvent.SELECTED) {
               lblForTest.setText(lblText);
            } else {
               lblForTest.setText("");
            }
         }
      });
      cbIcon.addItemListener(new ItemListener() {
         @Override
         public void itemStateChanged(ItemEvent e) {
            // Need to handle both SELECTED and DESELECTED
            if (e.getStateChange() == ItemEvent.SELECTED) {
               lblForTest.setIcon(iconCross);
            } else {
               lblForTest.setIcon(null);
            }
         }
      });

      // Create combobox (drop-down menu) for the foreground color of the JLabel
      String[] strColors = {"Red", "Blue", "Green",
                            "Cyan", "Magenta", "Yellow", "Black"};
      final Color[] colors = {Color.RED, Color.BLUE, Color.GREEN,
                        Color.CYAN, Color.MAGENTA, Color.YELLOW, Color.BLACK};
      comboColor = new JComboBox<String>(strColors);
      comboColor.addItemListener(new ItemListener() {
         @Override
         public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
               lblForTest.setForeground(colors[comboColor.getSelectedIndex()]);
            }
         }
      });
      // Set up a JPanel for the combobox
      JPanel pnlCombo = new JPanel(new FlowLayout());
      pnlCombo.add(comboColor);

      // Set up the content-pane with BorderLayout and adds the panels
      Container cp = this.getContentPane();
      cp.setLayout(new BorderLayout());
      cp.add(lblForTest, BorderLayout.CENTER);
      cp.add(pnlRbtnH, BorderLayout.NORTH);
      cp.add(pnlRbtnV, BorderLayout.SOUTH);
      cp.add(pnlCbox, BorderLayout.WEST);
      cp.add(pnlCombo, BorderLayout.EAST);

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setTitle("Button and ComboBox Demo");
      setSize(400, 300);  // or pack() the components
      setLocationRelativeTo(null);
      setVisible(true);
   }

   /** The entry main() method */
   public static void main(String[] args) {
      // Run GUI codes in the Event-Dispatching thread for thread safety
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            new ButtonComboBoxDemo();  // Let the constructor do the job
         }
      });
   }
}

1.7  Menu-Bar: JMenuBar, JMenu, JMenuItem

Swing_JMenuBarClassDiagram.png

The menu-bar is at the same level as the content-pane (of the top-level container JFrame). It is set via the JFrame‘s setJMenuBar() method (similar to setContentPane()).

To create a menu-bar, construct a JMenuBar. A menu-bar (JMenuBar) contains menu (JMenu). A menu contains menu-item (JMenuItem). JMenuItem is a subclass of AbstractButton, similar to JButton. JMenuItem fires ActionEvent upon activation to all its registered ActionListener.

Example

Swing_TestJMenuBar.png

This menu-bar contains 2 menus (Menu-A and Menu-B). Menu-A contains 2 menu-items (Up and Down). Menu-B has 1 menu-item (Reset).

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/** Testing menu-bar of JFrame */
public class TestJMenuBar extends JFrame {

   JTextField display;
   int count = 0;

   /** Constructor to setup the GUI */
   public TestJMenuBar() {
      // A menu-bar contains menus. A menu contains menu-items (or sub-Menu)
      JMenuBar menuBar;   // the menu-bar
      JMenu menu;         // each menu in the menu-bar
      JMenuItem menuItem; // an item in a menu

      menuBar = new JMenuBar();

      // First Menu
      menu = new JMenu("Menu-A");
      menu.setMnemonic(KeyEvent.VK_A);  // alt short-cut key
      menuBar.add(menu);  // the menu-bar adds this menu

      menuItem = new JMenuItem("Up", KeyEvent.VK_U);
      menu.add(menuItem); // the menu adds this item
      menuItem.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            ++count;
            display.setText(count + "");
         }
      });

      menuItem = new JMenuItem("Down", KeyEvent.VK_D);
      menu.add(menuItem); // the menu adds this item
      menuItem.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            --count;
            display.setText(count + "");
         }
      });

      // Second Menu
      menu = new JMenu("Menu-B");
      menu.setMnemonic(KeyEvent.VK_B);  // short-cut key
      menuBar.add(menu);  // the menu bar adds this menu

      menuItem = new JMenuItem("Reset", KeyEvent.VK_R);
      menu.add(menuItem); // the menu adds this item
      menuItem.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            count = 0;
            display.setText(count + "");
         }
      });

      setJMenuBar(menuBar);  // "this" JFrame sets its menu-bar

      Container cp = getContentPane();
      cp.setLayout(new FlowLayout());
      display = new JTextField("0", 10);
      cp.add(display);

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setTitle("Test MenuBar");
      setSize(300, 100);
      setVisible(true);
   }

   /** The entry main() method */
   public static void main(String[] args) {
      // Run the GUI codes on the event-dispatching thread for thread safety
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            new TestJMenuBar(); // Let the constructor do the job
         }
      });
   }
}

1.8  JOptionPane: Interacting with the User

The javax.swing.JOptionPane provides standard pre-built diglog boxes to interact with user for both input and output. To create a dialog box, use one of the static methods JOptionPane.showXxxDialog().

// Prompt for user input
public static String showInputDialog(Object message, [Object initialSelectionValue])
public static Object showInputDialog(Component parentComponent, Object message,
      [String title], [int messageType], [Icon icon], [Object[] options], [Object initialValue])

// Asks a confirming question (yes/no/cancel)
public static int showConfirmDialog(Component parentComponent, Object message,
      [String title], [int optionType], [int messageType], [Icon icon])

// Display a message
public static void showMessageDialog(Component parentComponent, Object message,
      [String title], [int messageType], [Icon icon])

// Support all features of the above three methods
public static int showOptionDialog(Component parentComponent, Object message,
      String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue)

// Component parentComponent: parent of this dialog box, for poisitioning.
//    If null, centered on the screen.
// Object message: the message, typically a String.
// String title: the title for the dialog box
// int messageType: the style of the message,
//    JOptionPane.ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE.
// int optionType: the set of option buttons,
//    JOptionPane.DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION
// Icon icon: a decorative icon, default depends on the messageType
// Object[] options, Object initialValue:

All these methods block the caller until the user’s interaction is complete. Each of these methods also comes has a showInternalXxxDialog() version, which uses an internal frame to hold the dialog box.

Example: Input, Confirm and Message Dialogs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import javax.swing.*;
public class JOptionPaneTest {
   public static void main(String[] args) {
      // JOptionPane does not have to run under a Swing Application (extends JFrame).
      // It can run directly under main().
      String inStr = JOptionPane.showInputDialog(null, "Ask for user input (returns a String)",
            "Input Dialog", JOptionPane.PLAIN_MESSAGE);
      System.out.println("You have entered " + inStr);
      JOptionPane.showMessageDialog(null, "Display a message (returns void)!",
            "Message Dialog", JOptionPane.PLAIN_MESSAGE);
      int answer = JOptionPane.showConfirmDialog(null, "Ask for confirmation (returns an int)",
            "Confirm Dialog", JOptionPane.YES_NO_CANCEL_OPTION);
      switch (answer) {
         case JOptionPane.YES_OPTION:
            System.out.println("You clicked YES"); break;
         case JOptionPane.NO_OPTION:
            System.out.println("You clicked NO"); break;
         case JOptionPane.CANCEL_OPTION:
            System.out.println("You clicked Cancel"); break;
      }
   }
}

Swing_JOptionPaneInputDialog.png Swing_JOptionPaneConfirmDialog.png Swing_JOptionPaneMessageDialog.png

Take note that input dialog returns the String entered by the user; confirm dialog returns an int (JOptionPane.YES_OPTION, NO_OPTION, CANCEL_OPTION); message dialog returns void. Furthermore, you can use JOptionPane directly under main() to prompt user for input, similar to text-based input via Scanner.

Example: Prompting User for Input with Validation

Swing_TestInputDialog.png

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
55
56
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class InputDialogWithValidation extends JFrame {
   JTextField tfDisplay;  // to display the number entered

   /** Constructor to setup the GUI components */
   public InputDialogWithValidation() {
      Container cp = getContentPane();
      cp.setLayout(new FlowLayout());

      tfDisplay = new JTextField(10);
      tfDisplay.setEditable(false);
      cp.add(tfDisplay);

      JButton btn = new JButton("Input");
      cp.add(btn);
      btn.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            boolean validInput = false;  // for input validation
            int numberIn;
            String inputStr = JOptionPane.showInputDialog("Enter a number [1-9]: ");
            do {
               try {
                  numberIn = Integer.parseInt(inputStr);
               } catch (NumberFormatException ex) {
                  numberIn = -1;  // input triggered NumberFormatException, set to invalid
               }
               if (numberIn < 1 || numberIn > 9) {
                  inputStr = JOptionPane.showInputDialog("Invalid numner! Enter a number [1-9]: ");
               } else {
                  JOptionPane.showMessageDialog(null, "You have entered " + numberIn);
                  validInput = true;
               }
            } while (!validInput); // repeat if input is not valid
            tfDisplay.setText(numberIn + "");
         }
      });
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setSize(300, 100);
      setTitle("Test Input Dialog");
      setVisible(true);
   }

   /** The "main" entry method */
   public static void main(String[] args) {
      // Run the GUI code on the Event-Dispatching Thread for thread safety
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            new InputDialogWithValidation(); // Let the constructor do the job
         }
      });
   }
}

Frame Layout Managers
Swing Class

Download PDF

Posted by Akash Kurup

Founder and C.E.O, World4Engineers Educationist and Entrepreneur by passion. Orator and blogger by hobby

Website: http://world4engineers.com