学生向けプログラミング入門

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース

Javaプログラミング入門その37 楕円図形を連続して表示させるプログラム

<<前  [TOP]  次>>


ここからは、Swingについて取り上げていきます。


Swingは下図のようにAWT上に構築されたGUIを構築するためのパッケージです。

java.lang.Object
 |
 +--java.awt.Component
     |
     +--java.awt.Panel+--java.applet.Applet+--javax.swing.JApplet
     |
     +--java.awt.Window
     |    |
     |    +--java.awt.Frame+--javax.swing.JFrame
     |    +--java.awt.Dialog+--javax.swing.JDialog
     |    +--javax.swing.JWindow
     |
     +--javax.swing.JComponent
         |
         +--javax.swing.JButton
         |    |
         |    +--javax.swing.JButton
         |    +--javax.swing.JMenuItem+--javax.swing.JMenu
         +--javax.swing.JPanel
         +--javax.swing.JTable
             :
             :

図の通り、Swingコンポーネントは「java.awt.Container」のサブクラスになります。
このことはSwingコンポーネントがレイアウトなどを行えることを表します。


Swingの多くのコンポーネントは「軽量コンポーネント」と呼ばれており、実行されるシステムとは密接に関係しないコンポーネントです。
AWTの多くのコンポーネントは「重量コンポーネント」です。
また、Swingコンポーネントの中でも「アプレット(JApplet)」「フレーム(JFrame)」「ダイアログ(JDialog)」「ウィンドウ(JWindow)」は重量コンポーネントです。
これらSwingの重量コンポーネントを「トップレベル・コンテナ」とも呼びます。


軽量コンポーネントになったことで、各システムで見た目が違うということや、場合によっては動作が同様ではない、といったことを避けることが出来るようになりました。
しかしSwingの場合、全てをJava側で処理するため動作速度が遅くなる場合が多いです。


Swingを用いたアプリケーションでは、javax.swing.*パッケージの他に、色や図形描画、イベント処理のために、AWTの機能(java.awt.*、java.awt.event.*パッケージ)を使うことが多いです。


Swingの特徴として、AWTの重量コンポーネント(ボタンなど)を置き換えた軽量コンポーネントが用意されています。
それらSwingコンポーネントはさらに追加の機能を持っていることが多いです。

  • 「テーブル」「ツリー」などAWTにはないコンポーネントが用意されています。これらSwingコンポーネントの中で、ユーザが操作する上で目にするコンポーネントを「ユーザインターフェイス・コンポーネント」と呼び、「JButton」のように「J」で始まる名前となっています。
  • Swingコンポーネントは主にこの「ユーザインターフェイス・コンポーネント」と「サポートクラス」で構成されています。
  • Swingではソースの修正無しに「ルック・アンド・フィール」を変更することが出来ます。
  • 「ルック・アンド・フィール」を変更すると、UNIXで動作するJavaアプリケーションをWindowsのような外観にすることも可能です。


    それでは、以下のサンプルプログラムを作成してみましょう。


    SwingDraw1.java 直

    /**
    *JPanelに楕円を表示する。SwingDraw.java
    */
    
    import java.awt.*;
    import javax.swing.*;
    
    public class SwingDraw1 extends JPanel {
    
    	private final int WIDTH = 400; //JPanelの幅と高さを定義
    	private final int HEIGHT = 200;
    	private int x=0; //楕円のx座標は0から
    
    	/**コンストラクタ*/
    	public SwingDraw1() {
    		super();    //JPanelのコンストラクタを呼び出す
    		setBackground(Color.white); //JPanelの背景色は白
    
    		//JPanelの幅と高さを設定
    		setPreferredSize(new Dimension(WIDTH, HEIGHT));
    	}
    
    	/**グラフィックス描画処理*/
    	public void paintComponent(Graphics g) {
    
    		//コンポーネント全体を白で描画
    		g.setColor(Color.white);
    		g.fillRect(0, 0, WIDTH, HEIGHT);
    
    		//200ミリ秒休止
    		try {
    			Thread.sleep(200);
    		}
    		catch(InterruptedException ex) {
    			System.err.println(ex);
    		}
    
    		//x座標を進めて楕円を描画
    		x+=10;
    		g.setColor(Color.red);
    		g.fillOval(x, 0, 30, 30);
    		g.setColor(Color.green);
    		g.fillOval(x, 50, 30, 30);
    		g.setColor(Color.blue);
    		g.fillOval(x, 100, 30, 30);
    		g.setColor(Color.pink);
    		g.fillOval(x, 150, 30, 30);
    	}
    
    	/**main()*/
    	public static void main(String[] args) {
    		SwingDraw1 sample = new SwingDraw1();
    
    		JFrame frame = new JFrame("SwingDraw1");
    
    		//「閉じる」ボタンが押された場合はフレームを閉じる
    		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
    		//コンテンツ・ペインにJPanelをadd
    		frame.getContentPane().add(sample, "Center");
    		frame.pack();
    		frame.setVisible(true);
    
    		//右端に行くまでpaintComponent()を呼び出す。
    		while(sample.x < sample.WIDTH) {
    			sample.repaint();
    		}
    	}
    }
    



    JFrameはウィンドウのクローズ・イベント処理を「setDefaultCloseOperation()」メソッドで設定できます。
    具体的には以下のように設定します。

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    



    ウィンドウが閉じられたときの動作は、以下の定数で決まります。

  • DO_NOTHING_ON_CLOSE    処理を行わない(初期設定)
  • HIDE_ON_CLOSE         ウィンドウを隠す
  • DISPOSE_ON_CLOSE      ウィンドウを隠し、使用している資源を破棄する。


    Swingの軽量コンポーネントは全て「JComponent」が基になっています。
    JComponentには以下のような特徴があります。
  • ボーダー(枠線)を持つことが可能で、複数のボーダーを組み合わせることも出来ます。
  • 組み込みで「ダブルバッファリング」機能を持っています。
  • 自動スクロール機能によって、カーソルをボーダーの外へドラッグするとコンポーネントの内容をスクロールさせることが出来ます。
  • 「ツールチップ」と呼ばれる機能があります。これはマウス・カーソルをあるウィンドウ上に置いておくと、小さなウィンドウに文字列が表示される機能です。


    JComponentはAWTのコンポーネントと同様にサイズを指定することが可能です。
    ただし、実際にはレイアウトマネージャーがサイズの最終決定を行うので、設定通りにならない場合もあります。
    サイズの設定には、最大サイズを設定する「void setMaximumSize(Dimension)」、最小サイズを設定する「void setMinimumSize(Dimension)」、推奨サイズを設定する「void setPreferredSize(Dimension)」があります。
    Demensionはサイズを規定するクラスです。
    「幅400・高さ300」のコンポーネントサイズを設定する例を挙げます。

    JPanel panel = new JPanel();
    panel.setPreferredSize(new Dimension(400, 300));
    



    SwingではCanvasは存在しませんが、Swingコンポーネントの多くはグラフィックスを扱えるので、目的に応じて使い分ければよいです。
    通常は「JPanel」を使用することが多いです。


    グラフィックスの描画自体は、JComponent.paint()メソッドによって実行されます。
    正確には、特定のコンポーネント描画だけならJComponent.paintComponent()をオーバーライドし、JComponent.paint()はコンポーネント(JComponent.paintComponent)やボーダー(JComponent.paintBorder)、あるいは子コンポーネント(JComponent.paintChirdren)を順次実行するので、必要ならメソッドをオーバーライドして、JComponent.paint()自体はオーバーライドしないようにします。


    Swingで再描画を行う場合は、repaint()メソッドを使用しますが、AWTのそれと違い、update()に処理を記述する必要はほぼありません。
    通常JComponent.update()は、paint()メソッドを呼び出す前にコンポーネントをクリアすることもありません。
    オーバーライドされていないJComponent.paintComponent()は背景をクリアします。


    repaint()は、なるべく早く書き換えを行うComponent.repaint()を使用することが多いと思います。


    では、サンプルプログラムを実行してみましょう。
    白いキャンバスに、4つの楕円図形が0.2秒ずつ描画して消えるのを繰り返し続けます。
    左から右に図形が動いていきます。
    フレームの終了ボタンで終了出来ます。








    <<前  [TOP]  次>>