中学2年の次男かずは最近,キーボードに向っていることが多い。何をしているのかとのぞき込むとタイプウェル国語Rというフリーのタイピングソフトをhttp://www.twfan.com/index.htmlからダウンロードして,一日に何回も練習しているのだ。聞けば,部活(陸上競技部)の仲間とタイプスピードを競っていると言う。中学生はムダなエネルギーに満ち溢れているのか,走るスピードだけでなくタイプスピードまで競ってしまう。どれくらいの時間で打てるのかと,高校2年の兄こうしろうが聞くと「110秒ぐらい」と答える。「まだまだやな」とこうしろうと私も挑戦してみた。こうしろうは,けたたましいキーボード音で70秒のタイムを出した。私は「ミスタイプが多いので,やり直せ」とタイピング・ソフトに叱られたので,「自分の考えるスピードより速くタイプできても,なんにもならんやろ」とうそぶいて競争から脱落した。

 かずは,その後も毎日,毎日コツコツと練習を重ね,100M走ではコンマ数秒を縮めることが大変らしいが,タイピングでは数日間で30秒近く縮め,82秒で入力できるようになったと言う。無駄なことには熱中できる中学生という年頃がうらやましくもある。

 かずはなめらかにキーボードを打つが,こうしろうと私はバチバチと叩く。タイプ音は入力者やキーボードによって異なるが,いつも聞いていると誰の音か,何をしている音かが聞き分けられるようになる。妻はポツリ,ポツリとキーボードを打ち,ほのちゃん(小1)はマウスしか使わない。

 キーボード音は小さな音であっても気になるときは気になるもので,休日に昼寝をしているときにキーボードの音で起こされると「部屋へ行って勉強でもしてこい」と,どなりたくなる。

 長い前振りだったが,Javaではイベントの発生をイベントリスナーで聞く。イベントはGUIのフォーム上のボタンを押したとか,フォームを閉じるボタンをクリックすることで発生する。Javaでは,AWTやSwing,そしてEclipseでも使われているSWTなどのGUIライブラリを使って,GUIのプログラムを作成することができる。他の2者に対してAWTは古い感じがするが,基本なのでとりあえず,こうしろうはAWTを使ったGUIプログラムの勉強をした。

 下記のプログラムはカンバス(Canvas)に指定した色(Red,Green,Blue)でドットを描くプログラムである。インポート部から,クラス定義,コンストラクタ,mainメソッドをまず,ざっと見てください。

----------------------------------------------------------

import java.awt.*;
import java.awt.event.*;

----------------------------------------------------------
 awtとawt.eventのクラスをインポートしている。
----------------------------------------------------------

public class ColorDots extends Frame {
  private FlowLayout flow;
  private Choice choice;
  private Canvas mc;
  private int rgb[]={255,0,0};

----------------------------------------------------------
 Frameクラスを継承してColorDotsクラスを作る。FrameはGUI部品をおく土台(ウィンドウ)となる。FlowLayout,Choice,Canvasオブジェクトについては後で触れる。int型のrgb配列は,Red,Green,Blueの色を指定するための配列である。
----------------------------------------------------------

  public ColorDots() {
    super("ドットを描こう");
    setSize(400,250);
    flow = new FlowLayout();
    setLayout(flow);
    addWindowListener(new CloseAction());
    choice = new Choice();
    choice.add("Red");
    choice.add("Green");
    choice.add("Blue");
    add(choice);
    choice.addItemListener(new ChoiceAction());
    mc = new Canvas();
    mc.setBounds(20,20,300,200);
    add(mc);
    mc.addMouseListener(new ClickAction());
  }

----------------------------------------------------------
 クラス名と同名のコンストラクタメソッドでは,superで親クラス(Frame)のコンストラクタを呼び出している。FlowLayoutは左から右に流れるレイアウトを作る。addWindowListener(new CloseAction())が最初のイベントリスナーを仕掛けているところだ。これはウィンドウ右上のX(閉じる)ボタンを押したときに,ウィンドウを閉じるためのリスナーだ。

 次にChoiceを作成する。ChoiceはVBやVBAで言うと,コンボボックスのことである。Red,Green,Blueの文字列を設定し,フレームに追加(add)している。choice.addItemListener(new ChoiceAction())でChoiceに設定した色が選択されたときの動作を登録している。次にCanvasオブジェクトmcを生成し,カンバス上でマウスがクリックされたときの動作を登録している。
----------------------------------------------------------

  public static void main (String args []) {
    new ColorDots().show();
  }

----------------------------------------------------------
 プログラムはmainメソッドから開始されるので,ColorDotsクラスを生成し,showメソッドで表示している。
----------------------------------------------------------

  class ChoiceAction implements ItemListener {
    public void itemStateChanged(ItemEvent e){
      switch (choice.getSelectedIndex()) {
        case 1:
          rgb[0]=0;
          rgb[1]=255;
          rgb[2]=0;
          break;
        case 2:
          rgb[0]=0;
          rgb[1]=0;
          rgb[2]=255;
          break;
        default:
          rgb[0]=255;
          rgb[1]=0;
          rgb[2]=0;
          break;
      }
    }
  }

----------------------------------------------------------
 choiceに登録しているリスナーはItemListenerインターフェースを実装(implements)したChoiceActionである。クラスの中にクラスを宣言しているので,ChoiceActionはクラス内クラスと呼ばれる。ItemListener からはitemStateChangedメソッドが呼び出される。choiceでGreenが選ばれたとき,getSelectedIndex()は1を返すのでRGBのGreenを255にし,RedとBlueを0にしている。2のときはBlueを255に,それ以外(0のとき)はRedを255にしている。
----------------------------------------------------------

  class ClickAction extends MouseAdapter {
    public void mouseClicked(MouseEvent ev){
      Graphics gr = mc.getGraphics();
      int x = ev.getX();
      int y = ev.getY();
      gr.setColor(new Color(rgb[0],rgb[1],rgb[2]));
      gr.fillOval(x  - 5,y - 5,10,10);
      gr.dispose();
    }
  }

----------------------------------------------------------
 ここから,ちょっと話しがややこしくなるが,今回がJavaの基礎編の最後なので,がんばって付き合ってもらいたい。Canvas型のオブジェクトmcに登録しているClickActionは,リスナーを実装しているのではなく,アダプタ(MouseAdapter)を継承している。なぜか?ItemListenerから呼び出されるメソッドはitemStateChangedだけなのだが,MouseListenerから呼び出されるメソッドはmouseClicked,mousePressed,mouseEntered,mouseExited,mouseReleasedとたくさんある。
----------------------------------------------------------

  class ClickAction implements MouseListener {
    public void mouseClicked(MouseEvent ev){
      Graphics gr = mc.getGraphics();
      int x = ev.getX();
      int y = ev.getY();
      gr.setColor(new Color(r,g,b));
      gr.fillOval(x  - 5,y - 5,10,10);
      gr.dispose();
    }
    public void mousePressed(MouseEvent evt) {}
    public void mouseEntered(MouseEvent evt) {}
    public void mouseExited(MouseEvent evt) {}
    public void mouseReleased(MouseEvent evt) {}
  }

----------------------------------------------------------
 MouseListenerインターフェイスを実装(implements)すると上記のように,今回は使わないメソッドも空実装しないといけないのである。MouseAdapterにはすべてのメソッドを空実装してあるので,アダプタを継承(extends)した方が,プログラミングが楽なのだ。  mouseClickedメソッドの内容はマウスがクリックされた座標を中心にchoiceで選択されている色でドットを描くことだ。

(マウスをポツポツとクリックしてドットをカンバスに描いていく)
----------------------------------------------------------

  class CloseAction extends WindowAdapter {
    public void windowClosing(WindowEvent e){
      System.exit(0);
    }
  }

----------------------------------------------------------
 addWindowListenerで登録しているCloseActionも同様の理由で,WindowAdapterクラスを継承している。