Synth のファイル形式 (dtd) により、独自の Look & Feel の作成に必要なものをすべて指定できます。Synth ファイルは SynthLookAndFeel.load(InputStream, Class) メソッドまたは SynthLookAndFeel.load(URL) メソッドを介してロードされます。次の例では、load メソッドを使用して SynthLookAndFeel を構成し、それを現在の Look & Feel として設定しています。
SynthLookAndFeel laf = new SynthLookAndFeel();
laf.load(MyClass.class.getResourceAsStream("laf.xml"), MyClass.class);
UIManager.setLookAndFeel(laf);
この例では、リソースベースとして指定されたクラスを使用してパスを解決し、Look & Feel を入力ストリームからロードします。また、次の例のように任意の URL から Look & Feel をロードすることもできます。
SynthLookAndFeel laf = new SynthLookAndFeel();
laf.load(new URL("file:///C:/java/synth/laf/laf.xml"));
UIManager.setLookAndFeel(laf);
たとえば、メソッド SynthLookAndFeel.load(URL) を使用して、次のいずれかから Look & Feel をロードできます。
file:///C:/java/synth/laf/laf.xml などhttp://host/laf.xml などjar:file:///C:/synth-laf.jar!/laf.xml などjar:http://host/synth-laf.jar!/laf.xml などSynth 用 DTD が指定されていますが、パーサーは検証しません。必要な属性が指定されていないか、必要な属性に不正な型が指定された場合のみ、構文解析が失敗します。
<!ELEMENT synth ((%beansPersistance;) | style | bind | font | color | imagePainter | imageIcon | defaultsProperty)*> <!ATTLIST synth version CDATA #IMPLIED >
属性の定義
synth 要素には、SynthLookAndFeel 定義を構成するその他の要素がすべて含まれます。
<!ELEMENT style (property | defaultsProperty | state | font | graphicsUtils | insets | painter | imagePainter | opaque | (%beansPersistance;) | imageIcon)*> <!ATTLIST style id ID #IMPLIED clone IDREF #IMPLIED >
属性の定義
style 要素は SynthStyle に対応し、すべての状態、または特定状態に対して固有のプロパティーを含む状態要素に適用されるプロパティーを子要素で指定します。次の例では、ID に button、インセットに 4、4、4、4、そしてフォントに Dialog 12 を指定して不透明なスタイルを作成します。
<style id="button">
<opaque value="true"/>
<insets top="4" left="4" right="4" bottom="4"/>
<font name="Dialog" size="12"/>
</style>
次の例では、ID に clonedButton を指定した新しいスタイルを作成しますが、このスタイルは ID button のスタイルのコピーであり、フォントは Dialog、14 です。作成されたスタイルは不透明になり、インセットに 4、4、4、4 が指定され、フォントに Dialog、14 が指定されます。
<style id="clonedButton" clone="button">
<font name="Dialog" size="14"/>
</style>
<!ELEMENT state (color | font | painter | imagePainter | (%beansPersistance;) | property | imageIcon)*> <!ATTLIST state id ID #IMPLIED clone IDREF #IMPLIED value CDATA #IMPLIED idref IDREF #IMPLIED >
属性の定義
state 要素は、コンポーネントの特定状態に使用される視覚的なプロパティーを指定します。たとえば、Component が有効な場合の背景色と無効な場合の背景色を異なる色に指定できます。すべての Component がすべての状態をサポートしているとはかぎりません。たとえば、Panel は状態 ENABLED および DISABLED のみをサポートします。
次の例では、コンポーネントが選択された状態および押された状態のときに使用される赤い背景を指定して状態を作成します。
<state value="SELECTED AND PRESSED">
<color value="RED" type="BACKGROUND"/>
</state>
個々の一致がもっとも多い状態が選択されます。たとえば、次の 2 つの状態を定義します。
<state value="SELECTED and PRESSED" id="one">
<color value="RED" type="BACKGROUND"/>
</state>
<state value="SELECTED" id="two">
<color value="RED" type="BACKGROUND"/>
</state>
Component が SELECTED および PRESSED の場合は状態 one が使用され、コンポーネントが SELECTED の場合は状態 two が使用されます。Component の状態に少なくとも SELECTED および PRESSED が含まれている場合は状態 one が選択され、それ以外の場合に状態が SELECTED であり PRESSED が含まれていないときは、状態 two が使用されます。
<!ELEMENT font EMPTY> <!ATTLIST font id ID #IMPLIED clone IDREF #IMPLIED name CDATA #IMPLIED style CDATA #IMPLIED size CDATA #IMPLIED >
属性の定義
現在の state、または style のフォントを定義します。idref、または name および size を指定する必要があります。
次の例では、Dialog 12 Bold の Font を指定してスタイルを作成します。
<style id="test">
<font name="DIALOG" size="12" style="BOLD"/>
</style>
次の例では、コンポーネントが ENABLED の場合は Dialog 12 Bold のフォントが使用され、それ以外の場合は Dialog 12 Italic が使用されるスタイルを作成します。
<style id="test">
<font name="DIALOG" size="12" style="ITALIC"/>
<state value="ENABLED">
<font name="DIALOG" size="12" style="BOLD"/>
</state>
</style>
状態ごとに別のフォントを指定できますが、一般にウィジェットは状態が変更されても再検証しないため、各種の状態に対してサイズが大きく異なるフォントを使用しようとすると、サイズ変更の問題が生じる場合があります。
<!ELEMENT color EMPTY> <!ATTLIST color id ID #IMPLIED idref IDREF #IMPLIED type CDATA #IMPLIED value CDATA #IMPLIED >
属性の定義
Color クラスの定数の名前 ( RED など)。
#RRGGBB の 16 進数の値で、RR は赤色成分、GG は緑色成分、BB は青色成分を示します。すべての色成分を指定する必要はありません。たとえば、#123 は #000123 と同等です。
#ARRGGBB または #AARRGGBB の 16 進数の値。これは、0xFF 以外のアルファ値に役立ちます。形式 #ARRGGBB は #0ARRGGBB と同等です。
color は色と、色を適用すべき Component の部分を定義します。次の例では、コンポーネントが有効な場合に赤色の背景色を使用します。
<state value="ENABLED">
<color value="RED" type="BACKGROUND"/>
</state>
次の例では、Component が有効な場合に赤色の背景を使用し、それ以外の場合は青色を使用します。
<style id="test">
<state value="ENABLED">
<color value="RED" type="BACKGROUND"/>
</state>
<state>
<color value="#00FF00" type="BACKGROUND"/>
</state>
</style>
<!ELEMENT property EMPTY> <!ATTLIST property key CDATA #REQUIRED type (idref|boolean|dimension|insets|integer|string) "idref" value CDATA #REQUIRED >
属性の定義
property 要素は SynthStyle にキーと値のペアを追加するために使用され、このキーと値のペアは get メソッドを介してアクセスできます。多くの Component は、外観を構成するためにキーと値のペアを使用します。各 Component がサポートするプロパティーのリストについては、プロパティー表を参照してください。次では、値 false、寸法 262x90、インセット 5、5、5、5、整数 20、およびクラス ArrowButtonPainter のインスタンスを指定して、プロパティー ScrollBar.allowsAbsolutePositioning、OptionPane.minimumSize、ScrollPane.viewportBorderInsets、Tree.rowHeight および foreground を作成します。
<style id="test">
<property key="ScrollBar.allowsAbsolutePositioning" type="boolean" value="false"/>
<property key="OptionPane.minimumSize" type="dimension" value="262 90"/>
<property key="ScrollPane.viewportBorderInsets" type="insets" value="5 5 5 5"/>
<property key="Tree.rowHeight" type="integer" value="20"/>
<object class="ArrowButtonPainter" id="ArrowButtonPainter"/>
<property key="foreground" type="idref" value="ArrowButtonPainter"/>
</style>
また、特定の状態に適用されるプロパティーを指定することもできます。各状態のプロパティーがアクセスされるかどうかは、プロパティーの使用方法により異なります。たとえば、デフォルトアイコンと、マウスがコンポーネント上にある場合に使用するアイコンを次のように指定します。
<style id="test">
<imageIcon id="defaultIcon" path="resources/myImage.png"/>
<property key="RadioButton.icon" value="defaultIcon"/>
<state value="MOUSE_OVER">
<imageIcon id="mouseOverIcon" path="resources/myMouseOverImage.png"/>
<property key="RadioButton.icon" value="mouseOverIcon"/>
</state>
</style>
<!ELEMENT defaultsProperty EMPTY> <!ATTLIST defaultsProperty key CDATA #REQUIRED type (idref|boolean|dimension|insets|integer|string) "idref" value CDATA #REQUIRED >
属性の定義
defaultsProperty 要素は、SynthLookAndFeel が UIManager に提供する UIDefaults テーブルに配置されるプロパティーを定義するために使用されます。次では、Table.focusCellForeground に赤色を割り当てています。
<style id="test">
<object class="javax.swing.plaf.ColorUIResource" id="color">
<int>255</int>
<int>0</int>
<int>0</int>
</object>
<defaultsProperty key="Table.focusCellForeground" type="idref" value="color"/>
</style>
これにより、UIManager.get("Table.focusCellForeground") を介してこの値を要求できます。
<!ELEMENT graphicsUtils EMPTY> <!ATTLIST graphicsUtils idref IDREF #REQUIRED >
属性の定義
GraphicsUtils 要素は、現在の style で使用される SynthGraphicsUtils を定義するために使用されます。次の例では、SynthGraphicsUtils の CustomGraphicsUtils のインスタンスを指定してスタイルを作成します。
<style id="test">
<object class="CustomGraphicsUtils" id="graphics"/>
<graphicsUtils idref="graphics"/>
</style>
<!ELEMENT insets EMPTY> <!ATTLIST insets id ID #IMPLIED idref IDREF #IMPLIED top CDATA #IMPLIED bottom CDATA #IMPLIED left CDATA #IMPLIED right CDATA #IMPLIED >
属性の定義
insets 要素は、現在の style の Insets を定義するために使用されます。insets は、style が関連付けられたすべての Component に設定されます。次の例では、insets に 1、2、3、0 を指定してスタイルを作成します。
<style id="test">
<insets top="1" bottom="2" left="3"/>
</style>
<!ELEMENT bind EMPTY> <!ATTLIST bind style IDREF #REQUIRED type (name|region) #REQUIRED key CDATA #REQUIRED >
属性の定義
bind 要素は、スタイルが使用される対象の Region を指定します。次の例では、style test を名前が test で始まるすべての Component に適用します。
<style id="test">
<insets top="1" bottom="2" left="3"/>
</style>
<bind style="test" type="name" key="test.*"/>
多くのスタイルが 1 つの領域に適用される場合があり、その場合、一致する各スタイルは結果として使用される 1 つのスタイルにマージされます。ファイルの後のほうで定義されたスタイルが優先されます。たとえば、2 つのスタイル (a および b) を次のように定義します。スタイル a は名前が test で始まるすべてのコンポーネントに適用され、スタイル b はボタン領域に使用されます。
<style id="a">
<font name="DIALOG" size="12" style="ITALIC"/>
<insets top="1" bottom="2" left="3"/>
</style>
<bind style="a" type="name" key="test.*"/>
<style id="b">
<font name="DIALOG" size="12" style="BOLD"/>
</style>
<bind style="b" type="region" key="button"/>
test の名前を持つボタンの場合、これは次と同じです。
<style>
<font name="DIALOG" size="12" style="BOLD"/>
<insets top="1" bottom="2" left="3"/>
</style>
マージはスタイルの状態にも同様に発生します。
<style id="a">
<font name="DIALOG" size="12" style="ITALIC"/>
<insets top="1" bottom="2" left="3"/>
<state value="ENABLED">
<object id="customPainter" class="CustomPainter"/>
<painter idref="customPainter"/>
</state>
</style>
<bind style="a" type="name" key="test.*"/>
<style id="b">
<font name="DIALOG" size="12" style="BOLD"/>
<state value="ENABLED">
<font name="Lucida" size="12" style="ITALIC"/>
</state>
</style>
<bind style="b" type="region" key="button"/>
test の名前を持つボタンの場合、これは次と同じです。
<style>
<font name="DIALOG" size="12" style="BOLD"/>
<insets top="1" bottom="2" left="3"/>
<state value="ENABLED">
<object id="customPainter" class="CustomPainter"/>
<painter idref="customPainter"/>
<font name="Lucida" size="12" style="ITALIC"/>
</state>
</style>
<!ELEMENT painter EMPTY> <!ATTLIST painter idref IDREF #IMPLIED method CDATA #IMPLIED direction (north|south|east|west|top|left|bottom|right|horizontal|vertical|horizontal_split|vertical_split) #IMPLIED >
属性の定義
painter は、現在のスタイル、または現在のスタイルの状態の SynthPainter を定義します。次の例では、SynthPainter にする必要があるクラス MyPainter のインスタンスをスタイル test にバインドします。
<style id="test">
<object class="MyPainter" id="MyPainter"/>
<painter idref="MyPainter"/>
</style>
特定のメソッドおよび状態に使用されるペインタは、次のように決定されます。
次を考慮してください。
<style id="test">
<painter idref="fallbackPainter"/>
<painter idref="styleButtonBackgroundPainter" method="buttonBackground"/>
<state value="SELECTED">
<painter idref="stateFallbackPainter"/>
<painter idref="stateButtonBackgroundPainter" method="buttonBackground"/>
</state>
</style>
次では、どの SynthPainter メソッドにどのペインタが使用されるかについて概要を示します。
| 状態 | メソッド | ペインタ |
|---|---|---|
| SELECTED | paintButtonBackground | stateButtonBackgroundPainter |
| SELECTED | paintButtonBackground 以外のなんでも | stateFallbackPainter |
| SELECTED 以外のなんでも | paintButtonBackground | styleButtonBackgroundPainter |
| SELECTED 以外のなんでも | paintButtonBackground 以外のなんでも | fallbackPainter |
複数の同一ペインタが宣言されると、単一のペインタに集約されます。direction および method の属性値が等しい場合、2 つのペインタは同一です。次を考慮してください。
<style id="panelStyle"> <imagePainter method="panelBackground" path="red.png" /> <imagePainter method="panelBackground" path="green.png" /> <imagePainter method="panelBackground" path="blue.png" /> </style>
これらの 3 つのペインタは、同じメソッドと同じ方向 (デフォルトではすべての方向) を使用しているため、同一です。Synth は、これらのペインタを集約して、子のペインタを宣言順にペイントする単一のペインタを作成します。したがって、Synth は赤色、緑色、青色の順に画像をペイントします。子の各ペインタは、集約されたペインタのレイヤーと見なすことができます。
ペインタのアグリゲーション (マルチレイヤー化) は要素の再利用にとても役立ちます。ボタンや選択されたメニュー項目に強調表示効果を使用するとします。ペインタのアグリゲーションを使用すると、ボタンのペインタとメニュー項目のペインタに処理させる代わりに、別個のハイライトペインタを作成するだけで済みます。
<!ELEMENT imagePainter EMPTY> <!ATTLIST imagePainter id ID #IMPLIED method CDATA #IMPLIED direction (north|south|east|west|top|left|bottom|right|horizontal|vertical|horizontal_split|vertical_split) #IMPLIED path CDATA #REQUIRED sourceInsets CDATA #IMPLIED destinationInsets CDATA #IMPLIED paintCenter (true|false) "true" stretch (true|false) "true" center (true|false) "false" >
属性の定義
imagePainter 要素は、指定されたイメージを使用してレンダリングする、現在のスタイルまたは状態のペインタを定義します。imagePainter は、2 つの個別のレンダリングモードを提供します。最初のモードは、提供されたスペース内でイメージを中央揃えにするために使用されます。これは、一般的にウィジェット上の装飾のレンダリングに使用され、たとえば、スクロールボタンの矢印を指定するには中央揃えモードを使用します。次に、この例を示します。
<style id="test">
<imagePainter path="resources/myImage.png" center="true"/>
</style>
2 番目のモードは、イメージを拡大縮小して提供されたスペース内に収める際に使用されます。このモードの場合、sourceInsets はイメージ周囲のボーダーを指定するために使用され、ここで、ボーダーの北、南、東、西の端は引き伸ばされるかまたはタイル表示され (stretch 属性)、ボーダーの 4 隅は適切な位置に描画されて、中央が引き伸ばされます。このモードでは sourceInsets を指定する必要があります。次の例は、イメージ MyImage.png と上下左右がすべて 2 のインセットを使用している ImagePainter を示します。
<style id="test">
<imagePainter path="resources/myImage.png"
sourceInsets="2 2 2 2"/>
</style>
ペインタ選択の優先順位と、同一ペインタの処理方法についての詳細は、painter 要素の説明を参照してください。
属性の定義
imageIcon は、Image をラップしている Icon 実装を一意の識別子に割り当てるために使用されます。これは通常、Icon をとるプロパティーのために使用されます。次の例は、ImageIcon をプロパティー RadioButton.icon にバインドしています。
<style id="test">
<imageIcon id="icon" path="resources/myImage.png"/>
<property key="RadioButton.icon" value="icon"/>
</style>
属性の定義
opaque 要素は、スタイルが関連付けられたすべての Component を不透明にするかどうかを示します。ペインタは、関連付けられた Component の不透明性に関係なく、ペイントするように要求されます。次の例は、不透明ではないスタイルを作成します。
<style id="test">
<opaque value="FALSE">
<painter idref="painter"/>
</style>
Bean の永続性は任意の Object を組み込むために使用できます。これは通常、独自の Painter を組み込むために使用されますが、ほかの任意のオブジェクトのためにも使用できます。Bean の永続性についての詳細は、http://java.sun.com/products/jfc/tsc/articles/persistence3/ を参照してください。
Synth ファイルの作成では、すべてのコンポーネントで使用されるバッキングスタイルを作成することをお勧めします。これにより、特定のスタイルに一致しないすべてのコンポーネントがデフォルトのフォント、前景、背景、および不透明性を使用するようになります。次に、この例を示します。
<synth>
<style id="backingStyle">
<opaque value="true"/>
<font name="Dialog" size="12"/>
<state>
<color value="BLACK" type="BACKGROUND"/>
<color value="WHITE" type="FOREGROUND"/>
</state>
</style>
<bind style="backingStyle" type="region" key=".*"/>
</synth>