コンテントペインとは?
実際にサンプルを動かしながらこの記事を読んでいる人の中には、先ほどのサンプルがうまく動かない!」という人もいるかも知れません。実は、先ほどのサンプルは、Java 5以降での書き方なのです。本来の書き方は、もう少し違ったものになります。では、先ほどのリストから、コンストラクタの部分だけを抜粋して書き直してみましょう。
public SampleApp(){
this.setSize(new Dimension(300,150));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = this.getContentPane(); // ★
label = new JLabel("This is Sample.");
label.setFont(new Font("Serif",Font.BOLD,24));
contentPane.add(label,BorderLayout.NORTH);
field = new JTextField();
contentPane.add(field,BorderLayout.CENTER);
button = new JButton("click");
contentPane.add(button,BorderLayout.SOUTH);
}
これが、Swing本来の書き方です。★の部分で「getContentPane」というメソッドを呼び出し、Containerインスタンスを取り出していますね。そして、作成したコンポーネント類は、このContainerにaddしています。JFrameには直接addされていません。一体、これはどういうことなのでしょう?
このgetContentPaneで得られるContainerは、「コンテントペイン」と呼ばれるものです。Swingのウインドウ関係クラスでは、ウインドウの上に透明のレイヤーがいくつか重なった構造をしています。コンポーネントを配置するレイヤー、メニュー関係がおかれるレイヤー、マウスポインタなどが表示されるレイヤーというように、用途に応じていくつもの透明レイヤーを重ね合わせた形をしているのです。
それぞれのレイヤーは、コンテナであるContainerクラスのインスタンスとして実装されています。そして、このContainerに、必要に応じてさまざまなオブジェクトを組み込んで表示を構成していくわけです。
ウインドウにコンポーネントを配置する場合には、コンポーネント類が置かれるレイヤーである「コンテントペイン」に配置します。ウインドウ本体に直接組み込んではいけないのです。そこで、上に上げたりストのようにgetContentPaneでコンテントペインのインスタンスを取得し、これに対してaddしていたのですね。
「では、Java 5以降は、なぜ直接addできるの? コンテントペインがなくなったの?」――いえいえ、そうではありません。Java 5以降も、コンテントペインの構造はそのままです。違うのは「組み込み方法が増えた」という点です。
コンテントペインへの組み込みは、原理としてはわかりますが、AWTより面倒なことには変わりありません。そこで、Java 5からは「JFrameに直接addすると、自動的にコンテントペインに組み込まれるようにしよう!」と機能修正されたのです。このため、JFrameにそのままaddして組み込んでいたのですね。
とはいえ、これはあくまで「そうやってもコンテントペインに組み込める」ということであって、「コンポーネントはすべてコンテントペインに組み込まれる」という構造は変わりありません。この点はしっかりと理解してください。