このドキュメントは、最初に「The Swing Connection」で公開された記事に基づいています。
多重Look & Feelを使用すると、通常のLook & Feel (デフォルト Look & Feel)を1つ以上の補助 Look & Feelで補足できます。たとえば、2つの補助のLook & Feel (1つは音声読上げ用、もう1つは点字用)をデフォルトLook & Feelに追加することにより、Swingベース・アプリケーションが生成する通常の表示出力に加えて、同時に音声読上げ出力や点字出力を提供できます。デフォルトLook & Feelは任意の通常のLook & Feel (JavaやWindowsのLook & Feelなど)にすることができ、補助のLook & Feelと連携するための変更は不要です。
このドキュメントには次のセクションがあります。
このドキュメントを読み進める前に、プラグイン可能なLook & Feelの概念に習熟しておくようにしてください。基本的な情報については、「The Java Tutorial」のセクション「How to Set the Look and Feel」を参照してください。アーキテクチャの詳細については、「Swing Connection」記事内のセクション「Pluggable look-and-feel architecture」を参照してください。
javax.swing.plaf.multi
パッケージ内のクラスは多重Look & Feelを実装します。多重Look & Feelは、UIオブジェクトを要求(getUI
メソッドを使用)するコンポーネントに応答して、複数の異なるLook & FeelからUIオブジェクトを透過的に作成し、同時にサポートします。
多重Look & Feelを使用しない場合、特定のLook & Feelを拡張する開発者はLook & Feelをサポートするクラスの継承が必要になります。たとえば、多重Look & Feelを使用しないで音声読上げサポートをJava Look & Feelに追加する場合、開発者はJava Look & Feelのクラスを継承したクラスのグループを作成して、音声読上げのサポートをこの新しいクラスに追加する必要があります。また、開発者が音声読上げのサポートをその他のLook & Feel (MotifやWindowsなど)にも追加する場合、これらのクラスのサブクラスも作成する必要があります。
この方法には次のように少なくとも2つの短所があります。
多重Look & Feelでは、複数のLook & Feelを組み合わせることができるため、これらの2つの問題が同時に解決されます。最初の問題(同じコードの別のコピーを使用する必要がある)は、開発者が特別なLook & Feelを作成してその他のLook & Feelと組み合わせることができるため、解決されます。
2番目の問題(特定のLook & Feelの使用を強制する必要がある)は、すでにロック済みの可能性があるデフォルトLook & Feelが何であれ、特別なLook & Feelを一緒に使用できるため、解決されます。
デフォルトの多重Look & Feelの実装は、javax.swing.plaf.multi
パッケージ内のMultiLookAndFeel
クラスで表され、(そのままの)多重Look & Feelという名前です。
補助的なLook & FeelをSwingとともに使用するのは容易です。Swingに多重Look & Feelを使用するように指示するには、すべてのアプリケーションで$JDKHOME/lib/swing.properties
ファイルを変更して、swing.auxiliarylaf
プロパティの定義を含める必要があります。Swingはswing.auxiliarylaf
プロパティをLookAndFeel
サブクラスのカンマ区切りのリストとみなしますが、これらのサブクラスは、デフォルトLook & Feelのほかに使用すべき補助的なLook & Feelを指定します。有効なLookAndFeel
サブクラスがswing.auxiliarylaf
プロパティに少なくとも1つ指定されていると、Swingは自動的にその多重Look & Feelを使用し、デフォルトおよび補助的なLook & Feelのロードとサポートを行います。
たとえば、アプリケーションが音声読上げフィード・バックをサポートするLook & Feelを使用し、香りを発するデバイスのサポートを追加するLook & Feelも使用するとします。音声読み上げLook & Feelの名前はcom.myco.TextTalkerLookAndFeel
であり、香りのサポートを追加するLook & Feelの名前はcom.smellco.OlfactoryLookAndFeel
とします。
Swingに、これら2つのLook & Feelを使用し、同時にデフォルトLook & Feelも使用するように指示するには、アプリケーションで単に次の行を$JDKHOME/lib/swing.properties
ファイルに追加するだけです。
swing.auxiliarylaf=com.myco.TextTalkerLookAndFeel,
com.smellco.OlfactoryLookAndFeel
この文は、コンポーネントのUIをデフォルトLook & Feelから直接取得する代わりに、多重Look & Feelから自動的に取得するようにSwingに指示します。結果として得られる多重UIは、デフォルトおよび補助的なLook & FeelからUIを取得して維持する小さな委譲先です。この結果、多重UIオブジェクトのメソッドが呼び出されると、多重UIは、デフォルトおよび補助的なLook & Feelから取得した各UIの同じメソッドを呼び出します。
補助的なLook & Feelは、デフォルトLook & Feelが提供する必要がある完全なサポートを提供する必要がない点を除いて、その他のLook & Feelと同様です。たとえば、音声読上げフィード・バックのみをサポートする補助的なLook & Feelは、ペイント用のコードを提供する必要はありません。また、すべてのコンポーネントをサポートする必要がない場合があります。たとえば、JSeparator
は無視されることがあります。
補助的なLook & Feelは単純な傾向があるため、視覚的なLook & Feelよりも開発が容易な可能性があります。開発者は特別な機能を用意することのみに集中できます。
補助的なLook & Feelの主な目的はデフォルトLook & Feelを拡張することにあるため、補助的なLook & Feelは非視覚的になる傾向があります。ただし、補助的なLook & Feelも純粋なLook & Feelであるため、画面に情報をレンダリングしても構いません。
ほかのLook & Feelの場合と同様、補助的なLook & Feelを実装するには、javax.swing.LookAndFeel
のサブクラスを記述し、javax.swing.plaf
パッケージに定義されているFooUI
クラスのサブクラスを作成します。
次の段落では、補助的なLook & Feelの開発における一般的な推奨事項についていくつか説明します。
すべての初期化を実行する場合はinstallUI
メソッドを使用し、すべてのクリーンアップを実行する場合はuninstallUI
メソッドを使用します。
コンポーネントのLook & Feelが設定されると、installUI
およびuninstallUI
メソッドが呼び出されます。installUI
メソッドにより、新しいUIオブジェクトはコンポーネントおよびそのデータ・モデルにリスナーを追加できます。同様に、uninstallUI
メソッドにより、そのUIオブジェクトはリスナーを削除できます。
視覚的なLook & Feelを継承しないでください。
補助的なLook & FeelのUIクラスを視覚的なLook & FeelのUIクラスのサブクラスとして実装しないことをお薦めします。 理由は次のとおりです。リスナーをコンポーネント・オブジェクトにインストールしたりコンポーネントを画面にレンダリングしたりするコードを誤って継承する場合があるためです。 その結果、補助的なLook & FeelはデフォルトLook & Feelと協調するのではなく、競合する可能性があります。
代わりに、補助的なLook & FeelのUIクラスがjavax.swing.plaf
パッケージの抽象UIクラスを直接継承することをお薦めします。 この方法を使用すると、補助的なLook & FeelがデフォルトLook & Feelと競合することを避けることができます。
UIクラスが継承するUI固有のすべてのメソッドをオーバーライドします。
補助的なLook & Feelの各UIクラスは派生元のjavax.swing.plaf
UIクラスに定義されているメソッドをオーバーライドすることをお薦めします。この推奨事項の理由は、視覚的なLook & Feelを継承しない理由と同様です。たとえば、すべてのUIクラスの派生元のComponentUI
クラスはupdate
メソッドのデフォルト実装を提供します。このデフォルト実装では、コンポーネントが不透明の場合に画面にペイントします。非視覚的で補助的なLook & FeelのUIクラスがこのメソッドをオーバーライドしないと、すべてが不透明なコンポーネントが空白領域として画面に表示されてしまいます。
多くの場合、補助的なLook & Feelが「不完全」になる場合があります。 つまり、コンポーネントの完全なセットをサポートする必要がない場合があります。たとえば、補助的なLook & FeelはButtonUI
サブクラスを提供して、LabelUI
サブクラスを提供しない場合があります。こうした選択は可能であり、多重Look & Feelはこのような状況を適切に処理します。
ただしデフォルトでは、Swingは、Look & FeelにUIオブジェクトを要求してLook & FeelがそのUIをサポートしない場合、エラー・メッセージを発行します。特に、補助的なLook & Feelの開発者が特定のコンポーネントをサポートする予定がない場合、このメッセージは迷惑な場合があります。
幸い、UIDefaults
クラスのサブクラスを作成し、そのインスタンスをLookAndFeel
クラスのgetDefaults
メソッドから返すことにより、このエラー・メッセージを回避できます。たとえば、
public class MyAuxLookAndFeel extends LookAndFeel {
...
public UIDefaults getDefaults() {
UIDefaults table =
new MyAuxUIDefaults();
Object[] uiDefaults = {
"ButtonUI", "MyAuxButtonUI",
...
}
table.putDefaults(uiDefaults);
return table;
}
}
class MyAuxUIDefaults extends UIDefaults {
protected void getUIError(String msg) {
//System.err.println
// ("An annoying message!");
}
}
前述の例では、MyAux
という補助的なLook & FeelはgetUIError
メソッドをオーバーライドするUIDefaults
サブクラスを作成します。 getUIError
メソッドは、SwingがLook & FeelのUIオブジェクトを検出できなかった場合に呼び出されるメソッドです。 単にこのメソッドで何もしなければ、エラー・メッセージを回避できます。
まれに、補助的なLook & FeelのUIオブジェクトが、コンポーネントに使用されるデフォルトUIオブジェクトに関心がある場合があります。 この場合、補助的なLook & FeelのUIオブジェクトはgetUI
メソッドを呼び出すことで、コンポーネントからUIを取得できます。 返されるUIは、いずれかの多重Look & Feel UIクラス(MultiButtonUI
など)のインスタンスです。補助的なLook & FeelのUIオブジェクトは、返されたオブジェクトのgetUIs
メソッドを呼び出して、多重UIによって処理されるすべてのUIオブジェクトの完全なリストが含まれた配列を取得できます。最初の要素は、デフォルトのLook & Feelから作成されたUIであることが保証されます。
javax.swing.plaf.multi.MultiLookAndFeel
で表される多重Look & Feelは、すべての開発者およびユーザーに対して透過的であるように作成されています。 それは「とにかく動作」すべきであり、ユーザーがSwingに補助的なLook & Feelを使用するように指示した場合にのみ使用されます。
多重Look & Feelが使用されている場合、各コンポーネントに関連付けられたUIオブジェクトの型は、現在使用中の任意の補助的なLook & Feelがそのコンポーネントをサポートするかどうかにより異なります。その場合、コンポーネントのUIオブジェクトは多重UIのインスタンスです。デフォルトLook & Feelのみがコンポーネントをサポートする場合、補助的なLook & Feelがインストールされていないかのように、そのコンポーネントはUIオブジェクトをデフォルトLook & Feelから取得します。
多重UIオブジェクトは、UIオブジェクトをデフォルトおよび補助的なLook & Feelから取得して維持し、これらのUIを次の方法で参照します。
swing.auxiliarylaf
プロパティで指定されている順序で、それぞれの補助的なLook &Feelから作成されます。getPreferredSize
メソッドが呼び出されると、このUIは、デフォルトLook & Feelから取得したUIのgetPreferredSize
の呼出しの結果のみを返します。また、それぞれの補助的なLook &FeelのUIオブジェクトのgetPreferredSize
メソッドも呼び出されますが、戻り値は無視されます。 installUI
メソッドを呼び出すと、多重UIは、デフォルトLook & Feelから取得したUIと、補助的なファクトリから取得したUIでinstallUI
を呼び出します。 すべての場合で、デフォルトLook & Feelから取得したUIオブジェクトが最初に処理され、補助的なLook & Feelはswing.auxiliarylaf
プロパティで指定されている順序で処理されます。
多重Look &Feelの動作が代わりの多重Look &Feelを必要としないほど柔軟になるのが望ましいことですが、Swingでは、ユーザーは使用する別の多重Look &Feelを指定できます。
これを実行するには、ユーザーが$JDKHOME/lib/swing.properties
ファイルを変更してswing.plaf.multiplexinglaf
プロパティの定義を含めるだけです。 その後、Swingはswing.plaf.multiplexinglaf
プロパティを、多重をサポートするLookAndFeel
のサブクラスとみなします。
たとえば、多重Look & Feel (javax.swing.plaf.multi.MultiLookAndFeel
)よりもニーズに合うcom.myco.SuperMultiLookAndFeel
で表される多重Look & Feelをユーザーが持っている場合、ユーザーは次の行を$JDKHOME/lib/swing.properties
に含めることができます。
swing.plaf.multiplexinglaf = com.myco.SuperMultiLookAndFeel
この文はSwingにjavax.swing.plaf.multi.MultiLookAndFeel
の代わりにcom.myco.SuperMultiLookAndFeel
を使用するように指示します。ただし、補助的なLook & Feelの供給者は標準の多重Look & Feelに対して開発しテストしている可能性が高いため、この種類の文を使用する場合は注意してください。