窓は窓枠と窓ガラスでできています。
窓枠に対応するのがJFrameです。
窓ガラスがはまる部分に処理内容に対応した部品を配置し、配置したインスタンスを通して処理を行います。 部品にはボタンやメニューなどもあります。
1 import javax.swing.*;
2 import java.awt.*;
3
4 public class Sample3
5 {
6 public static void main(String[] args)
7 {
8 JFrame f;
9 Container cp;
10 JPanel p;
11
12 f = new JFrame();
13 f.setVisible(true);
14 f.setTitle("swing");
15 f.setSize(200, 300);
16 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
17 cp = f.getContentPane();
18 p = new JPanel();
19 cp.add(p);
20 }
21 }
JFrame, Container, JPanelの3つのクラスを利用しています。
12~16行目はウインドウ枠の処理です。ウインドウの表示を参照。
枠の内側で部品を配置できる場所をContentPaneと呼び、クラスはContainerです。
JFrameインスタンスfのContentPaneを得て、変数cpに記憶しておきます。
この結果インスタンスの状態はこのようになります。
注
GUIではプログラムの実行開始時にだけ、ウインドウ内部が描画されるわけではありません。
ウインドウの大きさが変えられたり、ボタンが押されたり、文字が入力されたり など、いろいろな場面で描画が行われます。
JPanel上の描画が必要になったときには、JPanelクラスのpaintComponentメソッドが実行されます。
JPanelクラスのpaintComponentメソッドではプログラムで表示内容を指定できません。
JPanelクラスを継承してサブクラスを作成し、paintComponentメソッドを記述します。
サブクラス名を Sample4 とした例を示します。
paintComponentは引数としてGraphicsクラスのインスタンスをとります。 この例では変数名をgとしています。
描画はインスタンスgに対してメソッドを使って指示します。
drawRectは長方形を描くメソッドです。 引数は左上のx座標,y座標,横幅,縦幅です。
座標系は図のとおりです。
上のサンプルプログラムSample3でJPanelとなっていた箇所を、 このクラス(Sample4)で置き換えます。
public static void main(String[] args) { ... JPanel p; ... p = new Sample4(); ... }
するとContainerに配置されるのはSample4クラスのインスタンスとなり、 描画が必要なときにはSample4クラスのpaintComponentが実行されます。
変数pの宣言は
のままになっていますが、代入されるインスタンスはSample4クラスのものです。
mainメソッドは特殊なメソッドで、どのクラス内に記述するかはあまり意味を持ちません。
コマンド
>java クラス名
を行うと、そのクラス内のmainメソッドが実行されるだけです。
クラスの機能は普通のメソッドとして記述し、 mainメソッドは主として動作確認のために使ってきました。
例1
上のサンプルではSample4.javaでクラスを定義し、 Sample3.javaにSample4クラスを利用するmainメソッドを記述しています。
この場合、コンパイル後
> java Sample3
で実行できます。
コンパイルは2つのファイルを別々に行っても良いし、 mainメソッドのあるSample3.javaをコンパイルすれば一緒にコンパイルされます。
例2
ウインドウを作成し表示するためのmainメソッドを、 Sample4クラス内に記述すれば Sample4.javaだけを作成、コンパイルし
> java Sample4
で実行できます。(プログラムは1つのファイルで済みます)
public class Sample4 extends JPanel { void paintComponent(...) { ... } public static void main(...) { ... } }