GUI の構成ブロックであるコンポーネントを使用する |
AWT は当初から、プラットフォームに依存しない API をもつこと、なおかつそれぞ れのプラットフォームのルックアンドフィール (見た目と使い心地) を生かすことを 意図して作成された。 たとえば、AWT のボタンの API は 1 つだけ (Button クラスによって提供される) だが、ボタンの外観は Macintosh 上と Windows 95 が動作する PC 上とでは異なっている。AWT は、プラットフォームに依存しない API を提供し、かつプラットフォーム仕様の実装 (ピア) を生かすクラス (コンポーネント) を提供することにより、矛盾するように見える目的をうまく達成している。 具体的には、すべての AWT コンポーネントクラス (Component、MenuComponent、お よびこれらのサブクラス) は等価なピアクラスをもち、すべてのコンポーネントオブジェクトはオブジェクトのルックアンドフィールを制御するピアオブジェクトをもっ ている。
以下に、典型的な AWT コンポーネント (Button) がピアに割り当てられる様子を図で示す。 ボタンのピアは、java.awt.peer の ButtonPeer インタフェースを実装するプラットフォーム仕様のクラスで実装される。 java.awt Toolkit クラスは、ピア実装のために使用するクラスを細かく選定するメソッドを定義している。
ピアが作成される仕組み
ピアは、対応するコンポーネントオブジェクトが最初に描画される直前に、ゆっくり と作成される。 これには 1 つ副作用があることに注意する。それは、コンポーネントのサイズはコンポーネントの最初の表示が完了するまで無効だということである。可視でないコンテナ (ピアのないコンテナ) にコンポーネントを追加する場合、コンテナが最初に表示される直前に、コンテナのピアとコンテナが含むすべてのコンポーネントのピアが作成される。
しかし、可視の コンテナにコンポーネントを追加するのであれば、そのコンポーネントに対するピアを作成するよう AWT に明示的に指示する必要がある。この指示は、
validate()
メソッドの呼び出しを通じて行う。追加しよう としているコンポーネントに対して直接validate()
を呼び出すこと も可能だが、通常はコンテナに対して起動する。 この理由は、validate()
をコンテナに対して起動すると、そのコンテナの下にあるすべてのコンポーネントも同様に有効になるという連鎖反応が生じるからである。たとえば、Applet オブジェクトにコンポーネントを追加した後、その Applet に対してvalidate()
を呼び出すと、その Applet にあるすべてのコンポーネン トのピアが作成される。ピアがイベントを処理する仕組み
ピアはユーザ入力イベントに反応することによって、UI コンポーネントの使い心地 (そして間接的には見た目も) を実装する。 たとえば、ユーザがボタンをクリックすると、ピアはボタンの外観を変化させ、適切な Button オブジェクトにアクションイベントを転送することによって、マウスダウンとマウスアップイベントに反応する。理論上、ピアはイベントチェーンの最後にある。 生のイベント (キー押下など) が発生すると、そのイベントの宛先の Component が まずそのイベントの処理を始め、次に (Component のイベントハンドラが false を返した場合) その Component の Container がイベントを調べる、という具合に続いていく。 階層のすべての Component がイベントを処理する条件を得た (かつ、それらのイベント処理メソッドがすべて false を返した) 後で、ピアがそのイベントを調べ反応し始めるのである。
現在の実装では、上記のシナリオはキー押下に対しては当てはまるが、マウスイベントに対しては当てはまらない。 マウスイベントでは、ピアが最初にイベントを調べるようになっており、すべてのイベントを Component に渡すとはかぎらない。 将来のリリースでは、マウスイベントもキーボードイベントと同様に動作させる予定である。
キー押下やマウスクリックのような生のイベントをもとに、ピアは、アクション、フォーカス変更、ウィンドウアイコン化といった、さらに高いレベルのイベントを生成することがある。 このような高いレベルのイベントは関連する Component に渡され、そこで処理される。
GUI の構成ブロックであるコンポーネントを使用する |