Synth's file format (dtd)
allows for specifying all the pieces
necessary to create your own look and feel. A synth file is
loaded by way of the SynthLookAndFeel.load method. The
following example uses the load
method to configure
a SynthLookAndFeel
and sets it as the current look
and feel:
SynthLookAndFeel laf = new SynthLookAndFeel(); laf.load(MyClass.class.getResourceAsStream("laf.xml", MyClass.class)); UIManager.setLookAndFeel(laf);
While the DTD for synth is specified, the parser is not validating. Parsing will fail if a necessary attribute is not specified, or of the wrong type.
<!ELEMENT synth ((%beansPersistance;) | style | bind | font | color | imagePainter | imageIcon)*> <!ATTLIST synth version CDATA #IMPLIED >
Attribute definitions
The synth element contains all the other elements that make up a SynthLookAndFeel definition.
<!ELEMENT style (property | defaultsProperty | state | font | painter | imagePainter | backgroundImage | opaque | (%beansPersistance;) | imageIcon)*> <!ATTLIST style id ID #IMPLIED clone IDREF #IMPLIED >
Attribute definitions
A style element corresponds to a
SynthStyle
, with the child elements specifying
properties that apply to all states or state elements which
contain properties specific to a particular state. The following
example creates an opaque style with the id button
,
insets of 4, 4, 4, 4 and a font of Dialog 12.
<style id="button"> <opaque value="true"/> <insets top="4" left="4" right="4" bottom="4"/> <font name="Dialog" size="12"/> </style>
The following example creates a new style with an id of
clonedButton
that is a copy of the
style with id button
and has a font of Dialog,
14. The resulting style will be opaque, have insets of 4, 4, 4,
4 and a font of Dialog 14.
<style id="clonedButton" clone="button"> <font name="Dialog" size="14"/> </style>
<!ELEMENT state (color | font | painter | imagePainter | (%beansPersistance;))*> <!ATTLIST state id ID #IMPLIED clone IDREF #IMPLIED value CDATA #IMPLIED idref IDREF #IMPLIED >
Attribute definitions
The state element specifies the visual
properties that are to be used for
a particular state of a component. For example, you could
specify the background color when the Component is enabled should look
different than the background color when the component is
disabled. Not all Components support all states. For example, a
Panel
only supports the states ENABLED and DISABLED.
The following example creates a state with a red background that will be used when the component is in an a selected and pressed state:
<state value="SELECTED AND PRESSED"> <color value="RED" type="BACKGROUND"/> </state>
The state with the most individual matches will be chosen. For example, the following defines two states:
<state value="SELECTED and PRESSED" id="one"> <color value="RED" type="BACKGROUND"/> </state> <state value="SELECTED" id="two"> <color value="RED" type="BACKGROUND"/> </state>
State one
is used when the Component is SELECTED
and PRESSED, and state two
when the Component is
SELECTED. If the state of the Component
contains at least SELECTED and PRESSED, state one
will be
chosen, otherwise if the state is SELECTED, but not does not
contain PRESSED, state two
will be used.
<!ELEMENT font EMPTY> <!ATTLIST font id ID #IMPLIED clone IDREF #IMPLIED name CDATA #IMPLIED style CDATA #IMPLIED size CDATA #IMPLIED >
Attribute definitions
Defines the font for the current state, or style. You must specify either an idref or a name and size.
The following example creates a style with a Font of Dialog 12 Bold.
<style id="test"> <font name="DIALOG" size="12" style="BOLD"/> </style>
The following example creates a style with a font of Dialog 12 Bold that will be used if the component is ENABLED, otherwise Dialog 12 Italic will be used.
<style id="test"> <font name="DIALOG" size="12" style="ITALIC"/> <state value="ENABLED"> <font name="DIALOG" size="12" style="BOLD"/> </state> </style>
While you can supply a different font per state, in general widgets will NOT revalidate when the state changes, so that you may run into sizing problems if you try to use a font with a significantly different size for different states.
<!ELEMENT color EMPTY> <!ATTLIST color id ID #IMPLIED idref IDREF #IMPLIED type CDATA #IMPLIED value CDATA #IMPLIED >
Attribute definitions
Color
class, for example RED. A hex value of the form
#RRGGBB where RR gives the red component, GG the green component and
BB the blue component. A hex value of the form #RRGGBBAA, which is
the same as #RRGGBB with the addition of an alpha component.Color defines a color and what portion of the Component it should be applied to. The following example will use a background color of RED when the component is enabled.
<state value="ENABLED"> <color value="RED" type="BACKGROUND"/> </state>
The following example will have a red background when the Component is enabled, otherwise blue.
<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 IDREF #REQUIRED type (idref|boolean|dimension|insets|integer) "idref" value CDATA #REQUIRED >
Attribute definitions
Property elements are used to add key value pairs to a
SynthStyle
that can be accessed by way of the
get
method. Many Component
s use the
key value pairs for configuring their visual appearance. Refer to
property table for a list of the
properties each Component
supports. The following
creates the properties
ScrollBar.allowsAbsolutePositioning
,
OptionPane.minimumSize
,
ScrollPane.viewportBorderInsets
,
Tree.rowHeight
and foreground
with the
values false, a dimensions of 262x90, an insets of 5, 5, 5, 5,
the integer 20 and an instance of the
class ArrowButtonPainter.
<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>
<!ELEMENT defaultsProperty EMPTY> <!ATTLIST defaultsProperty key IDREF #REQUIRED type (idref|boolean|dimension|insets|integer) "idref" value CDATA #REQUIRED >
Attribute definitions
DefaultsProperty elements are
used to define properties that will be placed in the
UIDefaults
table that SynthLookAndFeel
supplies to the UIManager
. The following assigns the
the Color red to the value 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>
This value could then be asked by way of
UIManager.get("Table.focusCellForeground")
.
<!ELEMENT graphicsUtils EMPTY> <!ATTLIST graphicsUtils idref IDREF #REQUIRED >
Attribute definitions
GraphicsUtils elements are used to define the SynthGraphicsUtils that the current style will use. The following example creates a style with an instance of CustomGraphicsUtils for the SynthGraphicsUtils.
<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 >
Attribute definitions
Insets elements are used to define the Insets for the current style. The insets will be set on any Components the style is associated with. The following example creates a style with insets of 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 >
Attribute definitions
Bind elements specify which Regions a style
is to be used for. The following example applies the
style test to any Component whose name
starts with test
.
<style id="test"> <insets top="1" bottom="2" left="3"/> </style> <bind style="test" type="name" key="test.*"/>
Numerous styles may apply to a region, in which case each of the matching styles is merged into a resulting style that is used. Precedence is given to styles defined later in the file. For example, the following defines two styles, a and b. Style a is applied to any component with a name starting with test, and style b is used for button regions.
<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"/>
For a button with the name test this is equivalent to:
<style> <font name="DIALOG" size="12" style="BOLD"/> <insets top="1" bottom="2" left="3"/> </style>
Merging happens for states of a style as well.
<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"/>
For a button with the name test this is equivalent to:
<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|horizontal|vertical|horizontal_split|vertical_split) #IMPLIED >
Attribute definitions
Painter defines a SynthPainter for the current
style or the state of the current style. The following example
binds an instance of the class MyPainter
which must be a SynthPainter
to the style test
.
<style id="test"> <object class="MyPainter" id="MyPainter"/> <painter idref="MyPainter"/> </style>
The painter that is used for a particular method and state is determined as follows:
Consider the following:
<style id="test"> <painter idref="fallbackPainter"/> <painter idref="styleButtonBackgroundPainter" method="buttonBackground"/> <state value="SELECTED"> <painter idref="stateFallbackPainter"/> <painter idref="stateButtonBackgroundPainter" method="buttonBackground"/> </state> </style>
The following outlines which painter will be used for what SynthPainter method:
State | Method | Painter |
---|---|---|
SELECTED | paintButtonBackground | stateButtonBackgroundPainter |
SELECTED | Anything but paintButtonBackground | stateFallbackPainter |
Anything but SELECTED | paintButtonBackground | styleButtonBackgroundPainter |
Anything but SELECTED | Anything but paintButtonBackground | fallbackPainter |
<!ELEMENT imagePainter EMPTY> <!ATTLIST imagePainter id ID #IMPLIED method CDATA #IMPLIED direction (north|south|east|west|horizontal|vertical|horizontal_split|vertical_split) #IMPLIED path CDATA #REQUIRED sourceInsets CDATA #REQUIRED destinationInsets CDATA #IMPLIED paintCenter (true|false) "true" stretch (true|false) "true" >
Attribute definitions
The ImagePainter element defines a
painter for the current style or state that will render a particular
image. The following example
sets an image to be used for any painting this done by widgets that
use the style text
<style id="test"> <imagePainter path="resources/myImage.png" sourceInsets="2 2 2 2"/> </style>
Refer to the description of the painter element for details as to the precedence in choosing a painter.
Attribute definitions
ImageIcon is used to assign an Icon implementation that is wrapping an Image to a unique identifier. This is typically used for properties that take an Icon. The following example binds an ImageIcon to the property RadioButton.icon.
<style id="test"> <imageIcon id="icon" path="resources/myImage.png"/> <property key="RadioButton.icon" value="icon"/> </style>
Attribute definitions
The opaque element indicates whether or not any Components the style is associated with are to be made opaque. The painter will be asked to paint regardless of the opacity of the associated Component. The following example creates a style that is not opaque.
<style id="test"> <opaque value="FALSE"> <painter idref="painter"/> </style>
Beans persistance can be used to embed any Object. This is typically used for embedding your own Painters, but can be used for other arbritrary objects as well. Refer to http://java.sun.com/products/jfc/tsc/articles/persistence3/ for details on beans persistance.