教育サーバーのページ
オンラインテキスト目次
ソフトウエア基礎演習
多くのGUI環境ではグラフィックスを表示することができる。 一般にグラフィックスとは、線や点、四角形などの図形のことを指す。
JavaのAWTでは、Graphicsオブジェクトを使ってグラフィックス描画ができる。
※ 現在では、Java2Dというさらに高級なグラフィックス描画の仕組みが用意されているが、ここでは従来からAWTに備わっている機能を紹介する。
以下のプログラムDrawGraphicsTest.javaはJavaによるグラフィックス描画の例である。
import java.awt.*; import java.awt.event.*; class GraphicsFrame extends Frame { public GraphicsFrame() { setSize(200, 200); addWindowListener(new MyWindowAdapter()); } public void paint(Graphics g) { g.drawLine(50,50,150,150); g.drawLine(50,150,150,50); g.drawRect(70,70,60,60); g.drawOval(50,50,100,100); } } class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public class GraphicsTest { public static void main(String[] args) { GraphicsFrame f = new GraphicsFrame(); f.setVisible(true); } }
プログラムの説明
Frameクラスから継承したGraphicsFrameクラスにpaintメソッドを定義している。 プログラムの他の部分は従来と変わらない。 paintメソッドはFrameなどのコンポーネントに何か描画すべきときに呼ばれるメソッドである。 Frame内に何か描画したければ、paintメソッド内にそのプログラムを書けば良いわけである。
paintメソッドにはGraphics型の引数があり、 このGraphicsオブジェクトが備えるグラフィックス描画のメソッドを呼べば良い。 例えば、
g.drawLine(50,50,150,150)
は、 Graphicsオブジェクトのgに対して直線を描画せよというdrawLineメソッドを呼び出している。 drawLineメソッドの引数をそれぞれx1, y1, x2, y2 とすると、 drawLineメソッドは、点(x1,y1)から点(x2,y2)までの直線を描画する。 つまり、例の場合は、(50,50)-(150,150)の直線を描画する。 次の、
g.drawLine(50,150,150,50)
は、
(50,150)-(150,50)の直線を描画する。この2本の線でちょうど×印を描いているのである。
なお、Graphicsオブジェクトを使う場合、原点(0,0)がコンポーネントの左上端であり、
xの値が増えるにつれ右に移動する。また、yの値が増えるにつれ下に移動する。
数学でグラフを描画する場合と違い、yの値が下に向いていることに注意せよ。
※ Frameを使う場合、描画範囲にウインドウのタイトルバーが含まれるため、
原点(0,0)はタイトルバーの左上端となる。タイトルバーの場所は描画されないため、
実際に描画できるのはyがタイトルバーの幅を上回った所からとなる。例えば、
g.drawLine(0,0,100,100)などを実行すると確認できる。
drawRectは長方形(矩形)を描画するメソッドである。引数をそれぞれ x1, y1, w, h とすると、 始点を(x1,y1)とし、幅をh、高さをhとした長方形を描画する。 長方形の辺はx軸もしくはy軸と並行になる。また始点は長方形の左上の頂点の座標である。 例の、
g.drawRect(70,70,60,60)
では、 始点が(70,70)、幅と高さが60となる。つまり、(70,70)-(130,130)の長方形 を描画することになる。
drawOvalは楕円を描画するメソッドである。引数をそれぞれ x, y, w, h とすると、 始点を(x,y)とし幅w,高さhとした長方形に囲まれる最大の楕円を描画する。 幅と高さを同じ値にした場合は真円を描画することになる。例の、
g.drawOval(50,50,100,100)では、 始点が(50,50)、幅と高さが100となる。つまり、(50,50)-(150,150)の長方形で 囲まれた真円となる。いいかえると、中心が(100,100)、半径が50の円となる。
上記のプログラムでは、図形は黒で描画されたはずである。 この描画色を変更することができる。 以下のプログラム ColorTest.java では色の指定をしている。
import java.awt.*; import java.awt.event.*; class ColorFrame extends Frame { public ColorFrame() { setSize(200, 200); addWindowListener(new MyWindowAdapter()); setBackground(Color.yellow); } public void paint(Graphics g) { g.setColor(Color.red); g.drawLine(50,50,150,150); g.drawLine(50,150,150,50); g.setColor(Color.green); g.drawOval(50,50,100,100); g.setColor(new Color(0,0,255)); g.drawRect(70,70,60,60); } } class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public class ColorTest { public static void main(String[] args) { ColorFrame f = new ColorFrame(); f.setVisible(true); } }
まず、グラフィックス描画に使われる色には、前景色と背景色がある。 前景色は線や四角形などの図形を描画する時に使用する色である。 また、背景色はウインドウなどに何も描かれていない状態で表示されている色である。
前景色を変更するには、Graphicsオブジェクトに対してsetColorメソッドを呼び出す。 引数には設定したい色を指定するが、これはColorオブジェクトである。 Colorオブジェクトの指定方法として主に以下の2つがある。
例 | 説明 |
---|---|
Color.black | 黒色 |
Color.blue | 青色 |
Color.cyan | シアン色 |
Color.darkGray | 濃い灰色 |
Color.gray | 灰色 |
Color.green | 緑色 |
Color.lightGray | 薄灰色 |
Color.magenta | マゼンタ色 |
Color.orange | オレンジ色 |
Color.pink | ピンク色 |
Color.red | 赤色 |
Color.white | 白色 |
Color.yellow | 黄色 |
背景色を指定するには、そのコンポーネントに対して setBackgroundメソッド
を呼び出す。引数には、前景色と同様にColorオブジェクトを指定する。
例えば、上記のプログラムでは、ColorFrameクラスのコンストラクタの中で
背景色を黄色に指定している。
※ 前景色を指定するのに、背景色と同様にコンポーネントに対して
setForegroundメソッドを呼ぶ方法がある。ただし、paintメソッドの中で
setForegroundメソッドを呼んではならない。setForegroundメソッドでは
repaintメソッドを呼んでしまうので結果的にpaintメソッドを何重にも
呼んでしまいJavaが高負荷になってしまうからである。
import java.awt.*; import java.awt.event.*; class ImageFrame extends Frame { Image im; public ImageFrame() { setSize(280, 300); addWindowListener(new MyWindowAdapter()); Toolkit tk = Toolkit.getDefaultToolkit(); im = tk.getImage("usb-plugs.jpg"); } public void paint(Graphics g) { g.drawImage(im, 20, 50, this); } } class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public class ImageTest { public static void main(String[] args) { ImageFrame f = new ImageFrame(); f.setVisible(true); } }サンプルの画像ファイル ← この画像ファイルをJavaのプログラムを保存してあるディレクトリに保存して使用せよ。
AWTでは、JPEG, PNG, GIF形式の画像ファイルを読み込み表示することができる。 画像を取り扱うにはImageクラスを使う。まず、画像ファイルを読み込み Imageオブジェクトを生成する。
Toolkit tk = Toolkit.getDefaultToolkit(); im = tk.getImage("usb-plugs.jpg");
ここでは、Toolkitオブジェクトを使用している。 Toolkit.getDefaultToolkit()で、通常使われるToolkitオブジェクトを取得し、 そのオブジェクトのgetImageメソッドを呼び出すことで画像ファイルを読み Imageオブジェクトを返している。 引数の"usb-plugs.jpg"は読み込みたい画像ファイルである。
画像の描画は、paintメソッド内で行なっている。
g.drawImage(im, 20, 50, this);
Graphicsオブジェクトに対し、drawImageを呼び出している。 drawImageの引数は、それぞれ画像を示すImageオブジェクト、x座標、y座標、 ImageObserverオブジェクトである。xとyはそれぞれ、画像の左上端の座標である。 ImageObserverオブジェクトとしては、コンポーネント、つまりこの場合 this を指定すればよい。
以下のプログラム MouseEventTest.java はマウスイベントを処理するプログラムである。
import java.awt.*; import java.awt.event.*; class MouseEventFrame extends Frame { public MouseEventFrame() { setSize(280, 300); addWindowListener(new MyWindowAdapter()); addMouseListener(new MyMouseAdapter()); addMouseMotionListener(new MyMouseMotionAdapter()); } } class MyMouseAdapter extends MouseAdapter { public void mousePressed(MouseEvent e) { System.out.println("Pressed at ("+e.getX()+","+e.getY()+")"); } public void mouseClicked(MouseEvent e) { System.out.println("Clicked at ("+e.getX()+","+e.getY()+")"); } public void mouseReleased(MouseEvent e) { System.out.println("Released at ("+e.getX()+","+e.getY()+")"); } } class MyMouseMotionAdapter extends MouseMotionAdapter { public void mouseMoved(MouseEvent e) { System.out.println("Moved at ("+e.getX()+","+e.getY()+")"); } public void mouseDragged(MouseEvent e) { System.out.println("Draged at ("+e.getX()+","+e.getY()+")"); } } class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public class MouseEventTest { public static void main(String[] args) { MouseEventFrame f = new MouseEventFrame(); f.setVisible(true); } }
マウスイベントは、マウスボタンを押した、離した、クリックしたなど、 低レベルのイベントである。つまり、マウスというハードウェアに近いイベントと言える。これに対し、ボタンで使用したアクションイベントは、高レベルのイベントである。これは、GUIとして画面上に構成したボタンを押したという、アプリケーションソフトに近いイベントと言える。
マウスイベントには、マウスボタンを押した、離したというマウスの動き以外のイベントと、マウスを移動した時に発生するイベントの2種類に分かれており、それぞれ MouseListener, MouseMotionListenerといったイベントリスナーが対応する。 つまり、MouseListenerやMouseMotionListenerといったインタフェースを実装することでイベントを処理することができる。あるいは、MouseAdapterもしくはMouseMotionAdapterというアダプタクラスが用意されており、それらを継承してイベント処理することもできる。
MouseListenerとMouseMotionListenerには、それぞれ以下のようなイベント処理のメソッドが宣言されている。
MouseListenerに用意されているイベント処理メソッド
メソッド名 イベントの説明 mouseClicked マウスボタンをクリックした(押してから離した) mouseEntered コンポーネントにマウスが入った mouseExited コンポーネントからマウスが出た mousePressed マウスボタンを押した mouseReleased マウスボタンを離した
MouseMotionListenerに用意されているイベント処理メソッド
メソッド名 イベントの説明 mouseDragged マウスボタンを押したままドラッグした(移動した) mouseMoved マウスボタンを押さずにマウスを移動した
マウスの現在の位置は、イベント処理メソッドの引数であるMouseEventオブジェクトに対し、getX もしくは getYメソッドを呼ぶことで得られる。それぞれX座標とY座標である。
以下のプログラム KeyEventTest.java はキーイベントを処理するプログラムである。
import java.awt.*; import java.awt.event.*; class KeyEventFrame extends Frame implements KeyListener { char key='\0'; public KeyEventFrame() { setSize(280, 300); addWindowListener(new MyWindowAdapter()); addKeyListener(this); requestFocus(); } public void paint(Graphics g) { g.drawString(""+ key, 20,100); } public void keyTyped(KeyEvent e) { System.out.println("Typed '"+e.getKeyChar()+"'"); key = e.getKeyChar(); repaint(); } public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) {} } class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public class KeyEventTest { public static void main(String[] args) { KeyEventFrame f = new KeyEventFrame(); f.setVisible(true); } }
キーボードのイベントは、KeyListenerというイベントリスナーで処理する。 KeyListenerのイベント処理メソッドは以下の通りである。
メソッド名 イベントの説明 keyPressed キーを押した keyReleased キーを離した keyTyped キーをタイプした
キーをタイプしたというのは、キーを押したというのより高レベルのイベントで、 何か文字を入力した場合に、発生する。キーを押したというのは、 例えば、Shiftキーを押したなど、文字入力にいたっていないレベルのイベントも処理できる。単に文字入力を処理するなら、キータイプのみ処理すれば良いが、 ShiftやCtrlといった装飾キーを押した時の検知も必要な場合は、キーを押したイベントの処理もする必要がある。
なお、押した文字を得るには、KeyEventオブジェクトに対して、getKeyCodeメソッドを呼び出せば良い。