フレームに含まれるペインとコンポーネントの追加

広告

フレームを作成したらラベルやボタンなどコンポーネントを追加していきます。各コンポーネントの詳細はそれぞれのページで詳しく見ていきますが、ここではJFrameクラスで作成したオブジェクトにどのようにコンポーネントを追加していくのかを確認しておきます。

JFrameクラスから作成したフレームは1枚の板のように見えますが実際には別々の機能を持ったペインと呼ばれる層が重なっている構造となっています。ペイン(PANE)とは窓枠や窓ガラスと意味の言葉です。

p6-1

※上記の図はSunのサイトの中の「How to Use Root Panes」から引用させて頂いています。

それぞれの層には別々の使用目的がありますが、ボタンなどのコンポーネントはContentPaneに追加していくことになります。

ContentPaneの取得

そこでJFrameクラスのオブジェクトからContentPaneを取り出し、取り出したペインに対してコンポーネントを追加します。ContentPaneを取得するにはJFrameクラスで定義されているgetContentPaneメソッドを使います。

このフレームの contentPane オブジェクトを返します。  

戻り値:
  contentPane プロパティー

getContentPaneメソッドを実行すると、フレームのContentPaneを表すContainerクラス(java.awt.Container)のオブジェクトを取得します。

実際には次のように記述します。

import javax.swing.JFrame;
import java.awt.Container;

class Sample extends JFrame{
  public static void main(String args[]){
    /* ... */
  }

  Sample(String title){
    /* ... */

    Container contentPane = getContentPane();
  }
}

コンポーネントの追加

フレームからContentPaneを取得したら、追加したいコンポーネントをContentPaneに追加していきます。コンポーネントを追加するにはContainerクラスで定義されているaddメソッドを使います。

コンポーネントを追加する場合、追加する対象に設定されているレイアウトマネージャーによってはどこに追加するのかの情報を合わせて指定する必要がある場合があります。フレームのデフォルトレイアウトマネージャーであるBorderLayoutではコンポーネントを追加する位置を合わせて指定する必要があり、その場合は次のメソッドを使います。

指定されたコンポーネントをこのコンテナの最後に追加します。また、指定された制約オブジェクト
を使用して、このコンテナの配置にコンポーネントを追加することをレイアウトマネージャーに通知
します。これは addImpl(java.awt.Component, java.lang.Object, int) の簡易メソッドです。

注:コンポーネントを、表示されているコンテナに追加した場合、そのコンテナに対して validate を
呼び出し、新しいコンポーネントを表示する必要があります。複数のコンポーネントを追加する場合
は、すべてのコンポーネントを追加したあとで、validate を 1 回だけ呼び出すことによって、効率
を向上できます。 

パラメータ:
  comp - 追加されるコンポーネント
  constraints - このコンポーネントの配置条件を表現するオブジェクト 
例外:
  NullPointerException - comp が null の場合

1番目の引数に追加するコンポーネントのオブジェクト、2番目の引数に追加する位置を指定します。ここでは詳細は省略しますが、レイアウトマネージャーとしてBorderLayoutを使用している場合は次のいずれかを指定します。

BorderLayout.NORTH
BorderLayout.SOUTH
BorderLayout.EAST
BorderLayout.WEST
BorderLayout.CENTER

なおフレームに対してコンポーネントを追加する場合は必ずこのようにするわけではありません。フレームに別のレイアウトマネージャーを設定した場合にはまた別の指定方法となります。

実際には次のように記述します。

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Container;
import java.awt.BorderLayout;

class Sample extends JFrame{
  public static void main(String args[]){
    /* ... */
  }

  Sample(String title){
    /* ... */

    JButton btn = new JButton("ボタン");

    Container contentPane = getContentPane();
    contentPane.add(btn, BorderLayout.CENTER);
  }
}

なお、レイアウトマネージャーとしてBorderLayoutが設定されているコンテナに対して、単にadd(コンポーネント)と記述した場合はBorderLayout.CENNTERが省略されたものとして扱われます。

サンプル

では実際に試してみます。

SSample6_1.java

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Container;
import java.awt.BorderLayout;

class SSample6_1 extends JFrame{
  public static void main(String args[]){
    SSample6_1 frame = new SSample6_1("タイトル");
    frame.setVisible(true);
  }

  SSample6_1(String title){
    setTitle(title);
    setBounds(100, 100, 300, 250);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton btn = new JButton("ボタン");

    Container contentPane = getContentPane();
    contentPane.add(btn, BorderLayout.NORTH);
  }
}

ではコンパイルを行った上で実行してみます。

p6-2

ボタンを一つ作成してフレームに追加しました。

ContentPaneの省略

現在のバージョンではフレームからContentPaneを取得した上でContentPaneに対してコンポーネントを追加しなくても、単にフレームに対してコンポーネントを追加するだけで自動的にContentPaneに追加されるようになりました。

今までの記述方法:

JFrame frame = new JFrame();
JButton btn = new JButton("");

Container contentPane = frame.getContentPane();
contentPane.add(btn, BorderLayout.CENTER);

省略された記述方法:

JFrame frame = new JFrame();
JButton btn = new JButton("");

frame.add(btn, BorderLayout.CENTER);

あくまで自動的にContentPaneに追加してくれるようになっただけなので、考え方自身は今までと変わっていません。古い環境で省略した形で実行するとエラーとなるため、当面は以前のままの記述方法を使って行きます。

簡単なサンプルで試してみます。

SSample6_2.java

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;

class SSample6_2 extends JFrame{
  public static void main(String args[]){
    SSample6_2 frame = new SSample6_2("タイトル");
    frame.setVisible(true);
  }

  SSample6_2(String title){
    setTitle(title);
    setBounds(100, 100, 300, 250);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton btn = new JButton("ボタン");

    add(btn, BorderLayout.NORTH);
  }
}

ではコンパイルを行った上で実行してみます。

p6-3

実行結果は一つ前のサンプルと同じです。

( Written by Tatsuo Ikura )