AWTのシステムの仕組み
AWTのシステムの仕組みについて解説します。
そもそも AWT(Abstract Window Toolkit)とは、いったいどんな意味なのでしょうか?
これまで、awtパッケージのクラスを見てきましたが、
現実に目に見えるオブジェクトを提供しています。どこが「抽象的(abstract)」
なのでしょうか?
Javaは特定のマシンやシステムに依存しないプログラムを提供します。
UNIXのXウィンドウ、WindowsのPC、Macintoshなど複数のウィンドウシステムの上で
実行される可能性があるわけです。
AWTで提供されるクラスは、そうしたすべての環境に適応したものです。
たとえば、Javaの awtパッケージに登場する Buttonクラスのオブジェクトは、
その実行環境によって、Xウィンドウのボタンになったり、
Windowsのボタンになったりできます。
このようなことは Javaの登場以前には考えられないことでした。
Javaのawtパッケージのオブジェクトは「実体を持たず」に、
システムに応じて「その場で実体を作り出す」という性質を備えているわけです。
これが「抽象的(abstract)」と言われる理由です。
AWTはすべてのウィンドウシステムの上に共通して存在する
どんなウィンドウシステム下でも同じ機能を提供するプログラムを設計するためには、
次に述べる2つの条件を満たす必要があるでしょう。
- プログラムの記述はウィンドウシステムの違いに依存しない。
- 現実のウィンドウシステムの機能(実体)を呼び出すことができる。
ちょっと考えると互いに矛盾した要求です。
この2つの条件を同時に満たすようにするには、少し工夫が必要になります。
そのトリックを簡単に説明したのが下図です。
javaのawtパッケージで提供されるクラスと、
個々のウィンドウシステムとの間に、もう1つ、その橋渡しをするための
クラスの層を用意しています。この中間のクラスの存在がポイントです。
AWTの機能を実現する「3層構造」
3つの層のうち一番上が私たちがJavaのプログラミングの中で取り扱っている
java.awtパッケージのクラスです。これらのクラスはシステムに依存する
記述はいっさい含まれません。
たとえば java.awt.Graphics クラスを例にとって見てみましょう。
ふだんはあまり意識していませんが、
実は Graphicsクラスは abstractなクラスです。
このクラスは、システムに依存しないように、二番目の層のクラスを
覆い隠す目的を持っています。
すなわち、
実際にオブジェクトとして生成されているのは、
二番目の層に属するGraphicsのサブクラスなのです。
その名前が何になるかはシステムに依存します。
たとえば、Solarisならば sun.awt.motif.MGraphicsというクラスです。
java.awt.Graphics にはシステムの機能の呼び出しなどは記述されていません。
一方、sun.awt.motif.MGraphicsは内部で nativeメソッドと呼ばれる
マシンに依存したコードを呼び出すようになっています。
このようなクラスの継承の利用によって、
実際にはシステムの機能を呼び出しているにもかかわらず、
プログラムの記述の中にはシステムに依存する部分は見えなくなります。
コンポーネントのクラスの実現方法もやはり3層の構造を利用しています。
ただし、少しだけ複雑です。コンポーネントのクラスの直接のサブクラスが
nativeメソッドを呼び出すオブジェクトになるのではなく、
peer と呼ばれるインターフェイスを
実装したクラスをコンポーネントのクラスが内部に保持するという形式になります。
このような仕組みになっている理由は2つほどあります。
まず、peerを実装したクラスを複数用意しておけば、
それを交換することでコンポーネントのデザインを容易に変更することが
可能になります。
第2点目に、peerのインターフェイスを通じて、そのコンポーネントが実装すべき
機能を定義できるという点です。つまり peerは単に2層目のシステム依存の
クラスを覆い隠すだけでなく、コンポーネントの規格を定める役割もはたすわけです。
たとえば Buttonクラスの場合、ButtonPeerインターフェイスによって
ラベルの文字列を設定できるようにすることが要求されます。