このセクションでは、重量/軽量(HW/LW)混在機能で発生する可能性のある問題について説明します。特に、次の問題について説明します。
コンポーネント階層の有効化:
コンポーネントのレイアウト関係のプロパティ(サイズ、位置、フォントなど)を1つでも変更すると、コンポーネントとその祖先が無効にされます。HW/LW混在機能が正しく機能するには、そのような変更を行なったあとでコンポーネント階層を有効にする必要があります。無効化はデフォルトで、階層内の最上位コンテナ(Frame
オブジェクトなど)で停止します。したがって、階層の有効性を復元するには、アプリケーションからFrame.validate()
メソッドを呼び出すようにしてください。例:
component.setFont(myFont); frame.validate();
ここで、frame
はcomponent
を含んでいるフレームのことです。注意: SwingアプリケーションやSwingライブラリでは、多くの場合、次のパターンが使用されます。
component.setFont(myFont); component.revalidate();
このrevalidate()
呼出しは十分ではありません。この呼出しではコンポーネントのもっとも近い有効なルートから始まる階層のみを有効化するため、それより上位のコンテナが無効のままになっているからです。その場合、HW/LW機能はHWコンポーネントの正しい形状を計算できず、視覚的なアーティファクトが画面に表示される可能性があります。
コンポーネント階層全体の有効性を検証するには、「AWTのデバッグに関するヒント」で説明した[Ctrl]+[Shift]+[F1]というキーの組合せを使用できます。コンポーネントに「invalid」というマークが付いている場合、validate()
呼出しがどこかで欠落していることを示している可能性があります。
有効なルート:
コンポーネント階層の有効化のプロセスにかなりの時間を要することがあるため、プロセスの処理速度を上げるために、「コンポーネント階層の有効化」で説明した有効なルートという概念がSwingに取り入れられています。そのような最適化では階層の上位部分が無効のままになりますが、有効なルートの内側にあるコンポーネントのレイアウトはコンポーネント階層の外側(つまり、有効なルートの兄弟)のレイアウトに影響を与えないため、問題は起きませんでした。ただし、1つの階層内にHWコンポーネントとLWコンポーネントが混在している場合、この記述は当てはまらなくなります。そのため、この機能ではコンポーネント階層全体が有効になる必要があります。
frame.validate()
の呼び出しも効率的ではない可能性があるため、AWTでは、コンポーネント階層の無効化/有効化を処理するための最適化された代替手段がサポートされています。この機能を有効にするには、システム・プロパティを使用します。
-Djava.awt.smartInvalidate=true
このプロパティが指定されると、invalidate()
メソッドは、invalidate()
メソッドが呼び出されたコンポーネントのもっとも近い有効なルートに達した時点で、階層の無効化を停止するようになります。その後、コンポーネント階層の有効性を復元するには、アプリケーションから次を呼び出すだけです。
component.revalidate();
注意: この場合は、frame
が引き続き有効であるため、frame.validate()
の呼出しは事実上操作なし(何も行わない文)になります。一部のアプリケーションは、階層の有効なルート(フレームなど)より上位にあるコンポーネントで直接validate()
を呼び出すことに依存しているため、この新しい最適化された動作によって非互換性の問題が発生する可能性があり、したがってこの動作を使用できるのはシステム・プロパティを指定した場合のみです。
この最適化された新しいモードでアプリケーションを実行する際になんらかの問題が発生する場合は、「AWTのデバッグに関するヒント」で説明した[Ctrl]+[Shift]+[F1]というキーの組合せを使用することで、コンポーネント階層のどの部分が無効なままになっており、したがって問題の原因となっている可能性があるのかを調査できます。
Swingのペイントの最適化:
デフォルトでは、Swingライブラリはコンポーネント階層内にHWコンポーネントが1つも存在しないものと想定しているため、最適化された描画テクニックを使ってSwing GUIのパフォーマンスを向上させます。コンポーネント階層にHWコンポーネントが含まれている場合は、最適化をオフにする必要があります。これにはまずSwingのJScrollPane
が該当します。スクロール・モードを変更するには、JViewPort.setScrollMode(int)
メソッドを使用します。
不透明でないLWコンポーネント:
HW/LW混在機能の実装ではデフォルトで、不透明でないLWコンポーネントはサポートされません。矩形以外のLWコンポーネントをHWコンポーネントと混在できるようにするには、アプリケーションで非公開APIのcom.sun.awt.AWTUtilities.setComponentMixingCutoutShape()
を使用する必要があります。
注意: 矩形でないLWコンポーネントは、引き続き不透明(アルファ= 1.0)または透明(アルファ= 0.0)のいずれかのカラーを使用して自身をペイントするようにしてください。半透明カラー(0.0 < アルファ< 1.0)の使用はサポートされません。
デフォルトのHW/LW混在機能の無効化:
一部の開発者は以前、HWコンポーネントとLWコンポーネントを混在させる必要がある場合に備えて、独自のサポートを実装しました。JDK 6およびJDK 7以降で使用可能な機能の組込み実装が、カスタムの回避方法との間で問題を発生させる可能性があります。この組込み機能を無効にするには、アプリケーションの起動時に次のシステム・プロパティを指定する必要があります。
-Dsun.awt.disableMixing=true