ヘビー・ウェイト Java コンポーネントとライト・ウェイト Java コンポーネントの混合に関するヒント

Comments

問題

わたしは、Frame ウィンドウに組み込まれた Panel コンテナーに JComboBox を表示させています。入力フィールド内で選択を変更するために、下矢印を選択してポップアップ・ウィンドウを表示させると、ポップアップ・ウィンドウが一部欠落しているように見えます。事実、さらにもう少し詳しく調べてみると、選択肢をリストしているポップアップが Frame コンポーネントの後ろに隠れて表示されます。これは、z オーダーの問題ですか?

解答

z オーダーとは、各オブジェクトがコンテナーの中で互いにどのような階層になっているかを示すものです。あるオブジェクトが同一コンテナー内の別の制御機構の一部をオーバーレーしている場合は、そのオブジェクトは異なる層に入っています。これらの層が x、y、および z と呼ばれることから、z オーダー という名前が付けられています。z オーダーは、意図的に設定することができます。しかし、そうしても以下のような問題は解決しないことが分かりました。そこでわたしは、もう少し深く掘り下げてみなければなりませんでした。

Java API が初めて導入されたとき、AWT クラスはほとんどヘビー・ウェイト・オブジェクトからなっていました。(これの 1 つの例外はコンポーネント・クラスでした。)これらのオブジェクトはヘビーです。なぜならば、これらを画面に表示するためには、ピアと呼ばれるオブジェクト (つまり、プラットフォーム依存のオブジェクト) の同時作成が必要になるからです。ピア (ネイティブ・ウィンドウとも呼ばれます) は、実行するプラットフォームに応じて変わります。一方、AWT を拡張するほとんどの Swing クラスはピア・オブジェクトを使用しないため、オリジナルの AWT クラスのように荷物を運ぶことがありません。ライト・ウェイト という名前は、ここからきています。ライト・ウェイト・コンポーネントは、隠されたネイティブ・ウィンドウとは関連がありません。したがって、ユーザー・プログラムをどこで実行しても、同じルック・アンド・フィールが得られますし、最も重要なことは、ネイティブ・コードが関連していないことです。言い換えれば、Swing ボタン以外のボタンを使用した場合は、オペレーティング・システム (OS) に基づいたルックを持つボタンが得られます。これに対し、Swing ボタンを使用した場合は、OS と独立したボタンのように見えるオブジェクトの描画が得られます。また、これも重要なことですが、一部のクラスがネイティブ OS コードを使用したとしても、これによってアプリケーションの可搬性が損なわれることはありません。ネイティブ・コードは、アプリケーションの中ではなく、Java ランタイム環境の中に作成されます。

わたしが先ほど、AWT を拡張するほとんどの Swing クラスがピアを使用しないと言ったことに気付かれたかもしれません。JFrame はこのモデルに従っていません。JFrame は Frame クラスを拡張しますが、これはヘビー・ウェイト・オブジェクトです。したがって、JFrame もヘビー・ウェイト・オブジェクトです。ヘビー・ウェイトの Swing クラスとしては、ほかにも JWindow、JDialog、JApplet などがあります。

Swing コンポーネントは、すべて AWT コンポーネントから派生したものです。たとえば、階層ツリーを上へたどれば、JLabel が JComponent から派生し、JComponent が AWT コンポーネントから派生していることが分かります。AWT コンポーネントはライト・ウェイト・オブジェクトです。したがって、JLabel はライト・ウェイトです。ラベルも Component クラスをサブクラス化します。これもライト・ウェイトと見なされます。

上記の問題は、ヘビー・ウェイト Frame オブジェクトに組み込まれている Panel と関連しています。JCombobox の中のポップアップはライト・ウェイトです。したがって、frame コンポーネントは JCombobox のポップアップの通り道をふさぐため、それをバックグラウンドに隠しています。Frame コンポーネントで作成されたネイティブ・ピア・ウィンドウは隠されているため、透過エリアのインプリメントには使用できません。

解決

何が問題であるかが分かりましたから、次は、それをどう処理するかです。JDK 1.1 は、ライト・ウェイト UI フレームワークをインプリメントしました。Swing クラスはライト・ウェイト UI フレームワークを使用して、ユーザーが、隠されたネイティブ・ウィンドウを持たない AWT Component および Container クラスを拡張できるようにします。サブクラス化する元のクラスを変更することにより、現在ヘビー・ウェイト・オブジェクトをサブクラス化するクラスをこのモデルに適応することができます。

ボトム・ラインは、ヘビー・ウェイト・オブジェクトとライト・ウェイト・オブジェクトを混合してはならないことを示します。いずれかのパスをたどれば、アプリケーションは、各プラットフォームにわたって統一のとれた、整合性のあるビューを持っています。すべてのライト・ウェイト・オブジェクトを使用する場合の利点としては、透過エリアがサポートされること、追加ピア・クラスが不要になること (これにより、パフォーマンスが向上します)、100% Java コードを使用できることなどがあります。


ダウンロード可能なリソース


関連トピック

  • 拡張アプリケーションの作成 (Writing Advanced Applications)に示されているライト・ウェイト・コンポーネントや他の Project Swing フィーチャーを使用する Project Swing アプリケーション・コードについて勉強してください。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=218891
ArticleTitle=ヘビー・ウェイト Java コンポーネントとライト・ウェイト Java コンポーネントの混合に関するヒント
publish-date=04012000