メニューバーの作成(JMenuBar, JMenu, JMenuItem)

2025-08-06

Swingアプリケーションにメニューバーを追加することで、ユーザーが利用可能な機能を整理して表示できます。メニューシステムはJMenuBarJMenuJMenuItemの3つの主要コンポーネントで構成されます。

メニューコンポーネントの階層構造

menu-components

基本的なメニューバーの作成

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

public class BasicMenuExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("基本的なメニュー");
            frame.setSize(500, 400);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            // 1. メニューバーの作成
            JMenuBar menuBar = new JMenuBar();

            // 2. 「ファイル」メニューの作成
            JMenu fileMenu = new JMenu("ファイル");

            // 3. メニュー項目の作成
            JMenuItem newItem = new JMenuItem("新規作成");
            JMenuItem openItem = new JMenuItem("開く...");
            JMenuItem saveItem = new JMenuItem("保存");
            JMenuItem exitItem = new JMenuItem("終了");

            // アクションリスナーの追加
            exitItem.addActionListener(e -> System.exit(0));

            // メニューに項目を追加
            fileMenu.add(newItem);
            fileMenu.add(openItem);
            fileMenu.add(saveItem);
            fileMenu.addSeparator(); // セパレーターの追加
            fileMenu.add(exitItem);

            // 「編集」メニューの作成
            JMenu editMenu = new JMenu("編集");
            editMenu.add(new JMenuItem("元に戻す"));
            editMenu.add(new JMenuItem("やり直し"));
            editMenu.addSeparator();
            editMenu.add(new JMenuItem("コピー"));
            editMenu.add(new JMenuItem("貼り付け"));

            // メニューバーにメニューを追加
            menuBar.add(fileMenu);
            menuBar.add(editMenu);

            // フレームにメニューバーを設定
            frame.setJMenuBar(menuBar);

            frame.setVisible(true);
        });
    }
}

サブメニューの作成

import javax.swing.*;

public class SubMenuExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("サブメニュー例");
            frame.setSize(500, 400);

            JMenuBar menuBar = new JMenuBar();

            JMenu fileMenu = new JMenu("ファイル");

            // 新規作成サブメニュー
            JMenu newMenu = new JMenu("新規作成");
            newMenu.add(new JMenuItem("ドキュメント"));
            newMenu.add(new JMenuItem("スプレッドシート"));
            newMenu.add(new JMenuItem("プレゼンテーション"));

            fileMenu.add(newMenu);
            fileMenu.addSeparator();
            fileMenu.add(new JMenuItem("終了")).addActionListener(e -> System.exit(0));

            // 表示メニューにサブメニュー
            JMenu viewMenu = new JMenu("表示");

            JMenu zoomMenu = new JMenu("ズーム");
            zoomMenu.add(new JMenuItem("拡大"));
            zoomMenu.add(new JMenuItem("縮小"));
            zoomMenu.add(new JMenuItem("実際のサイズ"));

            viewMenu.add(zoomMenu);
            viewMenu.addSeparator();

            JMenu themeMenu = new JMenu("テーマ");
            JRadioButtonMenuItem lightItem = new JRadioButtonMenuItem("ライト");
            JRadioButtonMenuItem darkItem = new JRadioButtonMenuItem("ダーク");
            ButtonGroup themeGroup = new ButtonGroup();
            themeGroup.add(lightItem);
            themeGroup.add(darkItem);
            themeMenu.add(lightItem);
            themeMenu.add(darkItem);

            viewMenu.add(themeMenu);

            menuBar.add(fileMenu);
            menuBar.add(viewMenu);

            frame.setJMenuBar(menuBar);
            frame.setVisible(true);
        });
    }
}

アイコン付きメニュー項目

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

public class IconMenuExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("アイコン付きメニュー");
            frame.setSize(500, 400);

            JMenuBar menuBar = new JMenuBar();

            JMenu fileMenu = new JMenu("ファイル");

            // アイコン付きメニュー項目
            JMenuItem newItem = new JMenuItem("新規作成", 
                new ImageIcon("new_icon.png")); // 実際には適切なパスを指定
            JMenuItem openItem = new JMenuItem("開く", 
                new ImageIcon("open_icon.png"));

            // アクションを使用したメニュー項目
            Action saveAction = new AbstractAction("保存", 
                new ImageIcon("save_icon.png")) {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(frame, "保存しました");
                }
            };
            saveAction.putValue(Action.SHORT_DESCRIPTION, "ドキュメントを保存");

            fileMenu.add(newItem);
            fileMenu.add(openItem);
            fileMenu.add(new JMenuItem(saveAction));

            menuBar.add(fileMenu);
            frame.setJMenuBar(menuBar);
            frame.setVisible(true);
        });
    }
}

チェックボックスメニュー項目とラジオボタンメニュー項目

import javax.swing.*;

public class SpecialMenuItemsExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("特殊メニュー項目");
            frame.setSize(500, 400);

            JMenuBar menuBar = new JMenuBar();

            JMenu viewMenu = new JMenu("表示");

            // チェックボックスメニュー項目
            JCheckBoxMenuItem statusBarItem = new JCheckBoxMenuItem("ステータスバー");
            statusBarItem.setSelected(true);
            statusBarItem.addActionListener(e -> {
                System.out.println("ステータスバー: " + statusBarItem.isSelected());
            });

            viewMenu.add(statusBarItem);
            viewMenu.addSeparator();

            // ラジオボタンメニュー項目
            JMenu themeMenu = new JMenu("テーマ");

            JRadioButtonMenuItem lightTheme = new JRadioButtonMenuItem("ライトテーマ");
            JRadioButtonMenuItem darkTheme = new JRadioButtonMenuItem("ダークテーマ");
            JRadioButtonMenuItem systemTheme = new JRadioButtonMenuItem("システム設定に従う");

            ButtonGroup themeGroup = new ButtonGroup();
            themeGroup.add(lightTheme);
            themeGroup.add(darkTheme);
            themeGroup.add(systemTheme);

            systemTheme.setSelected(true);

            themeMenu.add(lightTheme);
            themeMenu.add(darkTheme);
            themeMenu.add(systemTheme);

            viewMenu.add(themeMenu);

            menuBar.add(viewMenu);
            frame.setJMenuBar(menuBar);
            frame.setVisible(true);
        });
    }
}

キーボードショートカットとアクセラレータ

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

public class ShortcutMenuExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("ショートカット付きメニュー");
            frame.setSize(500, 400);

            JMenuBar menuBar = new JMenuBar();

            JMenu fileMenu = new JMenu("ファイル");
            fileMenu.setMnemonic(KeyEvent.VK_F); // Alt+Fでメニューを開く

            JMenuItem newItem = new JMenuItem("新規作成");
            newItem.setMnemonic(KeyEvent.VK_N); // メニュー表示時のアクセスキー
            newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK));

            JMenuItem openItem = new JMenuItem("開く...");
            openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));

            JMenuItem saveItem = new JMenuItem("保存");
            saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK));

            fileMenu.add(newItem);
            fileMenu.add(openItem);
            fileMenu.add(saveItem);

            menuBar.add(fileMenu);
            frame.setJMenuBar(menuBar);
            frame.setVisible(true);
        });
    }
}

ポップアップメニュー(コンテキストメニュー)の作成

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

public class PopupMenuExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("ポップアップメニュー例");
            frame.setSize(500, 400);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            // ポップアップメニューの作成
            JPopupMenu popupMenu = new JPopupMenu();

            JMenuItem cutItem = new JMenuItem("切り取り");
            JMenuItem copyItem = new JMenuItem("コピー");
            JMenuItem pasteItem = new JMenuItem("貼り付け");

            popupMenu.add(cutItem);
            popupMenu.add(copyItem);
            popupMenu.addSeparator();
            popupMenu.add(pasteItem);

            // フレームにマウスリスナーを追加
            frame.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    maybeShowPopup(e);
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    maybeShowPopup(e);
                }

                private void maybeShowPopup(MouseEvent e) {
                    if (e.isPopupTrigger()) {
                        popupMenu.show(e.getComponent(), e.getX(), e.getY());
                    }
                }
            });

            frame.setVisible(true);
        });
    }
}

実践的なメニューシステムの例

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

public class PracticalMenuExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("実践的なメニューシステム");
            frame.setSize(800, 600);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            // メニューバーの作成
            JMenuBar menuBar = new JMenuBar();

            // ファイルメニュー
            JMenu fileMenu = new JMenu("ファイル");
            fileMenu.setMnemonic(KeyEvent.VK_F);

            JMenuItem newItem = new JMenuItem("新規作成", KeyEvent.VK_N);
            newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK));

            JMenuItem openItem = new JMenuItem("開く...", KeyEvent.VK_O);
            openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));

            JMenu recentMenu = new JMenu("最近使ったファイル");
            recentMenu.add(new JMenuItem("document1.txt"));
            recentMenu.add(new JMenuItem("report.docx"));

            JMenuItem exitItem = new JMenuItem("終了", KeyEvent.VK_X);
            exitItem.addActionListener(e -> System.exit(0));

            fileMenu.add(newItem);
            fileMenu.add(openItem);
            fileMenu.add(recentMenu);
            fileMenu.addSeparator();
            fileMenu.add(exitItem);

            // 編集メニュー
            JMenu editMenu = new JMenu("編集");
            editMenu.setMnemonic(KeyEvent.VK_E);

            JMenuItem undoItem = new JMenuItem("元に戻す");
            undoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_DOWN_MASK));

            JMenuItem redoItem = new JMenuItem("やり直し");
            redoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, KeyEvent.CTRL_DOWN_MASK));

            editMenu.add(undoItem);
            editMenu.add(redoItem);
            editMenu.addSeparator();
            editMenu.add(new JMenuItem("コピー"));
            editMenu.add(new JMenuItem("貼り付け"));

            // 表示メニュー
            JMenu viewMenu = new JMenu("表示");

            JCheckBoxMenuItem toolbarItem = new JCheckBoxMenuItem("ツールバー");
            toolbarItem.setSelected(true);

            JCheckBoxMenuItem statusbarItem = new JCheckBoxMenuItem("ステータスバー");
            statusbarItem.setSelected(true);

            viewMenu.add(toolbarItem);
            viewMenu.add(statusbarItem);

            // ヘルプメニュー
            JMenu helpMenu = new JMenu("ヘルプ");
            helpMenu.setMnemonic(KeyEvent.VK_H);

            JMenuItem aboutItem = new JMenuItem("バージョン情報");
            aboutItem.addActionListener(e -> {
                JOptionPane.showMessageDialog(frame, 
                    "Swingアプリケーション v1.0\n© 2023", 
                    "バージョン情報", 
                    JOptionPane.INFORMATION_MESSAGE);
            });

            helpMenu.add(aboutItem);

            // メニューバーに追加
            menuBar.add(fileMenu);
            menuBar.add(editMenu);
            menuBar.add(viewMenu);
            menuBar.add(Box.createHorizontalGlue()); // 右寄せのため
            menuBar.add(helpMenu);

            frame.setJMenuBar(menuBar);

            // メインコンテンツ
            JTextArea textArea = new JTextArea();
            frame.add(new JScrollPane(textArea), BorderLayout.CENTER);

            frame.setVisible(true);
        });
    }
}

メニュー作成のベストプラクティス

  1. 一般的な慣例に従う – ファイルメニューは左端、ヘルプメニューは右端など
  2. キーボードショートカット – 標準的なショートカット(Ctrl+Sで保存など)を使用
  3. アクセシビリティ – アクセスキー(Alt+Fなど)を設定
  4. 論理的なグループ化 – 関連する機能は同じメニューにまとめる
  5. 状態の可視化 – チェックボックスメニューで設定状態を表示
  6. グレーアウト – 利用できない機能はsetEnabled(false)で無効化
  7. 国際化対応 – リソースバンドルを使用してテキストを管理
// 国際化対応の例
ResourceBundle bundle = ResourceBundle.getBundle("MenuResources");
JMenu fileMenu = new JMenu(bundle.getString("menu.file"));
JMenuItem openItem = new JMenuItem(bundle.getString("menu.file.open"));
openItem.setAccelerator(KeyStroke.getKeyStroke(
    bundle.getString("shortcut.open")));

メニューシステムを適切に設計することで、アプリケーションの使い勝手が大幅に向上します。次に学ぶ「ツールバーの作成」では、よく使う機能を素早くアクセスできるようにする方法を解説します。