SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

作って覚えるJavaプログラミングのススメ

Java入門 (4) - Swingを使ったGUIプログラミング

作って覚えるJavaプログラミングのススメ 第4回


JFrameを継承してクラスを作る

 さて、作成したソースコードにもう一度目を向けてみましょう。ここでは、JFrameインスタンスを作り、このメソッドを呼び出して必要な処理を行っていました。実は、実際にSwingを利用する場合、このような書き方をすることはあまりないのです。

 これは、「既にあるJFrameというクラス」をそのまま利用するやり方です。しかし、実際にウインドウを使ったプログラムを作成する場合、「既に用意されている標準的なウインドウ」だけを使って何かをすることはあまりありません。JFrameにはウインドウを扱うための標準的な機能は一通り揃っていますが、逆にいえば「標準的なものしかない」とも言えます。

 実際にプログラムを作成する場合、標準的なウインドウに独自の機能を付け加えたり、既にある機能を修正したりしてオリジナルなウインドウを作成することになります。となると、「既にあるJFrameのインスタンスを作って操作する」というやり方ではいずれ限界が見えてしまいます。それよりも、JFrameを継承してオリジナルなウインドウ・クラスを作成し、利用した方が良いでしょう。

 継承については前回の記事を参考にして欲しいのですが、既にあるクラスの機能をすべて受け継いで新しいクラスを定義するという仕組みになります。これは、Java本体に用意されているライブラリのクラスに対しても使うことができます。では、JFrameを継承する形に書き直してみましょう。

package codezine.java;

import javax.swing.*;

public class Sample extends JFrame {
    
    public Sample(){
        this.setSize(300,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.setVisible(true);
    }

}

 今回は、Sampleクラスを「extends JFrame」して作成しています。そして、サイズの変更とクローズボックスの動作設定はSampleのコンストラクタに用意し、newしたら自動的に行われるようにしました。

 コンストラクタでは、setSizeやsetDefaultCloseOperationを利用するのに「this」というものが使われています。これは、「インスタンス自身」を示すキーワードです。Javaでは、クラスはインスタンスを作成して操作をするわけですが、その「現在、操作をしているこのインスタンス自身」を示すのに使われるのがthisなのです。

 例えば、this.setSizeは「現在操作しているこのインスタンス自身のsetSizeを呼び出す」ということになります。こうして、thisを使ってインスタンス自身を操作することで、そのインスタンスを操作できるのです。

JLabelでテキストを表示しよう

 では、ウインドウが表示できるようになったところで、続いて「コンポーネント」を利用してみることにしましょう。コンポーネントというのは、GUIで使われる「部品」のクラスのことです。ボタンやテキストラベルやメニューなどのことです。

 ここでは、最も簡単なコンポーネントとして「JLabel」というクラスを使ってみます。JLabelはjavax.swingパッケージにあるクラスで、テキストを表示するためのものです。

package codezine.java;

import java.awt.*;
import javax.swing.*;

public class Sample extends JFrame {
    
    public Sample(){
        this.setSize(300,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        String msg = "<html><h2>Swing Sample</h2>";
        msg += "<p>これはSwingのウインドウです。</p></html>";
        
        JLabel label = new JLabel(msg);
        this.add(label,BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.setVisible(true);
    }

}
JLabelを組み込むと、JFrameのウインドウにテキストを表示できる。
JLabelを組み込むと、JFrameのウインドウにテキストを表示できる。

 これを実行すると、ウインドウ内に「Swing Sample」「これはSwingのウインドウです。」といったテキストが表示されます。この表示されたテキストがJLabelなのです。

JLabel組み込みの手順

 JLabelは、設定されたテキストをウインドウ内に表示するコンポーネントです。このJLabelは次のような形で作成をします。

JLabel 変数 = new JLabel( [String] );

 これで、引数に指定したテキストを表示するJLabelが作成されます。このJLabelは、現時点ではJFrameのように大きさなどを設定する必要はありません。後述するレイアウトマネージャというものによって、自動的に最適なサイズに調整されます。

 ところで、よく見ると表示するテキストにちょっと変わったものが用意されています。変数msgの中には、"<html><h2>Swing Sample</h2><p>これはSwingのウインドウです。</p></html>"というように、HTMLを使って記述されたテキストが収められているのです。

 JLabelでは、普通にテキストを設定すればそれがそのまま表示されますが、このようにHTMLのソースコードを設定すると、それをレンダリングして表示するようになっています。ですから、ちょっとテキストの大きさやスタイルなどを変更したい場合は、HTMLを書いて表示させればいいわけです。これは覚えておくと結構役立つテクニックでしょう。

 さて、作成したJLabelは、そのままでは画面には表示されません。ウインドウ(JFrame)の中に組み込んで、初めてそこに表示されるようになります。この組み込みを行っているのが、JFrameのaddというメソッドです。

this.add(label,BorderLayout.CENTER);

 このaddでは、第1引数に組み込むJLabelインスタンスを設定しています。第2引数には「組み込む場所」を示す値が指定されています。

 JFrameなどでは、組み込んだコンポーネントを、必要に応じて自動的にレイアウトする機能が用意されています。「レイアウトマネージャ」と呼ばれるもので、これによりウインドウの大きさなどが変更されたとしても、コンポーネントの位置や大きさが自動的に変更され、常に最適な状態でコンポーネントが配置されるようになっています。

 このレイアウトマネージャにはいくつかの種類があります。JFrameに標準で用意されているのは「ボーダーレイアウト(BorderLayout)」と呼ばれるものです。これは、ウインドウの内部を「上」「下」「左」「右」「中央」の5つの領域に分け、それぞれにコンポーネントを組み込むというものです。組み込む場所は、java.awt.BorderLayoutクラスに用意されているクラスフィールドで指定をします。

 ここでは、BorderLayout.CENTERという値が指定されていますが、これは「中央」を示す値です。この他に「NORTH」「SOUTH」「EAST」「WEST」といった値が用意されており、これらで「上」「下」「右」「左」の位置を指定できます。上下左右だけではなく東西南北で指定できるというのも、ちょっと面白いですね。

BorderLayoutは、CENTER、NORTH、SOUTH、EAST、WESTのそれぞれの場所にコンポーネントを組み込める。
BorderLayoutは、CENTER、NORTH、SOUTH、EAST、WESTのそれぞれの場所にコンポーネントを組み込める。

自由にレイアウトをするには?

 このように、Swingでは簡単にコンポーネントを組み込んで表示できます。位置や大きさも考える必要はありません。ですが、逆にいえば「自由なレイアウトができない」ということにもなります。1つ1つの位置や大きさをプログラマが指定してコンポーネントを配置させることはできないのでしょうか。

 先に触れたように、ウインドウ内のコンポーネントの位置や大きさは、そのウインドウに設定されている「レイアウトマネージャ」によって行われています。レイアウトマネージャについてはいずれ改めて触れる予定ですが、これは「コンポーネントを、決まったルールに従って自動的にレイアウトするためのもの」と考えてください。ウインドウや、コンポーネントを組み込める部品類には、必ずこのレイアウトマネージャが設定されています。そして、これによって自動的にコンポーネントの配置が調整される仕組みになっているのです。

 このレイアウトマネージャというのは、なかなかに奥深い機能を持ったものなのですが、とりあえず「もっと自由にレイアウトしたい!」という人のために、レイアウトマネージャを取り外して、手作業でレイアウトをするやり方を紹介しておきましょう。

package codezine.java;

import java.awt.*;
import javax.swing.*;

public class Sample extends JFrame {
    
    public Sample(){
        this.setSize(300,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(null);
        
        String msg = "<html><h2>Swing Sample</h2>";
        for(int i = 0;i < 5;i++){
            JLabel label = new JLabel(msg);
            label.setSize(200,50);
            label.setLocation(i * 20,i * 20);
            this.add(label);
        }
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.setVisible(true);
    }

}
繰り返しを使い、setLayout(null)したJFrameにコンポーネントを斜めに配置してみる。
繰り返しを使い、setLayout(null)したJFrameにコンポーネントを斜めに配置してみる。

 ここでは、JFrameのレイアウトマネージャをOFFにし、繰り返しを使ってJLabelを少しずつ位置を移動しながら組み込んでいます。1つ1つのコンポーネントの位置や大きさをすべて設定しなければいけないため少々コードは長くなりましたが、手順さえ分かればそれほど難しいことではありません。

 まず、コンポーネントの組み込みを行う前に、JFrameのレイアウトマネージャをOFFにしておきます。これは、JFrameにレイアウトマネージャを設定するためのsetLayoutというものを利用します。これは通常、レイアウトマネージャのクラスのインスタンスを引数に指定することで、使用するレイアウトマネージャを変更できますが、これを「null」にすると、レイアウトマネージャを空っぽの状態(つまり何も設定されていない状態)にできます。このnullというのは、「何もない状態」を示すJavaのキーワードです。

 レイアウトマネージャがなくなった以上、組み込むコンポーネントの大きさや配置場所は、プログラマが1つ1つ指定しなければいけません。それを行っているのが以下のところです。

label.setSize(200,50);
label.setLocation(i * 20,i * 20);

 コンポーネントの大きさはsetSizeで行います。横幅と縦幅をそれぞれint値で指定します。また位置についてはsetLocationというメソッドで設定できます。これは、そのコンポーネントが組み込まれる部品(JFrameのこと。こうしたコンポーネントを組み込める部品のことを「コンテナ」と呼びます)の右端および上端からそれぞれ何ドット離れた場所にあるかをint値で指定します。

 これでコンポーネントの設定は終わりですが、この他に組み込みを行うaddメソッドを修正しています。先のサンプルでは組み込むコンポーネントの他、組み込む場所を示す値を引数に渡していましたが、ここでは単にJLabelインスタンスだけが引数に指定されています。レイアウトマネージャがないので、配置場所を指定する値は不要になったのです。

次のページ
主なコンポーネントを利用してみる

この記事は参考になりましたか?

作って覚えるJavaプログラミングのススメ連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2135 2008/03/10 17:40

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー