Skip to main content

Pack and Deliver Synth Based Look And Feel

Posted by xuanyun on February 1, 2009 at 2:57 AM PST

If you want to deliver your Synth based look and feel, packaging it as a jar
file will be a good idea. There are different structures for different look
and feel packages, here I will introduce the one from EaSynth
look and feel

To ease the usage of the new look and feel, it is better to create a new look
and feel class, which is extended from javax.swing.plaf.synth.SynthLookAndFeel.
The new look and feel class will load the XML file to initialize Synth look
and feel in its constructor, so the XML file is transparent to the end users.
Here is the example from EaSynth look and feel:

public class EaSynthLookAndFeel extends SynthLookAndFeel {
   public EaSynthLookAndFeel() {
   try {
   load(getClass().getResourceAsStream("easynth.xml"), getClass());
   } catch (Exception e) {

The XML file "easynth.xml" will be placed at the same directory of
the class, so that its content can be read as input stream and loaded into Synth
look and feel.

Some java
objects may be embedded
in the XML file, they are encoded as XML snippets
for storage. These XML snippets should be restored to java objects when in use,
so their java classes should be present in the class paths. If the object classes
are not included in JRE, you must remember to pack them into the jar file.

Also there will be a lot of image files, which are used by image painters defined
in XML, those images should also be packed. In EaSynth look and feel, there
is a sub directory named "resource", which is placed in the same directory
with the XML file. We put all images files into the "resource" directory,
and use relative path in the XML file:

<imageIcon id="Arrow_Up_Enabled" path="resource/1204972099671_arrow_up_normal.png"/>
<property key="EaSynth.arrow.up.enabled" type="idref"    value="Arrow_Up_Enabled"/>

You may also need to put some information in the "MANIFEST.MF" file,
such as the license info, copyright info, version info etc.

Here is the whole structure of EaSynth
look and feel package


Packing the look and feel jar manually is kind of complex, what's more, you
may need to repeat most steps of the process when you need to deliver a new
version. Writing an ANT script for that may be helpful, but not flexible enough.
Look And Feel Designer
provides a visual form to do all the jobs:


Related Topics >>


Thank you so much for posting the EaSynth look and feel. I have downloaded it and tried it. Now I have something to study as the basis of designing my own look and feel. I was just trying things blindly and having only partial success. This will help greatly.

Hi yilile, we met this issue before, and I think there are workarounds but no perfect solution for that. Once user invoke setUI() on a component, he means to implement the UI by himself, and paint anything as he expected. From Synth L&F aspect, this case is out of control, what we can do is to make the L&F more robust, to avoid the NPE. For example, you can put the missing objects into the UIManager, via defaultsProperties, to avoid the NPE.

NPE while using Third Party Tree component

Can you please tell me how to take care of the NPE problem when we are using third party component like Quest JCTreeTable.

Caused by: java.lang.NullPointerException
at com.klg.jclass.util.treetable.TreeTableSupport.inferLookAndFeel(Unknown Source)
at com.klg.jclass.util.treetable.TreeTableSupport.(Unknown Source)
at com.klg.jclass.util.treetable.TreeTableSupport.(Unknown Source)

Hi nmganesh

Hi nmganesh, I am not familiar with the Quest JCTreeTable component, so I could not give you the final solution. 

However, this kind of issues are usually caused by the lack of some objects in the UIManager.  Since the default Metal look and feel will put some objects into the UIManager, and some of the objects may be accessed by the third party component.  To solve this, you need to find out what objects are missing, and create those objects and put them into the UIManager.  Of course removing the code to access these objects are also an approach.

Hi Xuan Yun, I have an exception problem about integrating synth to the real client application. I wonder if you have any idea about it. For example, if the client application has a subclass of BasicTreeUI then use tree.setUI() to this UI. When I debug stepping into this line, installDefaults() within installUI() method of BasicTreeUI will call installDefaults() within BasicTreeUI instead of installDefaults() within SynthTreeUI, so null exception will occur. If we don't set this customized UI, exception won't occur since intallDefaults within SynthTreeUI is called instead. Do you know any way to handle this situation to make sure the proper method in Synth UI will be picked up? Thanks!