Proposal for uniform support of third-party components in custom look-and-feels
Posted by kirillcool on November 28, 2005 at 4:21 PM EST
In the recent years, Java Swing market has seen a surge in custom components that aim to provide UI widgets common in desktop applications yet missing from JDK. These components include date picker, task pane, tree table and many more. Among others, you can find those at SwingX and at JideSoft. The main problem with these components is the support of custom (third-party) look-and-feels. The general mechanism employed in Swing is to declare a UI delegate ID string in a component class, say ToggleButtonUI and have UIManager contain an entry with this key. The entry value is a fully-qualified class name of the UI delegate, say javax.swing.plaf.metal.MetalToggleButtonUI. The look-and-feel class (either system or custom) specifies such pairs for all supported components. But what happens with third-party components that are not bundled with JDK?
Here the water gets a little murky. First, the component writer should follow the same guidelines that are used in core components, allowing specifying the UI delegate in the application code. But more important is another question - how does the look-and-feel know that you have additional components with pluggable UI delegates?
Unless you have access to the look-and-feel code, you have to update the UIManager from the outside code. This can either be some initialization function supplied with the components that you are using, or the direct manipulation of UIManager tables from your own code. And things get more complicated when you want to switch look-and-feel at runtime.
The Laf-Plugin project proposes an approach that shares the responsibility between the look-and-feel and the component writers. The approach borrows ideas from the plugin mechanisms developed in the last years, where the main library looks up the configuration files in the classpath, and the plugin writers follow the conventions dictated by the main library to specify additional behaviour.
The main LookAndFeel class calls PluginManager to get the details of third-party UI components. The constructor of PluginManager gets three parameters:
- the XML descriptor name
- the main tag name (may be it's not needed really, but serves as a fault-protection mechanism)
- the name of the tag that contains the fully-qualified class name of the plugin class.
- initialize and reset - should be called by the main LookAndFeel class on initialization and theme switch.
- getUiDelegates - returns a collection of all UI delegates for custom components. Can also return UI delegate for core Swing component, effectively overriding the UI delegate of the LAF
- getFonts - returns font settings for custom components. The same as above - can override core settings for core Swing components
- getDefaults - returns other settings for custom components. Same as above.
- XML descriptor.
- Class that implements LafPlugin interface.
- UI delegate for each custom component.
<target name="jar-bin" description="create runtime jar">
<delete file="${substance.drop.dir}/substance.jar" />
<unjar src="${substance.drop.dir}/laf-plugin.jar" dest="${substance.output.dir}/"/>
<jar compress="true" destfile="${substance.drop.dir}/substance.jar"
manifest="${substance.src.dir}/META-INF/MANIFEST.MF">
<fileset dir="${substance.output.dir}/" excludes="test/**" />
<fileset dir="${module.substance.basedir}/" includes="resources/**" />
</jar>
</target>
This project was developed over the last month by Erik Vickroy and myself and has been successfully integrated into Substance and Liquid look-and-feels. Two examples of Substance plugins are the plugin for NetBeans components and the plugin for Ribbon components. The code itself is 1.4-compliant.Update: the owners of Squareness and Pgs LAFs have expressed their design to adopt the proposed approach in the next versions of the respective libraries.
Related Topics >>
Blog Links >>
- Login or register to post comments
- Printer-friendly version
- kirillcool's blog
- 641 reads





