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

Java JMenuBar 與 JPopupMenu 選單系統完整實作:主選單、單選/核取方塊項目、子選單、快捷鍵與右鍵彈出選單

     編輯:Java 相關知識

構建一個功能完整的 Swing 選單系統:頂層 JMenuBar 包含多層次選單、圖示項目、單選按鈕組、核取方塊項目、子選單與快捷鍵;文字區右鍵彈出 JPopupMenu 提供情境操作。完整展示選單模型構建、事件監聽(ActionListener/ItemListener)、鍵盤助記符與加速鍵、彈出選單觸發機制。

核心類別:MenuDemo


public class MenuDemo implements ActionListener, ItemListener {
    JTextArea output; JScrollPane scrollPane; String newline = "\n";
    // 主選單列構建
    public JMenuBar createMenuBar() {
        JMenuBar menuBar = new JMenuBar();
        // 選單 1
        JMenu menu = new JMenu("(A)選單");
        menu.setMnemonic(KeyEvent.VK_A);
        // 純文字項目 + 快捷鍵 Alt+1
        JMenuItem item = new JMenuItem("(O)純文字項目", KeyEvent.VK_O);
        item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
        item.addActionListener(this); menu.add(item);
        // 圖示+文字項目
        ImageIcon icon = createImageIcon("images/middle.gif");
        item = new JMenuItem("(B)圖示+文字", icon);
        item.setMnemonic(KeyEvent.VK_B); item.addActionListener(this); menu.add(item);
        // 純圖示項目
        item = new JMenuItem(icon); item.setMnemonic(KeyEvent.VK_D); item.addActionListener(this); menu.add(item);
        menu.addSeparator();
        // 單選按鈕組
        ButtonGroup group = new ButtonGroup();
        JRadioButtonMenuItem rb = new JRadioButtonMenuItem("(R)單選項目 1");
        rb.setSelected(true); rb.setMnemonic(KeyEvent.VK_R); group.add(rb); rb.addActionListener(this); menu.add(rb);
        rb = new JRadioButtonMenuItem("(D)單選項目 2");
        rb.setMnemonic(KeyEvent.VK_D); group.add(rb); rb.addActionListener(this); menu.add(rb);
        menu.addSeparator();
        // 核取方塊項目
        JCheckBoxMenuItem cb = new JCheckBoxMenuItem("(C)核取項目 1");
        cb.setMnemonic(KeyEvent.VK_C); cb.addItemListener(this); menu.add(cb);
        cb = new JCheckBoxMenuItem("(H)核取項目 2");
        cb.setMnemonic(KeyEvent.VK_H); cb.addItemListener(this); menu.add(cb);
        menu.addSeparator();
        // 子選單
        JMenu submenu = new JMenu("(S)子選單");
        submenu.setMnemonic(KeyEvent.VK_S);
        item = new JMenuItem("子選單項目 1");
        item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
        item.addActionListener(this); submenu.add(item);
        item = new JMenuItem("子選單項目 2"); item.addActionListener(this); submenu.add(item);
        menu.add(submenu);
        menuBar.add(menu);
        // 選單 2
        menu = new JMenu("(N)第二個選單");
        menu.setMnemonic(KeyEvent.VK_N);
        menuBar.add(menu);
        return menuBar;
    }
    // 內容面板
    public Container createContentPane() {
        JPanel panel = new JPanel(new BorderLayout());
        output = new JTextArea(5, 30); output.setEditable(false);
        scrollPane = new JScrollPane(output);
        panel.add(scrollPane, BorderLayout.CENTER);
        return panel;
    }
    // 彈出選單
    public void createPopupMenu() {
        JPopupMenu popup = new JPopupMenu();
        JMenuItem item = new JMenuItem("開啟檔案", createImageIcon("images/Open16.gif"));
        item.addActionListener(this); popup.add(item);
        item = new JMenuItem("儲存檔案", createImageIcon("images/Save16.gif"));
        item.addActionListener(this); popup.add(item);
        // 滑鼠監聽觸發彈出
        output.addMouseListener(new PopupListener(popup));
    }
    // 事件處理
    public void actionPerformed(ActionEvent e) {
        JMenuItem src = (JMenuItem)e.getSource();
        output.append("動作事件: " + src.getText() + " (" + getClassName(src) + ")" + newline);
    }
    public void itemStateChanged(ItemEvent e) {
        JMenuItem src = (JMenuItem)e.getSource();
        output.append("狀態改變: " + src.getText() + " -> " + 
            (e.getStateChange() == ItemEvent.SELECTED ? "選取" : "取消") + newline);
    }
    protected String getClassName(Object o) {
        String cn = o.getClass().getName(); return cn.substring(cn.lastIndexOf('.')+1);
    }
    protected static ImageIcon createImageIcon(String path) {
        java.net.URL url = MenuDemo.class.getResource(path);
        return url != null ? new ImageIcon(url) : null;
    }
    // 彈出選單滑鼠觸發器
    class PopupListener extends MouseAdapter {
        JPopupMenu popup;
        PopupListener(JPopupMenu p) { popup = p; }
        public void mousePressed(MouseEvent e) { maybeShow(e); }
        public void mouseReleased(MouseEvent e) { maybeShow(e); }
        private void maybeShow(MouseEvent e) {
            if (e.isPopupTrigger()) popup.show(e.getComponent(), e.getX(), e.getY());
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Menu Demo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            MenuDemo demo = new MenuDemo();
            frame.setJMenuBar(demo.createMenuBar());
            frame.setContentPane(demo.createContentPane());
            demo.createPopupMenu();
            frame.setSize(450, 260);
            frame.setVisible(true);
        });
    }
}

選單項目類型完整對照

類別用途事件監聽視覺特徵
JMenuItem一般指令項目ActionListener文字/圖示/文字+圖示
JRadioButtonMenuItem互斥單選組ActionListener圓形單選按鈕,配合 ButtonGroup
JCheckBoxMenuItem獨立開關狀態ItemListener方形核取方塊
JMenu子選單容器—展開顯示子項目
JPopupMenu情境彈出選單ActionListener滑鼠右鍵觸發

鍵盤互動三層次

  1. 助記符:setMnemonic(KeyEvent.VK_X) → Alt+X 聚焦選單/項目(底線標示)。
  2. 加速鍵:setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)) → Ctrl+S 直接觸發動作(無需開啟選單)。
  3. 鍵盤導航:選單展開後,方向鍵移動、Enter 確認、Esc 關閉。

彈出選單觸發最佳實踐

  • 同時監聽 mousePressed 和 mouseReleased,跨平台相容(Windows 釋放觸發,macOS 按下觸發)。
  • 使用 e.isPopupTrigger() 判斷而非檢查按鈕編號。
  • popup.show(component, x, y) 相對元件座標定位。

進階擴展方向

  1. 動態啟用/停用:根據應用狀態 item.setEnabled(false)。
  2. 圖示狀態切換:核取方塊項目切換圖示 item.setIcon(selectedIcon)。
  3. 鍵盤快捷鍵表:Help → Keyboard Shortcuts 動態生成顯示所有加速鍵。
  4. 觸控友善:增加項目高度、間距,支援長按顯示彈出選單。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved