メニューアイテムのキーボードアクセラレーターの設定

広告

メニューアイテムにキーボードニーモニックを設定して使う場合、まずそのメニューアイテムを表示されている状態にしてから対応するキーを押す必要があります。これに対してキーボードアクセラレーターとはメニューアイテムが表示されていない状態でも特定のキーを押すことでメニューアイテムをクリックしたのと同じ動作をさせることが可能です。(その為、1つのアプリケーションで同じキーボードアクセラレーターは1つのメニューアイテムやその他のコンポーネントにしか設定できません)。

メニューアイテムにキーボードアクセラレーターを設定するにはJMenuItemクラスで定義されているsetAcceleratorメソッドを使います。

public void setAccelerator(KeyStroke keyStroke)

メニュー階層を移動することなくメニュー項目のアクションリスナーを呼び出すキーの組み合わせを
設定します。適切なアクションをインストールするのは UI の役割です。キーボードアクセラレータ
が入力されると、メニューが現在表示されているかどうかを処理します。

パラメータ:
  keyStroke - アクセラレータとして機能する KeyStroke

引数にはメニューアイテムに設定したいキーを表す値をKeyStrokeクラスのオブジェクトで指定します。

javax.swing.KeyStrokeクラスには複数のstaticメソッドが用意されており、メソッドを使ってKeyStrokeクラスのオブジェクトを作成します。ここではその一つであるgetKeyStrokeメソッドを確認してみます。

public static KeyStroke getKeyStroke(int keyCode, int modifiers)

数値キーコードおよび修飾子のセットが指定されると、KeyStroke の共有インスタンスを返します。
返される KeyStroke は、キーを押す動作に対応します。

java.awt.event.KeyEvent で定義される「仮想キー」定数は、キーコードを指定するために使用でき
ます。例を示します。

    * java.awt.event.KeyEvent.VK_ENTER
    * java.awt.event.KeyEvent.VK_TAB
    * java.awt.event.KeyEvent.VK_SPACE 

修飾子は、次の組み合わせで構成されます。

    * java.awt.event.InputEvent.SHIFT_DOWN_MASK
    * java.awt.event.InputEvent.CTRL_DOWN_MASK
    * java.awt.event.InputEvent.META_DOWN_MASK
    * java.awt.event.InputEvent.ALT_DOWN_MASK
    * java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK 

以前使われていた修飾子を次に挙げます。

    * java.awt.event.InputEvent.SHIFT_MASK
    * java.awt.event.InputEvent.CTRL_MASK
    * java.awt.event.InputEvent.META_MASK
    * java.awt.event.InputEvent.ALT_MASK
    * java.awt.event.InputEvent.ALT_GRAPH_MASK 

これらも使用できますが、これらは _DOWN_ 修飾子にマッピングされます。 これらの数字はすべて
異なる 2 の累乗であるため、それらの組み合わせは各ビットが別々の修飾キーを表す整数です。修
飾子を指定しない場合は、0 を使います。 

パラメータ:
  keyCode - キーボードのキーの数値コードを指定する int 値
  modifiers - 修飾子のビット単位の論理和
戻り値:
  そのキーの KeyStroke オブジェクト

2つの引数を指定します。1つ目にはキーを表すint型の値を指定します。指定できる値はキーボードニーモニックの時と同じく指定できる値は java.awt.event.KeyEventクラスで定義されています。

数値:
KeyEvent.VK_0 から KeyEvent.VK_9

アルファベット:
KeyEvent.VK_A から KeyEvent.VK_Z

2つ目には修飾子を指定します。修飾子とは「ALT」や「SHIFT」などキーと一緒に押すキーのことです。指定できる値はjava.awt.event.InputEventクラスで定義されており例えば次のような値です。

InputEvent.SHIFT_DOWN_MASK
InputEvent.CTRL_DOWN_MASK
InputEvent.META_DOWN_MASK
InputEvent.ALT_DOWN_MASK
InputEvent.ALT_GRAPH_DOWN_MASK

※キーボードニーモニックの場合は「ALT」キーとの組み合わせで決まっていましたが、キーボードアクセラレータの場合は修飾子も同時に指定します。

実際の使い方は次のようになります。

JMenu menu = new JMenu("File");

ImageIcon icon = new ImageIcon("./img/sample.png");

JMenuItem menuitem = new JMenuItem("Open", icon);
menuitem.setMnemonic(KeyEvent.VK_O);
menuitem.setAccelerator(KeyStroke.getKeyStroke(
  KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK));

menu.add(menuitem);

上記ではキーボードニーモニックとしてALT+「O」を設定し、さらにキーボードアクセラレーターとしてCTRL+「O」を設定しました。

サンプルプログラム

では実際に試してみます。

SSample17_1.java

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;

class SSample17_1 extends JFrame implements ActionListener{
  JLabel label;

  public static void main(String args[]){
    SSample17_1 frame = new SSample17_1("タイトル");
    frame.setVisible(true);
  }

  SSample17_1(String title){
    setTitle(title);
    setBounds(100, 100, 300, 250);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JMenuBar menubar = new JMenuBar();
    JMenu menu1 = new JMenu("File");
    JMenu menu2 = new JMenu("Edit");
    JMenu menu3 = new JMenu("Tool");
    JMenu menu4 = new JMenu("Help");

    menubar.add(menu1);
    menubar.add(menu2);
    menubar.add(menu3);
    menubar.add(menu4);

    JMenuItem menuitem1_1 = new JMenuItem("New");
    menuitem1_1.setMnemonic(KeyEvent.VK_N);
    menuitem1_1.setAccelerator(
      KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK));
    menuitem1_1.setActionCommand("New");
    menuitem1_1.addActionListener(this);

    JMenuItem menuitem1_2 = new JMenuItem("Open");
    menuitem1_2.setMnemonic(KeyEvent.VK_O);
    menuitem1_2.setAccelerator(
      KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK));
    menuitem1_2.setActionCommand("Open");
    menuitem1_2.addActionListener(this);

    JMenuItem menuitem1_3 = new JMenuItem("Save");
    menuitem1_3.setMnemonic(KeyEvent.VK_S);
    JMenuItem menuitem1_4 = new JMenuItem("Close(X)");
    menuitem1_4.setMnemonic(KeyEvent.VK_X);

    menu1.add(menuitem1_1);
    menu1.add(menuitem1_2);
    menu1.add(menuitem1_3);
    menu1.add(menuitem1_4);

    setJMenuBar(menubar);

    JPanel p = new JPanel();

    label = new JLabel();
    p.add(label);

    Container contentPane = getContentPane();
    contentPane.add(p, BorderLayout.CENTER);
  }

  public void actionPerformed(ActionEvent e){
    label.setText(e.getActionCommand());
  }
}

ではコンパイルを行った上で実行してみます。

メニューアイテムのキーボードアクセラレーターの設定

では「File」メニューをクリックして下さい。

メニューアイテムのキーボードアクセラレーターの設定

1つ目と2つ目のメニューアイテムにキーボードアクセラレーターを設定してあります。キーボードアクセラレーターが設定されているメニューアイテムには、メニューアイテムの右側に設定されているキーが表示されています。

メニューアイテムのキーボードアクセラレーターの設定

ではいったんメニューを閉じます。

メニューアイテムのキーボードアクセラレーターの設定

キーボードアクセラレータが設定されているメニューアイテムは、表示されていなくても対応するキーを押す事でメニューアイテムをクリックしたのと同じ扱いをされます。ではCTRL+「O」を押して下さい。

メニューアイテムのキーボードアクセラレーターの設定

「Open」メニューアイテムに設定されている動作が実行されました。(今回はメニューアイテムがクリックされたら画面上のラベルにメニューアイテムの文字列を表示しています)。今度はCTRL+「N」を押すと次のように「New」メニューアイテムがクリックされたのと同じ動作をします。

メニューアイテムのキーボードアクセラレーターの設定

キーボードアクセラレーターは便利な機能ですが、一般的に使われているコピーを表すCTRL+「C」やCTRL+「V」などを割り当てしまうと利用者が混乱するので注意して下さい。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。