The style binding mechanism is another great feature of Synth look and feel. By using style binding, you can define several button styles within the same look and feel (one as default button style and the others are candidates), the final user can decide which style can be applied on which button.
How could Synth achieve this? The answer is hidden in thebind node in XML. Let's make an example, the Synth look and feel can be customized by an XML file like this:
<synth> <style id="Button"> ...... </style> <bind style="Button" type="region" key="Button" /> <style id="Button_Search"> ...... </style> <bind style="Button_Search" type="name" key="Button.Search" /> </synth>
It is really simple and only two styles are defined, each style node will be followed by a bind node, which specify how to apply the style. After reading the Synth XML format, we understand that thetype attribute in bind node can be either "region" or "name", these two region types are both used in the example above, but what do they mean?
<bind style="Button" type="region" key="Button" />
This bind node is defining this rule: the style with id "Button" will be bound to the region named "Button". But what is region? It is really confusing at the first time, but finally I understand it is a distinct rendering area of a Swing component, we can find thejavax.swing.plaf.synth.Region class from JRE5+ to represent the same thing, this class defines a set of constant instances for external usage, like these:
public static final Region ARROW_BUTTON = new Region("ArrowButton","ArrowButtonUI"); public static final Region BUTTON = new Region("Button", "ButtonUI"); public static final Region CHECK_BOX = new Region("CheckBox", "CheckBoxUI"); ......
The constructor of Region class accepts two parameters, the first one is the name of region, and the second one is the corresponding UI identification. The name of region can be used by the bind node in Synth XML. Now we know the first bind node exactly bind the style to the BUTTON region. BTW, how could we know the region name (like "Button") when we are writing the Synth XML? Oh, I am afraid we have to read the source code ofjavax.swing.plaf.synth.Region class.
Each simple swing component has one region only. For example, BUTTON region is for JButton component, so bind a style to the BUTTON region can customize the painting of JButton. For some complex component, it is consist of several simple components, so they will have several regions. For example, a JComboBox component is consist of SynthArrowButton, JList, JPopupMenu, JScrollPane and JTextField etc., so it will have several regions for customizing: ARROW_BUTTON, LIST, POPUP_MENU, SCROLL_PANE and TEXT_FIELD etc.
If a style is bound to a region, it will become thedefault style of this region. Example: if we bind a style to the BUTTON region, all JButton objects we created will have the same style (unless we specify not to use the default style, see below).
The Usage of Component Name:
There is a public method setName() injava.awt.Component class , so this method is available on any swing components. That means we can specify the name of each swing component, is it meaningful for using Synth? Sure! Remember the type value of bind node? It can be "name", which means the style will be bound to the component with the given name! So now we can explain the second bind node in the example:
<bind style="Button_Search" type="name" key="Button.Search" />
It defines such a rule: the style with id "Button_Search" will be bound to the component with the name "Button.Search". So if we have a JButton created in this way:
final JButton searchButton = new JButton("Search"); searchButton.setName("Button.Search");
This button will have a different style than other buttons, since it has the special name, so a non-defaultstyle will be applied on it.
Once we understand the style binding mechanism provided by Synth, making several styles for any components will not be a problem.
PS: One name can be assigned to several components, all components with the same name will share the same style.