Creating and Managing Swing Menus
Menus provide space-effficient user interfaces for selecting from multiple options. Swing offers several menu components that can appear in menu bars or as popup menus.
Menu Component Structure
Swing menu components follow a hierarchical structure where menu items are essentially specialized buttons. When activated, menus automatically display their items in popup windows.
Building Menu Systems
This example demonstrates creating a complete menu structure with various menu item types:
// Menu component declarations
JMenuBar mainMenuBar;
JMenu primaryMenu, secondaryMenu;
JMenuItem standardItem;
JRadioButtonMenuItem radioItem;
JCheckBoxMenuItem checkItem;
// Initialize menu bar
mainMenuBar = new JMenuBar();
// Create first menu
primaryMenu = new JMenu("Primary Menu");
primaryMenu.setMnemonic(KeyEvent.VK_P);
primaryMenu.getAccessibleContext().setAccessibleDescription(
"Main application menu with various item types");
mainMenuBar.add(primaryMenu);
// Add standard menu items
standardItem = new JMenuItem("Text item", KeyEvent.VK_T);
standardItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_1, ActionEvent.ALT_MASK));
primaryMenu.add(standardItem);
standardItem = new JMenuItem("Text with icon",
new ImageIcon("icons/center.png"));
standardItem.setMnemonic(KeyEvent.VK_I);
primaryMenu.add(standardItem);
// Radio button menu items
primaryMenu.addSeparator();
ButtonGroup radioGroup = new ButtonGroup();
radioItem = new JRadioButtonMenuItem("Radio option 1");
radioItem.setSelected(true);
radioItem.setMnemonic(KeyEvent.VK_R);
radioGroup.add(radioItem);
primaryMenu.add(radioItem);
radioItem = new JRadioButtonMenuItem("Radio option 2");
radioItem.setMnemonic(KeyEvent.VK_O);
radioGroup.add(radioItem);
primaryMenu.add(radioItem);
// Checkbox menu items
primaryMenu.addSeparator();
checkItem = new JCheckBoxMenuItem("Check option 1");
checkItem.setMnemonic(KeyEvent.VK_C);
primaryMenu.add(checkItem);
checkItem = new JCheckBoxMenuItem("Check option 2");
checkItem.setMnemonic(KeyEvent.VK_H);
primaryMenu.add(checkItem);
// Submenu creation
primaryMenu.addSeparator();
secondaryMenu = new JMenu("Submenu");
secondaryMenu.setMnemonic(KeyEvent.VK_S);
standardItem = new JMenuItem("Submenu item 1");
standardItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_2, ActionEvent.ALT_MASK));
secondaryMenu.add(standardItem);
standardItem = new JMenuItem("Submenu item 2");
secondaryMenu.add(standardItem);
primaryMenu.add(secondaryMenu);
// Add menu bar to frame
frame.setJMenuBar(mainMenuBar);
Menu Event Handling
Menu items generate action events when selected. Different menu item types may require different listener approaches:
public class MenuHandler implements ActionListener, ItemListener {
public MenuHandler() {
// Register action listeners for standard items
standardItem.addActionListener(this);
// Register item listeners for checkbox items
checkItem.addItemListener(this);
}
public void actionPerformed(ActionEvent event) {
// Handle standard menu item selections
JMenuItem source = (JMenuItem)event.getSource();
// Process menu item action
}
public void itemStateChanged(ItemEvent event) {
// Handle checkbox menu item state changes
// Process state changes
}
}
Keyboard Navigation
Menus support mnemonics for keyboard navigation and accelerators for direct access:
// Set mnemonic during construction
menuItem = new JMenuItem("Save", KeyEvent.VK_S);
// Set mnemonic after creation
menuItem.setMnemonic(KeyEvent.VK_S);
// Configure accelerator key
menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_S, ActionEvent.CTRL_MASK));
Popup Menu Implementation
Context menus appear on right-click and require mouse listener registration:
JPopupMenu contextMenu = new JPopupMenu();
JMenuItem contextItem = new JMenuItem("Context action");
contextItem.addActionListener(this);
contextMenu.add(contextItem);
// Register mouse listener for popup trigger
component.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
showContextMenu(e);
}
public void mouseReleased(MouseEvent e) {
showContextMenu(e);
}
private void showContextMenu(MouseEvent e) {
if (e.isPopupTrigger()) {
contextMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
Working with JPanel Containers
JPanel provides lightweight containers for organizing components. Panels can be opaque or transparent and support custom painting.
Panel Layout Configuration
Panels use layout managers to organize child components. Common approaches enclude:
// Panel with border layout
JPanel borderPanel = new JPanel(new BorderLayout());
// Panel with box layout
JPanel boxPanel = new JPanel();
boxPanel.setLayout(new BoxLayout(boxPanel, BoxLayout.PAGE_AXIS));
Component Management
Adding components varies by layout manager:
// FlowLayout, BoxLayout, GridLayout
panel.add(component);
// BorderLayout requires position specification
panel.add(component, BorderLayout.CENTER);
Password Field Security
JPasswordField provides secure text input with character masking and character array storage.
JPasswordField passwordField = new JPasswordField(15);
passwordField.setActionCommand("VERIFY");
passwordField.addActionListener(this);
// Password verification
public void actionPerformed(ActionEvent e) {
if ("VERIFY".equals(e.getActionCommand())) {
char[] entered = passwordField.getPassword();
if (validatePassword(entered)) {
// Successful authentication
}
// Clear password for security
Arrays.fill(entered, '\0');
}
}
Progress Monitoring Components
Swing provides progress bars and progress monitors for long-running tasks.
Determinate Progress Bars
JProgressBar progressBar = new JProgressBar(0, taskLength);
progressBar.setValue(0);
progressBar.setStringPainted(true);
Indeterminate Mode
progressBar.setIndeterminate(true);
Progress Monitor
ProgressMonitor monitor = new ProgressMonitor(parent,
"Processing Task", "Initializing...", 0, totalWork);
Root Pane Components
Root panes manage glass panes, layered panes, content panes, and menu bars in top-level containers.
Glass Pane Usage
CustomGlassPane glass = new CustomGlassPane();
frame.setGlassPane(glass);
Scroll Pane Implementation
JScrollPane provides scrollable veiws for large or dynamically sized components.
JTextArea textArea = new JTextArea(20, 50);
JScrollPane scrollPane = new JScrollPane(textArea);
Scroll Bar Policies
scrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
Custom Headers and Corners
scrollPane.setColumnHeaderView(columnHeader);
scrollPane.setRowHeaderView(rowHeader);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, cornerComponent);
Separator Components
JSeparator creates visual dividers between interface elements.
// Horizontal separator
JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL);
// Vertical separator in panel
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(component);
panel.add(Box.createHorizontalStrut(5));
panel.add(new JSeparator(SwingConstants.VERTICAL));
Slider Controls
JSlider enables numerical input within specified ranges.
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 50);
slider.setMajorTickSpacing(25);
slider.setMinorTickSpacing(5);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
Custom Slider Labels
Hashtable<integer jlabel=""> labels = new Hashtable<>();
labels.put(0, new JLabel("Low"));
labels.put(50, new JLabel("Medium"));
labels.put(100, new JLabel("High"));
slider.setLabelTable(labels);</integer>