首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Swing 菜單系統全解析:JMenuBar、快捷鍵、單選/複選項、子菜單

     編輯:Java 程式設計入門

菜單體系架構

Swing 菜單層級結構:

JFrame
 └─ JMenuBar
      ├─ JMenu "菜單 A"
      │   ├─ JMenuItem "純文本" (Alt+1)
      │   ├─ JMenuItem "圖標+文本" (Alt+B)
      │   ├─ JMenuItem "純圖標" (Alt+D)
      │   ├─ JSeparator
      │   ├─ JRadioButtonMenuItem 組 (ButtonGroup)
      │   ├─ JSeparator
      │   ├─ JCheckBoxMenuItem 組
      │   ├─ JSeparator
      │   └─ JMenu "子菜單 S" (Alt+2)
      │       ├─ JMenuItem "子項 1"
      │       └─ JMenuItem "子項 2"
      └─ JMenu "菜單 N"

核心實現:MenuDemo

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

public class MenuDemo implements ActionListener, ItemListener {
    private JTextArea output;
    private final String NL = "\n";

    public JMenuBar createMenuBar() {
        JMenuBar bar = new JMenuBar();

        // --- 菜單 A ---
        JMenu menuA = new JMenu("(A)菜單");
        menuA.setMnemonic(KeyEvent.VK_A);
        bar.add(menuA);

        // 純文本項 + 快捷鍵 Alt+1
        JMenuItem item = new JMenuItem("(O)只有文本的菜單", KeyEvent.VK_O);
        item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
        item.addActionListener(this);
        menuA.add(item);

        // 圖標+文本
        ImageIcon icon = createIcon("images/middle.gif");
        item = new JMenuItem("(B)有圖標和文字的菜單", icon);
        item.setMnemonic(KeyEvent.VK_B);
        item.addActionListener(this);
        menuA.add(item);

        // 純圖標
        item = new JMenuItem(icon);
        item.setMnemonic(KeyEvent.VK_D);
        item.addActionListener(this);
        menuA.add(item);

        menuA.addSeparator();

        // 單選組
        ButtonGroup group = new ButtonGroup();
        JRadioButtonMenuItem rb = new JRadioButtonMenuItem("(R)使用radio的菜單");
        rb.setSelected(true);
        rb.setMnemonic(KeyEvent.VK_R);
        group.add(rb);
        rb.addActionListener(this);
        menuA.add(rb);

        rb = new JRadioButtonMenuItem("(d)另外一個radio菜單");
        rb.setMnemonic(KeyEvent.VK_D);
        group.add(rb);
        rb.addActionListener(this);
        menuA.add(rb);

        menuA.addSeparator();

        // 複選組
        JCheckBoxMenuItem cb = new JCheckBoxMenuItem("(C)使用檢查盒的菜單");
        cb.setMnemonic(KeyEvent.VK_C);
        cb.addItemListener(this);
        menuA.add(cb);

        cb = new JCheckBoxMenuItem("(H)另外一個檢查盒");
        cb.setMnemonic(KeyEvent.VK_H);
        cb.addItemListener(this);
        menuA.add(cb);

        menuA.addSeparator();

        // 子菜單
        JMenu sub = new JMenu("(S)帶有子菜單");
        sub.setMnemonic(KeyEvent.VK_S);
        item = new JMenuItem("這是子菜單");
        item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
        item.addActionListener(this);
        sub.add(item);
        sub.add(new JMenuItem("子菜單項")).addActionListener(this);
        menuA.add(sub);

        // --- 菜單 N ---
        JMenu menuN = new JMenu("(N)第二個菜單");
        menuN.setMnemonic(KeyEvent.VK_N);
        bar.add(menuN);

        return bar;
    }

    // --- 事件處理 ---
    @Override
    public void actionPerformed(ActionEvent e) {
        output.append("動作: " + e.getActionCommand() + NL);
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        JCheckBoxMenuItem src = (JCheckBoxMenuItem) e.getSource();
        output.append("複選: " + src.getText() + " -> " +
            (e.getStateChange() == ItemEvent.SELECTED ? "選中" : "取消") + NL);
    }

    protected static ImageIcon createIcon(String path) {
        java.net.URL url = MenuDemo.class.getResource(path);
        return (url != null) ? new ImageIcon(url) : null;
    }

    // --- 主程序啟動 ---
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame("MenuDemo");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            MenuDemo demo = new MenuDemo();
            demo.output = new JTextArea(10, 40);
            demo.output.setEditable(false);
            f.setJMenuBar(demo.createMenuBar());
            f.add(new JScrollPane(demo.output));
            f.pack();
            f.setVisible(true);
        });
    }
}

關鍵 API 對照表

組件用途關鍵方法
JMenuBar頂級菜單容器add(JMenu)
JMenu一級/子菜單setMnemonic, addSeparator, add(JMenuItem)
JMenuItem普通動作項setAccelerator, addActionListener
JRadioButtonMenuItem互斥單選項需加入 ButtonGroup
JCheckBoxMenuItem獨立開關項addItemListener 監聽狀態變化
KeyStroke鍵盤快捷鍵getKeyStroke(key, modifiers)

最佳實踐

  • 快捷鍵不衝突:菜單助記符(Alt+字母)與加速器(Ctrl/Alt+功能鍵)分離設計
  • 圖標統一規範:16x16 或 24x24,透明背景,放入 classpath /images/
  • 動作解耦:採用 Action 接口(AbstractAction)封裝文本、圖標、快捷鍵、執行邏輯,菜單項與工具欄按鈕共享同一 Action 實例
  • 上下文菜單:JPopupMenu + MouseListener 實現右鍵菜單
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved