Project Home Page

# 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

- Substance from version 2.1.
- Liquid from version 2.9.
- Squareness from version 2.1.0 - see this entry.
- PgsLookAndFeel from version 0.5.
- Skin from version 6.7.

In addition, the following LAFs have expressed their wish to use laf-plugin in the respective next versions:

- JGoogies Looks around 09-10/2006.

### 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:

1. XML descriptor.
2. Class that implements LafComponentPlugin interface.
3. 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.