Laf-Plugin - support for third-party components in look-and-feel libraries
The goal of this project is to provide a generic plugin framework for look-and-feels and
define the interface of a common kind of plugins - the component plugins.
Look-and-feels that use this library
In addition, the following LAFs have expressed their wish to use laf-plugin
in the respective next versions:
Introduction
The main LookAndFeel class instantiates and queries ComponentPluginManager to get the details of
third-party UI components. The constructor of PluginManager gets the XML descriptor name.
The plugin class LafComponentPlugin contains a number of functions:
- initialize and uninitalize - should be called by the main LookAndFeel
class on initialization and unitialization.
- getDefaults - returns collection of all settings for custom components.
Can also return settings for core Swing components, effectively overriding the settings of the LAF
This way, the base look-and-feel library has no dependencies on third-party components,
and can have as many plugins as you wish. Plugin writer must comply with the settings of
the particular look-and-feel for XML name and XML tag names. In addition, she must
implement the LafComponentPlugin interface with the above functions.
If you are a provider of custom component, you will need to provide the following for each LAF:
- XML descriptor.
- Class that implements LafComponentPlugin interface.
- UI delegate for each custom component.
Using this library in your look-and-feel
The laf-plugin.jar library (in Documents & Files section)
contains the runtime classes. You can use the following simple Ant task to
put the laf-plugin classes in your main LAF runtime library:
<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>
The ComponentPluginManager class provides utility functions for working with the plugins.
Here is a sample implementation of a look-and-feel that uses these functions.
- Defining a plugin manager in your main LAF class:
/**
* Plugin manager for component plugins.
*/
protected static ComponentPluginManager componentPlugins;
Here the ComponentPluginManager is defined as static in order to allow static
functions to access it. You can also define ComponentPluginManager as an instance member.
- Initializing the plugin manager in the LAF constructor:
componentPlugins = new ComponentPluginManager(PLUGIN_XML);
PLUGIN_XML is the string name of the LAF-specific XML configuration file.
- Helper function to initialize all plugins is
/**
* Helper function to initialize all available plugins of <code>this</code>
* plugin manager. Calls the {@link LafComponentPlugin#initialize()} of all available
* plugins.
*/
public void initializeAll()
Sample usage of this function:
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.basic.BasicLookAndFeel#initialize()
*/
public void initialize() {
super.initialize();
// initialize this LAF
// ...
// initialize component plugins
componentPlugins.initializeAll();
}
- Helper function to uninitialize all plugins is
/**
* Helper function to uninitialize all available plugins of <code>this</code>
* plugin manager. Calls the {@link LafComponentPlugin#uninitialize()} of all available
* plugins.
*/
public void uninitializeAll()
Sample usage of this function:
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.basic.BasicLookAndFeel#uninitialize()
*/
public void uninitialize() {
super.uninitialize();
// uninitialize this LAF
// ...
// uninitialize component plugins
componentPlugins.uninitializeAll();
}
- Helper function to set plugin defaults is
/**
* Helper function to process the (possibly) theme-dependent default
* settings of all available plugins of <code>this</code> plugin manager.
* Calls the {@link LafComponentPlugin#getDefaults(Object)} of all available plugins and
* puts the respective results in the specified table.
*
* @param table
* The table that will be updated with the (possibly)
* theme-dependent default settings of all available plugins.
* @param themeInfo
* LAF-specific information on the current theme.
*/
public void processAllDefaultsEntries(UIDefaults table, Object themeInfo)
Recommended usage of this function is in the implementation of getDefaults
of your LAF:
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.metal.MetalLookAndFeel#getDefaults()
*/
@Override
public UIDefaults getDefaults() {
UIDefaults table = super.getDefaults();
componentPlugins.processAllDefaultsEntries(table, currentTheme);
return table;
}
where currentTheme contains LAF-specific information on the current theme.
Developers
- Erik Vickroy - Liquid LAF
- Kirill Grouchnikov - Substance LAF
Additional thanks to Patrick Gotthardt of PgsLookAndFeel, Robert Beeger
of Squareness and Frederic Lavigne of Skin for valuable suggestions on the proposed approach.
License
The license for this project is BSD. However, this project uses third-party
NanoXML Lite XML parser for time
and memory efficiency. The license
for NanoXML Lite is very much like BSD. In case you wish to obtain fully-BSD
version of laf-plugin, you are welcome to open an issue and specify
whether you wish to use DOM or SAX parser.