Platinum Partner
java,easynth l&f,java l&f custom,synth l&f customize

EaSynth Look And Feel Customization (2)

This article will introduce the customization of arrow button, checkbox button, radio button and toggle button base on EaSynth look and feel.

Arrow Button Customization

The arrow buttons are used in four kinds of components: JComboBox, JSplitPane, JScrollBar and JSpinner (see the figure bellow), if we custom the style for arrow button, all arrow buttons on these components will change as well.

We can find the arrow button style block in the "easynth.xml" file by searching the style with "Arrow Button" id:

<!-- The style for arrow buttons. -->
<style id="Arrow Button">
<property key="ArrowButton.size" type="integer" value="9"/>
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="north"/>
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="west"/>
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="south"/>
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="east"/>
<state value="ENABLED">
<imageIcon id="Arrow_Up_Enabled" path="resource/1204972099671_arrow_up_normal.png"/>
<property key="EaSynth.arrow.up.enabled" type="idref" value="Arrow_Up_Enabled"/>
<imageIcon id="Arrow_Left_Enabled" path="resource/1204972109765_arrow_left_normal.png"/>
<property key="EaSynth.arrow.left.enabled" type="idref" value="Arrow_Left_Enabled"/>
<imageIcon id="Arrow_Down_Enabled" path="resource/1204972119562_arrow_down_normal.png"/>
<property key="EaSynth.arrow.down.enabled" type="idref" value="Arrow_Down_Enabled"/>
<imageIcon id="Arrow_Right_Enabled" path="resource/1204972131593_arrow_right_normal.png"/>
<property key="EaSynth.arrow.right.enabled" type="idref" value="Arrow_Right_Enabled"/>
</state>
<state value="MOUSE_OVER">
<imageIcon id="Arrow_Up_MouseOver" path="resource/1204972154296_arrow_up_over.png"/>
<property key="EaSynth.arrow.up.mouseover" type="idref" value="Arrow_Up_MouseOver"/>
<imageIcon id="Arrow_Left_MouseOver" path="resource/1204972172953_arrow_left_over.png"/>
<property key="EaSynth.arrow.left.mouseover" type="idref" value="Arrow_Left_MouseOver"/>
<imageIcon id="Arrow_Down_MouseOver" path="resource/1204972180796_arrow_down_over.png"/>
<property key="EaSynth.arrow.down.mouseover" type="idref" value="Arrow_Down_MouseOver"/>
<imageIcon id="Arrow_Right_MouseOver" path="resource/1204972188046_arrow_right_over.png"/>
<property key="EaSynth.arrow.right.mouseover" type="idref" value="Arrow_Right_MouseOver"/>
</state>
<state value="PRESSED">
<imageIcon id="Arrow_Up_Pressed" path="resource/1204972222593_arrow_up_press.png"/>
<property key="EaSynth.arrow.up.pressed" type="idref" value="Arrow_Up_Pressed"/>
<imageIcon id="Arrow_Left_Pressed" path="resource/1204972229812_arrow_left_press.png"/>
<property key="EaSynth.arrow.left.pressed" type="idref" value="Arrow_Left_Pressed"/>
<imageIcon id="Arrow_Down_Pressed" path="resource/1204972236828_arrow_down_press.png"/>
<property key="EaSynth.arrow.down.pressed" type="idref" value="Arrow_Down_Pressed"/>
<imageIcon id="Arrow_Right_Pressed" path="resource/1204972243953_arrow_right_press.png"/>
<property key="EaSynth.arrow.right.pressed" type="idref" value="Arrow_Right_Pressed"/>
</state>
<state value="DISABLED">
<imageIcon id="Arrow_Up_Disabled" path="resource/1204972279156_arrow_up_disable.png"/>
<property key="EaSynth.arrow.up.disabled" type="idref" value="Arrow_Up_Disabled"/>
<imageIcon id="Arrow_Left_Disabled" path="resource/1204972286015_arrow_left_disable.png"/>
<property key="EaSynth.arrow.left.disabled" type="idref" value="Arrow_Left_Disabled"/>
<imageIcon id="Arrow_Down_Disabled" path="resource/1204972293703_arrow_down_disable.png"/>
<property key="EaSynth.arrow.down.disabled" type="idref" value="Arrow_Down_Disabled"/>
<imageIcon id="Arrow_Right_Disabled" path="resource/1204972301171_arrow_right_disable.png"/>
<property key="EaSynth.arrow.right.disabled" type="idref" value="Arrow_Right_Disabled"/>
</state>
</style>
<bind style="Arrow Button" type="region" key="ArrowButton" />

The arrow button also have four states: ENABLED, MOUSE_OVER, PRESSED and DISABLED, just like the regular buttons. This style block firstly define the size of the arrow, this value should be consistent with the image to render the arrow:

<property key="ArrowButton.size" type="integer" value="9"/> 

The "ArrowButton.size" property is not an EaSynth open property, it is a standard property provided by Synth look and feel. Then assign the EaSynthPainter object to the four painter elements for the paintings for different directions.

<object id="EaSynthPainter" class="com.easynth.designer.laf.painter.EaSynthPainter"></object>
......
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="north"/>
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="west"/>
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="south"/>
<painter idref="EaSynthPainter" method="arrowButtonForeground" direction="east"/> 

Again we see a Java been persistance, it is an object of painter class that extended from "javax.swing.plaf.synth.SynthPainter". EaSynth look and feel use only one painter object for all the paintings, it is simpler but less flexible. Actually Synth look and feel allows using different painters for different paintings, just needing to assign different painter bean object to different painter element.

The painter elements set the "method" attribute to "arrowButtonForeground", means the calling of paintArrowButtonForeground() method defined in SynthPainter class will be delegated to the EaSynthPainter subclass. If we review the "EaSynthPainter.java" file, we will notice that the paintArrowButtonForeground() method in the EaSynthPainter class will load different icons to paint the arrow for different directions. It accepts the icons linked by the following properties:

EaSynth.arrow.up.enabled: the arrow icon for "up" direction, for ENABLED state;
EaSynth.arrow.left.enabled: the arrow icon for "left" direction, for ENABLED state;
EaSynth.arrow.down.enabled: the arrow icon for "down" direction, for ENABLED state;
EaSynth.arrow.right.enabled: the arrow icon for "right" direction, for ENABLED state;

EaSynth.arrow.up.mouseover: the arrow icon for "up" direction, for MOUSE_OVER state;
EaSynth.arrow.left.mouseover: the arrow icon for "left" direction, for MOUSE_OVER state;
EaSynth.arrow.down.mouseover: the arrow icon for "down" direction, for MOUSE_OVER state;
EaSynth.arrow.right.mouseover: the arrow icon for "right" direction, for MOUSE_OVER state;

EaSynth.arrow.up.pressed: the arrow icon for "up" direction, for PRESSED state;
EaSynth.arrow.left.pressed: the arrow icon for "left" direction, for PRESSED state;
EaSynth.arrow.down.pressed: the arrow icon for "down" direction, for PRESSED state;
EaSynth.arrow.right.pressed: the arrow icon for "right" direction, for PRESSED state;

EaSynth.arrow.up.disabled: the arrow icon for "up" direction, for DISABLED state;
EaSynth.arrow.left.disabled: the arrow icon for "left" direction, for DISABLED state;
EaSynth.arrow.down.disabled: the arrow icon for "down" direction, for DISABLED state;
EaSynth.arrow.right.disabled: the arrow icon for "right" direction, for DISABLED state;

So we can see the xml code to link an image to a property under each state in the arrow button style, the following piece of code is an example, it links a png image file to the "EaSynth.arrow.up.mouseover" property element, via the "Arrow_Up_MouseOver" id:

<imageIcon id="Arrow_Up_MouseOver" path="resource/1204972154296_arrow_up_over.png"/>
<property key="EaSynth.arrow.up.mouseover" type="idref" value="Arrow_Up_MouseOver"/> 

So, by changing the specified image files, we can custom the arrow image, for different state, for different directions.

Checkbox Button Customization

There are four states defined for checkbox button in EaSynth look and feel, the states and their appearance are shown below:

There is no any special open property used here to custom the checkbox style, EaSynth look and feel only use the "CheckBox.icon" property, which is defined in the Synth XML Format document. If we search the style with "Check Box" id, we will find these:

<!-- The style for check box button. -->
<style id="Check Box">
<property key="CheckBox.margin" type="insets" value="2 2 2 2"/>
<state value="ENABLED">
<imageIcon id="Checkbox_Normal" path="resource/1204453247375_checkbox_normal.png"/>
<property key="CheckBox.icon" type="idref" value="Checkbox_Normal"/>
</state>
<state value="MOUSE_OVER">
<imageIcon id="Checkbox_MouseOver" path="resource/1204453256531_checkbox_mouseover.png"/>
<property key="CheckBox.icon" type="idref" value="Checkbox_MouseOver"/>
</state>
<state value="SELECTED">
<imageIcon id="Checkbox_Selected" path="resource/1204453267203_checkbox_selected.png"/>
<property key="CheckBox.icon" type="idref" value="Checkbox_Selected"/>
</state>
<state value="DISABLED">
<imageIcon id="Checkbox_Disabled" path="resource/1204122673828_checkbox_disabled.png"/>
<property key="CheckBox.icon" type="idref" value="Checkbox_Disabled"/>
</state>
</style>
<bind style="Check Box" type="region" key="CheckBox" />

The property element again uses "idref" type to link to an imageIcon element, which specifies an image file for the checkbox icon. So the customization for checkbox will be very easy: just replace those image files, we will then have a new look of the checkbox.

Radio Button Customization

There are five states defined for radio button in EaSynth look and feel, the states and their appearance are shown below:

 

Nothing surprise here, EaSynth look and feel use the "RadioButton.icon" typical property to define the icon for each state. The xml code to define the radio button looks like:

<!-- The style for radio button. -->
<style id="Radio Button">
<property key="RadioButton.margin" type="insets" value="2 2 2 2"/>
<state value="ENABLED">
<imageIcon id="Radio_Button_Normal" path="resource/1204454221531_radio_enabled.png"/>
<property key="RadioButton.icon" type="idref" value="Radio_Button_Normal"/>
</state>
<state value="MOUSE_OVER">
<imageIcon id="Radio_Button_MouseOver" path="resource/1204454231234_radio_mouseover.png"/>
<property key="RadioButton.icon" type="idref" value="Radio_Button_MouseOver"/>
</state>
<state value="PRESSED">
<imageIcon id="Radio_Button_Pressed" path="resource/1204454241875_radio_pressed.png"/>
<property key="RadioButton.icon" type="idref" value="Radio_Button_Pressed"/>
</state>
<state value="DISABLED">
<imageIcon id="Radio_Button_Disabled" path="resource/1204121589843_radio_disabled.png"/>
<property key="RadioButton.icon" type="idref" value="Radio_Button_Disabled"/>
</state>
<state value="SELECTED">
<imageIcon id="Radio_Button_Selected" path="resource/1204454252156_radio_selected.png"/>
<property key="RadioButton.icon" type="idref" value="Radio_Button_Selected"/>
</state>
</style>
<bind style="Radio Button" type="region" key="RadioButton" />

So again it will be an easy job to custom the look of radio button: just change those image files.

Comparing with the checkbox button customization, we will find that the radio button has one more state: PRESSED. Can checkbox button also have a PRESSED state? The answer is positive. EaSynth look and feel omits the PRESSED state for checkbox button; it is just a decision for designing. We can custom the PRESSED state for checkbox button by adding a new state node with "PRESSED" value under the checkbox style node.

Toggle Button Customization

In EaSynth look and feel, the toggle button has almost the same look of regular button, except that it has one more customized state: SELECTED. The figure below shows its appearance:

Actually the way to custom the toggle button is almost the same with that for the regular button, except that we need to replace the painter method value from "buttonBackground" to "toggleButtonBackground" and from "buttonBorder" to "toggleButtonBorder". Here is the xml to custom the toggle button:

<!-- The style for toggle button. -->
<style id="Toggle Button">
<insets top="4" left="6" bottom="4" right="6"/>
<!-- Use the same border painter with regular button -->
<painter idref="EaSynthPainter" method="toggleButtonBorder"/>
<!-- This property will specify the arc with of the round border -->
<defaultsProperty key="EaSynth.button.arc.width" type="integer" value="9"/>
<!-- This property will specify the arc height of the round border -->
<defaultsProperty key="EaSynth.button.arc.height" type="integer" value="9"/>
<defaultsProperty key="EaSynth.button.border.color.enabled" type="idref" value="Button_Border_Color_Enabled"/>
<defaultsProperty key="EaSynth.button.border.color.mouseover" type="idref" value="Button_Border_Color_MouseOver"/>
<defaultsProperty key="EaSynth.button.border.color.pressed" type="idref" value="Button_Border_Color_Pressed"/>
<defaultsProperty key="EaSynth.button.border.color.disabled" type="idref" value="Button_Border_Color_Disabled"/>
<defaultsProperty key="EaSynth.button.border.color.default.enabled" type="idref" value="Button_Border_Color_Default_Enabled"/>
<defaultsProperty key="EaSynth.button.border.color.default.mouseover" type="idref" value="Button_Border_Color_Default_MouseOver"/>
<defaultsProperty key="EaSynth.button.border.color.default.pressed" type="idref" value="Button_Border_Color_Default_Pressed"/>
<defaultsProperty key="EaSynth.button.border.color.default.disabled" type="idref" value="Button_Border_Color_Default_Disabled"/>
<state value="ENABLED">
<imagePainter method="toggleButtonBackground" path="resource/1204727000093_button_enabled.png" sourceInsets="5 5 5 5" paintCenter="true" stretch="true" center="false"/> </state>
<state value="MOUSE_OVER">
<imagePainter method="toggleButtonBackground" path="resource/1204727022828_button_mouseover.png" sourceInsets="5 5 5 5" paintCenter="true" stretch="true" center="false"/>
</state>
<state value="PRESSED">
<imagePainter method="toggleButtonBackground" path="resource/1204727039640_button_pressed.png" sourceInsets="5 5 5 5" paintCenter="true" stretch="true" center="false"/>
</state>
<state value="DISABLED">
<imagePainter method="toggleButtonBackground" path="resource/1204727048156_button_disabled.png" sourceInsets="5 5 5 5" paintCenter="true" stretch="true" center="false"/>
</state>
<state value="SELECTED">
<imagePainter method="toggleButtonBackground" path="resource/1204808843937_button_selected.png" sourceInsets="5 5 5 5" paintCenter="true" stretch="true" center="false"/>
</state>
</style>
<bind style="Toggle Button" type="region" key="ToggleButton" />

We can see that the open properties that supported by regular button are also used here, and the configuration of these properties are completely the same, so that the toggle button will have the same look with the regular button, besides that it will have one more stable state: SELECTED.

Making the toggle button looks like a regular button is only a decision of EaSynth look and feel, when we custom the look and feel, we can have our own decision. We can replace the images, specify the insets, change border colors, and we can even use another painter object to obtain a brand new look for the toggle button.

Reference Resource

EaSynth Look And Feel Homepage: http://www.easynth.com/freewares/EaSynthLookAndFeel.html

Synth Look and Feel Introduction from SUN: http://java.sun.com/docs/books/tutorial/uiswing/lookandfeel/synth.html

Synth Look and Feel wiki: http://en.wikipedia.org/wiki/Synth_Look_and_Feel

Synth Look and Feel Javadoc: http://java.sun.com/javase/6/docs/api/javax/swing/plaf/synth/package-summary.html

Synth XML File Format: http://java.sun.com/javase/6/docs/api/javax/swing/plaf/synth/doc-files/synthFileFormat.html

Synth Component Specific Properties: http://java.sun.com/javase/6/docs/api/javax/swing/plaf/synth/doc-files/componentProperties.html

Synth Painter Javadoc: http://java.sun.com/javase/6/docs/api/javax/swing/plaf/synth/SynthPainter.html

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}