キーボード入力に対するイベント処理


167ページに,キーボード入力に対して,アクションイベントを発生させ,キー 入力に応じた処理を記述する方法を述べた。それには,JComponentクラスの regisiterKeyboardActionメソッドを使う。ところが,現在のAPIを見ると,「こ のメソッドは使われていない」と記述されている。このようにAPIに述べられてい ても,このメソッドは使えるが,regisiterKeyboardActionメソッドを使わず, キーイベントを処理する方法を,補足としてここに紹介する。

キーボード入力時に発生するキーイベント

キーボードフォーカスがあるコンポーネント上でユーザがキーを押す、ある いは離したときにキーイベントが発生する。
キーイベントには,KEY_PRESSED,KEY_RELEASED,KEY_TYPEDの3種のタイプが あり,どのタイプのキーイベントが起るかは,キーにより異なる。
  1. 「a」キーを押して離すと,次の3つのキーイベント(KeyEvent)が発生す る。 キーキャラクター(keyChar)は,KeyEventのgetKeyCharメソッドを使って 知ることができる。このメソッドはUnicode文字またはクラス変数 CHAR_UNDEFINEDを返す。文字,数字,特殊記号に対応したキーを押して, 離した場合は,この例と同様のキーイベントが起る。

  2. 「→」キーを押して離すと,次の2つのキーイベントが発生する。 どのキーが操作されたかは,getKeyCodeメソッドによって取得できる。 このメソッドは、KeyEventクラスのクラス変数として定義されている仮 想キーコードを返す。仮想キーコードの値は整数(int)で、どのキー がタイプされたのかを知らせるために使われる。「→」キーの仮 想キーコードはVK_RIGHTで,KeyEventクラス内部ではその値は39と定義 されている。

キーイベント処理の記述

コンポーネント上でのキー入力を取得して、それに反応させるには、 addKeyListenerメソッドを使ってキーリスナーを設定する。KeyListenerの イベント処理のメソッドには,keyPressed,keyReleased,keyTypedがあり, これらは,起ったキーイベントのタイプに応じて呼び出される。

キーイベントのタイプが 実行される。一つのキー操作で,複数のKeyEventが生成されるので,プログラム の機能に合わせたイベント処理メソッドを定義する。

たとえば,「j」キーがタイプされたら,それに応じた処理をするには, keyTypedメソッドを定義し,getKeyCharメソッドで取得したキーキャラク ターが「j」なら,その処理を記述する。

    public void keyTyped(KeyEvent e) {  
        char c = e.getKeyChar();
        if (c == 'j') { 
          //「j」キーが押されたときの処理
        }
   }

キーボードフォーカスの取得

コンポーネント上で,KeyEvent処理をする場合,そのコンポーネントにあ らかじめキーボードフォーカスを指定しておく必要がある。多くの場合, Swingパッケージのコンポーネントのサブクラスとして定義されたコンポー ネントがその処理の対象になるであろう。その場合,具体的には mouseListenerをインプリメントして,マウスボタンが押されたら, requestFocusメソッドを実行するようにしておく。

public void mousePressed(MouseEvent e) { requestFocus(); //キーボードフォーカスの設定 }

練習問題12.6

練習問題12.6のプログラムをKeyEventを処理を使って書いたソースコードを次 に示します。
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import tg.Turtle;
import tg.TurtlePanel;

public class TurtleDraw extends JPanel {
   TurtlePanel tf;
   Turtle kame;
   ButtonPanel bp;
   public TurtleDraw(){
      setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
      tf = new TurtlePanel();  //TurtlePanelを生成
      bp = new ButtonPanel(this);  
      kame = new Turtle();
      tf.addMesh();   //TurtlePanelに格子を描く
      tf.add(kame);   //TurtlePanelにTurtleオブジェクトを置く
      tf.setAlignmentX(JComponent.CENTER_ALIGNMENT);  //TurtlePanelを中央に置く
      setListener();  //TurtlePanelにリスナーを設定
      add(tf);
      add(bp);
   }

   void setListener(){
       KeyInput listener = new KeyInput();
       tf.addMouseListener(listener); //TurtlePanelにマウスリスナーを設定
       tf.addKeyListener(listener); //TurtlePanelにキーリスナーを設定
   }
   
   public static void main(String args[]){
      TurtleDraw t = new TurtleDraw();
      JFrame frame = new JFrame("Turtle Draw");//JFrameオブジェクトを生成
      Container c = frame.getContentPane(); //フレームの内容表示域を得る
      c.add(t, BorderLayout.CENTER);
      frame.pack();               //フレームを必要最小の大きさにする
      frame.setVisible(true);     //フレームを画面に見せる
   }

   class ButtonPanel extends JPanel implements ActionListener{
      TurtleDraw top;
      JButton fB, bB, rB, lB;

      ButtonPanel(TurtleDraw t){
        top = t;
        setBackground(Color.white);
        fB = addButton("前進");
        bB = addButton("後退");
        rB = addButton("右旋回");
        lB = addButton("左旋回");
      }

     JButton addButton(String label){
        JButton button = new JButton(label);
        button.setBackground(Color.white);
        button.addActionListener(this);
        add(button);
        return button;
     }

     public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if (obj == fB) { top.kame.fd(10); }
        else if (obj == bB) { top.kame.bk(10); }
        else if (obj == rB) { top.kame.rt(10); }
        else if (obj == lB) { top.kame.lt(10); }
     }
   }

   class KeyInput extends KeyAdapter implements MouseListener{
      public void keyTyped(KeyEvent e) {
        char c = e.getKeyChar();  //タイプされたキーのキーキャラクターを取得
        if (c == 'f') { kame.fd(10); }
        else if (c == 'b') { kame.bk(10); }
        else if (c == 'r') { kame.rt(10); }
        else if (c == 'l') { kame.lt(10); }
      }     

      public void mousePressed(MouseEvent e) { 
           tf.requestFocus();  //TurtlePanelにキーボードフォーカスを設定
      }
      public void mouseReleased(MouseEvent e) { }
      public void mouseClicked(MouseEvent e) { }
      public void mouseExited(MouseEvent e) { }
      public void mouseEntered(MouseEvent e) { }
   }
}