Download the JDK
Search the Tutorials
Hide the TOC
Trail: Creating a GUI with JFC/Swing
Lesson: Modifying the Look and Feel
Section: The Synth Look and Feel
Modifying the Look and Feel
How to Set the Look and Feel
The Synth Look and Feel
A Synth Example
Home Page > Creating a GUI with JFC/Swing > Modifying the Look and Feel
A Synth Example

> In the lesson titled A GroupLayout Example , `GroupLayout` was used to create a search dialog box called "Find." The program that created the dialog box, `Find.java`, used the cross platform ("Metal") look and feel with the "Ocean" theme:

> This lesson creates the same dialog box with Synth, using an external XML file. Here is the listing of the ``SynthDialog.java``file.

> `SynthDialog.java` is exactly the same as `Find.java` except for the `initLookAndFeel()` method, which has been altered to use the Synth look and feel with an external file called `synthDemo.xml`. Here is the new `initLookAndFeel()` method:

> >     private static void initLookAndFeel() {
> >        SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();

> >        // SynthLookAndFeel load() method throws a checked exception
> >        // (java.text.ParseException) so it must be handled
> >        try {
> >           lookAndFeel.load(SynthDialog.class.getResourceAsStream("synthDemo.xml"),
> >                                                                    SynthDialog.class);
> >           UIManager.setLookAndFeel(lookAndFeel);
> >        }

> >        catch (ParseException e) {
> >           System.err.println("Couldn't get specified look and feel ("
> >                                        + lookAndFeel
> >                                         + "), for some reason.");
> >           System.err.println("Using the default look and feel.");
> >           e.printStackTrace();
> >        }
> >     }

> ### The XML File

> The XML file, `synthDemo.xml`, begins with a style bound to all regions. It is good practice to do this to ensure that regions without a style bound to them will contain something. This style makes all regions paint their background in an opaque color. It also sets a default font and default colors.

> >       <!-- Style that all regions will use -->
> >       <style id="backingStyle">
> >         <!-- Make all the regions opaque-->
> >         <opaque value="TRUE"/>
> >         <font name="Dialog" size="14"/>
> >         <state>
> >           <color value="#D8D987" type="BACKGROUND"/>
> >           <color value="RED" type="FOREGROUND"/>
> >         </state>
> >       </style>
> >       <bind style="backingStyle" type="region" key=".*"/>

> > Notes:

> > 1. The color definitions must be inside a <state> element. This permits changing colors depending on state. The <state> element in `backingStyle` has no attributes and is therefore applied to all regions, irrespective of their state. If a region has other states, the states are merged with precedence given to state definitions that appear later in the file.

> > 2. The font definition is not inside a <state> element because the font should not change when there is a change of state (many components are sized depending on their font, and a change in font could cause components to change in size unintentionally).

> The next <style> element defined is for the text field, which is painted using an image.

> >       <style id="textfield">
> >         <insets top="4" left="6" bottom="4" right="6"/>
> >         <state>
> >            <font name="Verdana" size="14"/>
> >            <color value="#D2DFF2" type="BACKGROUND"/>
> >            <color value="#000000" type="TEXT_FOREGROUND"/>
> >         </state>
> >         <imagePainter method="textFieldBorder" path="images/textfield.png"
> >                       sourceInsets="4 6 4 6" paintCenter="false"/>
> >       </style>
> >       <bind style="textfield" type="region" key="TextField"/>

> > Notes:

> > 1. The font and color definitions override the definitions in `backingStyle`.

> > 2. The `insets` and `sourceInsets` are given the same values, which is just a coincidence because they are unrelated to each other.

> > 3. The BACKGROUND color, #D2DFF2, is a pale blue—the same color as the background in the image, `textfield.png`.

> > 4. `paintCenter` is `false` so that you can see the background color.

> The next <style> element is for buttons that are painted with different images, depending on the button state. When the mouse passes over the button, its appearance changes. When it is clicked (PRESSED) the image changes again.

> >      <style id="button">
> >       	<!-- Shift the text one pixel when pressed -->
> >         <property key="Button.textShiftOffset" type="integer" value="1"/>
> >         <!-- set size of buttons -->
> >         <insets top="15" left="20" bottom="15" right="20"/>
> >         <state>
> >           <imagePainter method="buttonBackground" path="images/button.png"
> >                                sourceInsets="10 10 10 10" />
> >           <font name="Dialog" size="16"/>
> >           <color type="TEXT_FOREGROUND" value="#FFFFFF"/>
> >         </state>

> >         <state value="PRESSED">
> >           <imagePainter method="buttonBackground"
> >               path="images/button_press.png"
> >                        sourceInsets="10 10 10 10" />
> >         </state>

> >         <state value="MOUSE_OVER">
> >           <imagePainter method="buttonBackground"
> >               path="images/button_over.png"
> >                      sourceInsets="10 10 10 10" />
> >         </state>
> >       </style>
> >       <bind style="button" type="region" key="Button"/>

> > Notes:

> > 1. The font and color definitions inside the <state> element without attributes apply to all button states. This is because the definitions of all states that apply (and the <state> element without attributes is one of these) will merge and there are no other font and color definitions that might take precedence.

> > 2. The `sourceInsets` values are large enough that the curved corners of the button image will not be stretched.

> > 3. The order of the `PRESSED` and `MOUSE_OVER` states is important. Since the mouse will always be over the button when it is pressed, both states will apply to a pressed button and the first state defined (`PRESSED`) will apply. When the mouse is over the button but it is not pressed, only the `MOUSE_OVER` state applies. If the order of the `PRESSED` and `MOUSE_OVER` states is reversed, the `PRESSED` state image will never be used.

> The next <style> element is for checkboxes that are painted with different icons, depending on the checkbox state.

> >       <style id="checkbox">
> >         <imageIcon id="check_off" path="images/checkbox_off.png"/>
> >         <imageIcon id="check_on" path="images/checkbox_on.png"/>
> >         <property key="CheckBox.icon" value="check_off"/>
> >         <state value="SELECTED">
> >           <property key="CheckBox.icon" value="check_on"/>
> >         </state>
> >       </style>
> >       <bind style="checkbox" type="region" key="Checkbox"/>

> > Notes:

> > 1. You must use the <imageIcon> element to define any icons to be used.

> > 2. The <insets> element and the `sourceInsets` attribute are not used with icons because they are rendered in their fixed size and are not stretched.

> > 3. The icon used to render the checkbox is the icon named in the `CheckBox.icon` property. (see `javax/swing/plaf/synth/doc-files/componentProperties.html`), which is the icon with id="check_off" unless the checkbox state is `SELECTED`.

> The `synthDemo.xml` file is constructed of the styles presented above, wrapped in <synth></synth> tags. You can open the completed file by clicking ``synthDemo.xml``.

> > Try this: Click the Launch button to run the SynthDialog example using Java™ Web Start (download JDK 6). Alternatively, to compile and run the example yourself, consult the example index.

Previous page: The Synth Look and Feel
Next page: Drag and Drop and Data Transfer