AWT(Abstract Window Toolkit)


多くの言語では,グラフィクスを扱うライブラリは言語処理系およびOSに固 有のものであり,たとえば Unixの X Window system 用に書いたプログラムは Windows上で動かすことはできない.

Java言語では,グラフィクスを扱う部分はAWT(Abstract Window Toolkit)と いうOSに依存しないライブラリとして,提供されている..

ただし,AWTだけでは不十分なため,JDK 1.2からは Java2D, Java3D という APIが加わっている(ただし,Java3Dは教育用計算機システムの端末では今のと ころ使うことができない).また,AWTに関してもバージョンによって,動作の 違いがあるなど問題はある.また,OSによって見栄えが変わるのを防ぐために, かなりの部分を Java で書き直した Swing というツールキットも用意されて いるが,基本的な考え方は変わらないので,ここでは AWTをベースに考える.


AWTは基本的には GUI(Graphical User Interface) 部品を組み合わせて,対 話的なGUIプログラムを作るためのものなので,ちょっと絵を描いてみようと するには,おおげさな枠組みが用意されているが,ここでは AWT の機能のほ んの一部分を使ってプログラムを書くことにする.

ウィンドウを表示してみよう

単純に 600 x 400 のサイズのウィンドウを作ってみる.

AWT のパッケージに属するクラスの中を探すとタイトル付のウィンドウ に対応するクラスは, Frame クラス である.

Frameを作って表示するには,

といった手順を取る. これに対応するプログラムを書いてみる.
  // AWT を使う際には java.awt.* を import することが必要.
import java.awt.*;

class Awt1 {
  public static void main(String[] args){
      // 「Awt1」というタイトルを持つウィンドウを作成
    Frame frame=new Frame("Awt1");
      // ウィンドウのサイズを 600 x 400 に変更
    frame.setSize(600,400);
      // ウィンドウを表示
    frame.setVisible(true);
  }
}
AWTを使うためには,最初に,
import java.awt.*;
とする必要がある.

このプログラムを実行すると,(600,400) のサイズのウィンドウが開く.

注意: Java2 SDK 1.3 上で CDE以外のウィンドウマネージャを使っている時は, setSizeで指定されたサイズ通りのウィンドウができないというバグが残って いるようです.良い解決法が見つかるまでは,後で手でresize するようにし てください.

これまでのプログラムは,静的メソッド main の始めから始まって,終りで 終わっていたが,このプログラムは main メソッドが終了しても,自律的に動 くMyFrameクラスのオブジェクトが存在する限り終わらない.終了するには C-c を押す必要がある.


ウィンドウに何かを書いてみよう

絵を書くためには,さきほどの Frame のサブクラスを作成して,その中(正 確にはFrameの祖先のクラスである Component クラス)の paint メソッドをオーバーライド (override) する(この一文をわかって もらいたいがために,先週は面白くない話を聞かせることになってしまった).

paint メソッドは名前の通り, GUI部品を描画するためのメソッドである. 引 数として, Graphicsクラス のオブジェクトが渡される. Graphicsクラスは, 描画す る際に必要な以下のような情報を含む.

Graphicsクラスにはさまざまな描画メソッドが用意されている. 説明は, Graphicsクラス を見てもらうことにして, 試しにいろいろ書いてみる.

import java.awt.*;

class MyFrame extends Frame{
  public MyFrame(String name){
    super(name);
  }
  public void paint(Graphics g){
    System.out.println("paint("+g+") is called");
	// 使う色を黒に変更する
    g.setColor(Color.black); 
	// (0,0)から幅600高さ400の長方形(rectangle )を塗り潰す(fill)
    g.fillRect(0,0,600,400); 
	// 使う色を黄色に変更する
    g.setColor(Color.yellow); 
	// (10,10)から幅190, 高さ20の3次元風の盛り上がった長方形を描画する
    g.draw3DRect(10,10,190,20,true); 
	// (10,40)から幅190, 高さ20の3次元風の盛り上がった長方形を塗りつぶす
    g.fill3DRect(10,40,190,20,true); //
	// (10,70)から幅190, 高さ20の3次元風のへこんだ長方形を描画する
    g.draw3DRect(10,70,190,20,false); //
	// (10,100)から幅190, 高さ20の3次元風のへこんだ長方形を塗りつぶす
    g.fill3DRect(10,100,190,20,false); //
	// (10,130)から幅190, 高さ20の長方形を描画する
    g.drawRect(10,130,190,20); //
	// (10,160)から幅190, 高さ20の長方形を塗りつぶす
    g.fillRect(10,160,190,20); //
        // R値 0, G値 200, B値 200 の色(暗めの水色)に設定する
    g.setColor(new Color(0,200,200));
	// (10,190)から幅190, 高さ20の領域に内接する楕円を描画する
    g.drawOval(10,190,190,20); //
	// (10,220)から幅190, 高さ20の領域に内接する楕円を塗りつぶす
    g.fillOval(10,220,190,20); //
	// (10,250)から幅190, 高さ20の領域で, 四端が縦半径5横半径5の楕円弧であるような長方形を書く
    g.drawRoundRect(10,250,190,20,5,5); //
	// (10,280)から幅190, 高さ20の領域で, 四端が縦半径5横半径5の楕円弧であるような長方形を塗りつぶす
    g.fillRoundRect(10,280,190,20,5,5); //
	// (10,310)-(200,360)の間に線を引く
    g.drawLine(10,310,200,360); 
	// (10,340) を起点(左下端)に"ABCDE"という文字列を表示する
    g.drawString("ABCDE",10,340); 
        //  使用するフォントを 書体名 Courier の太字(BOLD), 30ポイントに設定
    g.setFont(new Font("Courier",Font.BOLD,30));
	// (10,370) を起点(左下端)に"FGHIJ"という文字列を表示する
    g.drawString("FGHIJ",10,370); 
       // (200,30)から幅60高さ40の領域に始点45度, 角度180度で弧形を描く
    g.drawArc(200,30,60,40,45,180);
       // (260,30)から幅40高さ60の領域に始点135度, 角度270度で弧形を塗りつぶす
    g.fillArc(260,30,40,60,135,270);
    int[] xs0={220,220,280,340,340};
    int[] ys0={100,150,120,150,100};
    g.drawPolygon(xs0,ys0,5);
       // (220,100)-(220,150)-(280,120)-(340,150)-(340,100) で囲まれる多角形(polygon)を書く
    int[] xs1={220,220,280,340,340};
    int[] ys1={200,250,180,250,200};
    g.fillPolygon(xs1,ys1,5);
       // (220,200)-(220,250)-(280,180)-(340,250)-(340,200) で囲まれる多角形(polygon)を塗りつぶす
  }
}
class Awt2 {
  public static void main(String[] args){
    MyFrame frame=new MyFrame("Awt2");
    frame.setSize(600,400);
    frame.setVisible(true);
  }
}
これで,MyFrameの中に main メソッドを書くと1つのクラス定義に まとめることができる.
import java.awt.*;

class MyFrame extends Frame{
  public MyFrame(String name){
    super(name);
  }
  public static void main(String[] args){
    MyFrame frame=new MyFrame("MyFrame");
    frame.setSize(600,400);
    frame.setVisible(true);
  }
  public void paint(Graphics g){
    System.out.println("paint("+g+") is called");
	// 使う色を黒に変更する
    g.setColor(Color.black); 
	// (0,0)から幅600高さ400の長方形(rectangle )を塗り潰す(fill)
    g.fillRect(0,0,600,400); 
	// 使う色を黄色に変更する
    g.setColor(Color.yellow); 
	// (10,10)から幅190, 高さ20の3次元風の盛り上がった長方形を描画する
    g.draw3DRect(10,10,190,20,true); 
	// (10,40)から幅190, 高さ20の3次元風の盛り上がった長方形を塗りつぶす
    g.fill3DRect(10,40,190,20,true); //
	// (10,70)から幅190, 高さ20の3次元風のへこんだ長方形を描画する
    g.draw3DRect(10,70,190,20,false); //
	// (10,100)から幅190, 高さ20の3次元風のへこんだ長方形を塗りつぶす
    g.fill3DRect(10,100,190,20,false); //
	// (10,130)から幅190, 高さ20の長方形を描画する
    g.drawRect(10,130,190,20); //
	// (10,160)から幅190, 高さ20の長方形を塗りつぶす
    g.fillRect(10,160,190,20); //
        // R値 0, G値 200, B値 200 の色(暗めの水色)に設定する
    g.setColor(new Color(0,200,200));
	// (10,190)から幅190, 高さ20の領域に内接する楕円を描画する
    g.drawOval(10,190,190,20); //
	// (10,220)から幅190, 高さ20の領域に内接する楕円を塗りつぶす
    g.fillOval(10,220,190,20); //
	// (10,250)から幅190, 高さ20の領域で, 四端が縦半径5横半径5の楕円弧であるような長方形を書く
    g.drawRoundRect(10,250,190,20,5,5); //
	// (10,280)から幅190, 高さ20の領域で, 四端が縦半径5横半径5の楕円弧であるような長方形を塗りつぶす
    g.fillRoundRect(10,280,190,20,5,5); //
	// (10,310)-(200,360)の間に線を引く
    g.drawLine(10,310,200,360); 
	// (10,340) を起点(左下端)に"ABCDE"という文字列を表示する
    g.drawString("ABCDE",10,340); 
        //  使用するフォントを 書体名 Courier の太字(BOLD), 30ポイントに設定
    g.setFont(new Font("Courier",Font.BOLD,30));
	// (10,370) を起点(左下端)に"FGHIJ"という文字列を表示する
    g.drawString("FGHIJ",10,370); 
       // (200,30)から幅60高さ40の領域に始点45度, 角度180度で弧形を描く
    g.drawArc(200,30,60,40,45,180);
       // (260,30)から幅40高さ60の領域に始点135度, 角度270度で弧形を塗りつぶす
    g.fillArc(260,30,40,60,135,270);
    int[] xs0={220,220,280,340,340};
    int[] ys0={100,150,120,150,100};
    g.drawPolygon(xs0,ys0,5);
       // (220,100)-(220,150)-(280,120)-(340,150)-(340,100) で囲まれる多角形(polygon)を書く
    int[] xs1={220,220,280,340,340};
    int[] ys1={200,250,180,250,200};
    g.fillPolygon(xs1,ys1,5);
       // (220,200)-(220,250)-(280,180)-(340,250)-(340,200) で囲まれる多角形(polygon)を塗りつぶす
  }
}

paintはウィンドウシステムが適当と思ったタイミングで呼ばれる.具体的には 以下のような時である.