ーザには秘密のメニューを作成したい,の巻
2000.11.17 新規
2000.11.24 修正

普通にメニュー・バーを作成できる人であれば、いたって簡単に作れます。 ポイントは

となります。 アクセラレータとは、キーボードから特定の組合せのキーが押されたときに、関連付けられたメニュー等が起動する仕組みです。

下のソースコードは例のごとく単独動作のための無駄な部分が多いですが、重要な部分は setSecretMenu() メソッドの中だけです。 このメソッドの中で、表示名が半角スペースのメニューを作成し、ユーザからの操作を無効に設定しています。 こうすることでユーザには見えず更に操作もできないので、このメニューが保持するメニュー・アイテムも露出されません。

しかし、そのメニュー・アイテムのほうはユーザ操作が有効で、またアクセラレータ設定がされています。 従って、アクセラレータからのメニュー・アイテムの要求により、処理が可能となります。


「SampleMenuPanel.java」のソースコード
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

/**
 * 秘密メニューのサンプル・プログラムです.
 * 
 * @author Musi_chan
 * (Musi_chan@cool.biglobe.ne.jp)
 * @version 2000/11/17 13:12
 */
public class SampleMenuPanel extends JFrame implements ActionListener {
/******************************************************************************
  フィールド
******************************************************************************/
  /**
   * メイン・パネルのインスタンス変数です.
   */
  private JPanel routePanel;
  /**
   * メイン・メニュー・バーのインスタンス変数です.
   */
  private JMenuBar routeMenuBar;

/******************************************************************************
  コンストラクタ
******************************************************************************/
  /**
   * コンストラクタです.
   */
  public SampleMenuPanel() {
    this("");
  }

  /**
   * コンストラクタです.
   * 
   * @param args 起動時の引数(ルック&フィール名)
   */
  public SampleMenuPanel(String args) {
    // ルック&フィール名保持用ローカル変数
    String LAFName;

    // 各種ウィンドウ設定
    setLocation(50,25);
    setSize(360,280);
    setResizable(true);
    setTitle("Secret-menu sample program.");
    getContentPane().setLayout(new BorderLayout());
    //setIconImage(ICON.getImage());
    setBackground(SystemColor.menu);
    setForeground(SystemColor.menuText);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    // ルック&フィール名の判別
    if(args.equals("windows")) {
      LAFName="com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
    } else if(args.equals("motif")) {
      LAFName="com.sun.java.swing.plaf.motif.MotifLookAndFeel";
    } else {
      LAFName="javax.swing.plaf.metal.MetalLookAndFeel";
    }
    // ルック&フィール設定
    try {
      UIManager.setLookAndFeel(LAFName);
    } catch(ClassNotFoundException cnfe) {
    } catch(InstantiationException ie) {
    } catch(IllegalAccessException iae) {
    } catch(UnsupportedLookAndFeelException ulafe) {
    }

    // メニュー・バーの作成と配置
    setMenuBar();
    setJMenuBar(routeMenuBar); // 2000.11.24 修正
//    getContentPane().add(routeMenuBar,BorderLayout.NORTH);
    // メイン・パネルの設定と追加
    setRoutePanel();
    getContentPane().add(routePanel,BorderLayout.CENTER);

    // メイン・ウィンドウの表示
    setVisible(true);
  }

/******************************************************************************
  メソッド
******************************************************************************/

/******************************************************************************
  ビュー
******************************************************************************/
  /**
   * メニュー・バーの設定をするメソッドです.
   */
  private void setMenuBar() {
    // メニュー・バーのインスタンス生成
    routeMenuBar=new JMenuBar();

    // ファイル・メニューをメニュー・バーに追加
    routeMenuBar.add(setFileMenu());
    // ヘルプ・メニューをメニュー・バーに追加
    routeMenuBar.add(setHelpMenu());
    // 秘密メニューをメニュー・バーに追加
    routeMenuBar.add(setSecretMenu());
  }

  /**
   * ファイル・メニューの設定をするメソッドです.
   * 
   * @return 設定済みメニュー
   */
  private JMenu setFileMenu() {
    // ファイル・メニュー保持用ローカル変数
    JMenu fileMenu;
    // 新規メニュー・アイテム保持用ローカル変数
    JMenuItem newMenuItem;
     // 開くメニュー・アイテム保持用ローカル変数
    JMenuItem openMenuItem;
    // 保存メニュー・アイテム保持用ローカル変数
    JMenuItem saveMenuItem;
    // 名前付けメニュー・アイテム保持用ローカル変数
    JMenuItem saveasMenuItem;
    // 終了メニュー・アイテム保持用ローカル変数
    JMenuItem extMenuItem;

    // ファイル・メニューの初期化
    // メニューのインスタンス生成
    fileMenu=new JMenu("File");
    // ニーモニックの設定(Alt+Fでも可にする)
    fileMenu.setMnemonic('F');

    // 新規メニュー・アイテムの初期化
    // メニュー・アイテムのインスタンス生成
    newMenuItem=new JMenuItem("New");
    // ニーモニックの設定
    newMenuItem.setMnemonic('N');
    // アクセラレータの設定(メニューを開かず,Ctrl+Nでも可にする)
    newMenuItem.setAccelerator(
      KeyStroke.getKeyStroke(KeyEvent.VK_N,ActionEvent.CTRL_MASK));
    // アクションコマンドの設定
    newMenuItem.setActionCommand("menu new");
    // アクション用イベントリスナの登録
    newMenuItem.addActionListener(this);
    // メニュー・アイテムをメニューに追加
    fileMenu.add(newMenuItem);

    // 開くメニュー・アイテムの初期化など
    openMenuItem=new JMenuItem("Open");
    openMenuItem.setMnemonic('O');
    openMenuItem.setAccelerator(
      KeyStroke.getKeyStroke(KeyEvent.VK_O,ActionEvent.CTRL_MASK));
    openMenuItem.setActionCommand("menu open");
    openMenuItem.addActionListener(this);
    fileMenu.add(openMenuItem);

    // 保存メニュー・アイテムの初期化など
    saveMenuItem=new JMenuItem("Save");
    saveMenuItem.setMnemonic('S');
    saveMenuItem.setAccelerator(
      KeyStroke.getKeyStroke(KeyEvent.VK_S,ActionEvent.CTRL_MASK));
    saveMenuItem.setActionCommand("menu save");
    saveMenuItem.addActionListener(this);
    fileMenu.add(saveMenuItem);

    // 名前付けて保存メニュー・アイテムの初期化など
    saveasMenuItem=new JMenuItem("saveAs");
    saveasMenuItem.setMnemonic('A');
    saveasMenuItem.setActionCommand("menu saveas");
    saveasMenuItem.addActionListener(this);
    fileMenu.add(saveasMenuItem);

    // メニューの中に棒線を挿入
    fileMenu.addSeparator();

    // 終了メニュー・アイテムの初期化など
    extMenuItem=new JMenuItem("eXit");
    extMenuItem.setMnemonic('X');
    extMenuItem.setActionCommand("window exit");
    extMenuItem.addActionListener(this);
    fileMenu.add(extMenuItem);

    return fileMenu;
  }

  /**
   * ヘルプ・メニューの設定をするメソッドです.
   * 
   * @return 設定済みメニュー
   */
  private JMenu setHelpMenu() {
    // ヘルプ・メニュー保持用ローカル変数
    JMenu helpMenu;
    // ヘルプ・メニュー・アイテム保持用ローカル変数
    JMenuItem helpMenuItem;
     // バージョン・メニュー・アイテム保持用ローカル変数
    JMenuItem verMenuItem;

    // ヘルプ・メニュー
    // メニューのの初期化など
    helpMenu=new JMenu("Help");
    helpMenu.setMnemonic('H');

    // ヘルプ・メニュー・アイテムの初期化など
    helpMenuItem=new JMenuItem("Help");
    helpMenuItem.setMnemonic('H');
    helpMenuItem.setActionCommand("menu help");
    helpMenuItem.addActionListener(this);
    helpMenu.add(helpMenuItem);

    // メニューの中に棒線を挿入
    helpMenu.addSeparator();

    // バージョン・メニュー・アイテムの初期化など
    verMenuItem=new JMenuItem("Version");
    verMenuItem.setMnemonic('V');
    verMenuItem.setActionCommand("menu version");
    verMenuItem.addActionListener(this);
    helpMenu.add(verMenuItem);

    return helpMenu;
  }

  /**
   * 秘密メニューの設定をするメソッドです.
   * 
   * @return 設定済みメニュー
   */
  private JMenu setSecretMenu() {
    // 秘密メニュー保持用ローカル変数
    JMenu secretMenu;
    // 秘密メニュー・アイテム保持用ローカル変数
    JMenuItem secretMenuItem;

    // 秘密メニューの初期化
    // メニューのインスタンス生成
    secretMenu=new JMenu(" ");
    // ユーザからの機能使用不可に設定
    secretMenu.setEnabled(false);

    // 秘密メニュー・アイテムの初期化
    // メニュー・アイテムのインスタンス生成
    secretMenuItem=new JMenuItem("Nameless");
    // アクセラレータの設定
    secretMenuItem.setAccelerator(
      KeyStroke.getKeyStroke(KeyEvent.VK_ENTER
      ,ActionEvent.CTRL_MASK|ActionEvent.SHIFT_MASK|ActionEvent.ALT_MASK));
    // アクションコマンドの設定
    secretMenuItem.setActionCommand("secret");
    // アクション用イベントリスナの登録
    secretMenuItem.addActionListener(this);
    // メニュー・アイテムをメニューに追加
    secretMenu.add(secretMenuItem);

    return secretMenu;
  }

  /**
   * メイン・パネルの設定をするメソッドです.
   */
  private void setRoutePanel() {
    // ルートパネルのインスタンス生成
    routePanel=new JPanel();
  }

  /**
   * 情報ダイアログを表示するメソッドです.
   * 
   * @param message メッセージ
   */
  public void showInformationMessageDialog(String message) {
    // 情報ダイアログの表示
    JOptionPane.showMessageDialog(this,new JLabel(message)
      ,"Information...",JOptionPane.INFORMATION_MESSAGE);
    repaint();
  }

  /**
   * 警告ダイアログを表示するメソッドです.
   * 
   * @param message 警告メッセージ
   */
  public void showWarningMessageDialog(String message) {
    // 警告ダイアログの表示
    JOptionPane.showMessageDialog(this,new JLabel(message)
      ,"Warning...",JOptionPane.WARNING_MESSAGE);
    repaint();
  }

/******************************************************************************
  コントローラ
******************************************************************************/
  /**
   * メインメソッドです.起動時に呼び出されます.
   * 
   * @param args コマンドライン引数
   */
  public static void main(String[] args) {
    // 自身のインスタンス生成(=アプリの開始)
    if(args.length==0) {
      new SampleMenuPanel();
    } else {
      new SampleMenuPanel(args[0]);
    }
  }

  /**
   * アクションイベント用メソッドです.
   * メニューが押されたときに呼び出されます.
   * 
   * @param ae アクションイベント
   */
  public void actionPerformed(ActionEvent ae) {
    // トークン保持用ローカル変数
    String token;
    // トークン分解用ローカル変数
    StringTokenizer st;

    // イベントに設定されたアクションコマンドをトークン分解
    st=new StringTokenizer(ae.getActionCommand()," ");
    token=st.nextToken();
    // 第1トークンの判定
    if(token.equalsIgnoreCase("window")) {
      // ウィンドウ関係の処理
      System.exit(0);
    } else if(token.equalsIgnoreCase("menu")) {
      // メニュー関係の処理
      showInformationMessageDialog(st.nextToken());
    } else if(token.equalsIgnoreCase("secret")) {
      // 秘密の処理
      showWarningMessageDialog(
        "The operation of the closed-door was demanded.");
    }
  }
}

戻る