Substance look and feel - watermarks

Overview

Substance provides watermark painting capabilities on relevant UI components. The watermark is painted over the background and under the child components. The watermark is painted on panels, toolbars, menus, menu items and some other UI components. The basic runtime archive comes with ten watermarks.

Substance allows changing watermark at runtime, providing a function that retrieves information on all available watermarks. In addition, Substance uses plugin mechanism to automatically discover additional watermarks at runtime.

Watermark

A watermark must implement org.jvnet.substance.watermark.SubstanceWatermark interface. This interface defines the following methods:

  /**
   * Draws the watermark on the specified graphics context in the specified
   * region.
   
   @param graphics
   *            Graphics context.
   @param c
   *            Component that is painted.
   @param x
   *            Left X of the region.
   @param y
   *            Top Y of the region.
   @param width
   *            Region width.
   @param height
   *            Region height.
   */
  public void drawWatermarkImage(Graphics graphics, Component c, int x,
      int y, int width, int height);

  /**
   * Updates the current watermark image.
   
   @return <code>true</code> if the watermark has been updated
   *         successfully, <code>false</code> otherwise.
   */
  public boolean updateWatermarkImage();

  /*
   * (non-Javadoc)
   
   * @see org.jvnet.substance.utils.SubstanceTrait#getDisplayName()
   */
  public String getDisplayName();

  /**
   * Returns indication whether <code>this</code> watermark depends on the
   * current {@link org.jvnet.substance.theme.SubstanceTheme}.
   
   @return <code>true</code> if <code>this</code> watermark depends on
   *         the current {@link org.jvnet.substance.theme.SubstanceTheme},
   *         <code>false</code> otherwise.
   */
  public boolean isDependingOnTheme();

  /**
   * Draws the preview of the watermark image.
   
   @param g
   *            Graphic context.
   @param x
   *            the <i>x</i> coordinate of the watermark to be drawn.
   @param y
   *            The <i>y</i> coordinate of the watermark to be drawn.
   @param width
   *            The width of the watermark to be drawn.
   @param height
   *            The height of the watermark to be drawn.
   */
  public void previewWatermark(Graphics g, int x, int y, int width, int height);

  /**
   * Disposes the memory associated with <code>this</code> watermark.
   */
  public void dispose();

These functions (except the getDisplayName) are used at runtime to paint watermarks on the corresponding components.

Substance provides the following seventeen watermarks:

Regular watermarks:
Stripes Binary Bubbles Crosshatch Katakana Latch Metal Wall Mosaic

The Null watermark draws translucent fill:
Mosaic

The None watermark draws nothing:
Mosaic

Noise-based watermarks:
Copperplate Engraving Fabric Magnetic Field Marble Vein Maze Plankton Wood

Image-based watermarks

The last watermark is image-based. Its fully-qualified classname is org.jvnet.substance.watermark.SubstanceImageWatermark. In case you wish to use the image-based watermark, you must specify a substancelaf.watermark.image VM flag that points to the desired background image. The background image can be either remote (in case the VM flag value starts with http) or local. Here are examples of image-based watermarks:

Image Beyonce Image Terry Image Angelina Image Dominic

The SubstanceConstants.ImageWatermarkKind enum defines the following kinds of image watermark: In order to set the image watermark kind use An example of APP_TILE image watermark kind:



The default opacity of the image watermark is 0.2 and can be changed by An example of default opacity (0.2) and custom opacity (0.6):

Using watermarks

There are three options for using watermarks in Substance look and feel. The available core watermarks are located in org.jvnet.substance.watermark package. The STRIPES watermark is the default. If you do not use the below options, the STRIPES watermark will be used. In order to change the current watermark, you can
  1. Call SubstanceLookAndFeel.setCurrentWatermark() with one of the above watermarks, for example SubstanceLookAndFeel.setCurrentWatermark(new SubstanceKatakanaWatermark())
  2. Call SubstanceLookAndFeel.setCurrentWatermark() with the fully qualified name of one of the above watermarks, for example SubstanceLookAndFeel.setCurrentWatermark("org.jvnet.substance.watermark.SubstanceKatakanaWatermark")
  3. Set substancelaf.watermark parameter of the VM, for example -Dsubstancelaf.watermark=org.jvnet.substance.watermark.SubstanceKatakanaWatermark
If you use one of the first two options after your application has started, don't forget to repaint your root components.

Providing custom watermarks

Substance provides an option for specifying custom watermark. This option uses the Substance plugin mechanism that discovers the additional watermarks at runtime (this approach is taken by Substance itself and by the Substance watermark pack subproject). As with all Substance plugins, you must pack an additional XML configuration file in one of your runtime jarfiles. The name of this file must be substance-plugin.xml and it must comply with the following syntax:
<laf-plugin>
   additional optional tags
   <watermark-plugin-class>...</watermark-plugin-class>
   additional optional tags
</laf-plugin>
The contents of watermark-plugin-class tag must be the fully-qualified class name of a class that implements the SubstanceWatermarkPlugin interface. This interface specifies a single function:
  public Set<WatermarkInfo> getWatermarks();
The WatermarkInfo class contains information on a single (base or custom) watermark. Its single constructor gets the following two parameters: In addition, this class provides the setDefault function that can mark a watermark as default.

In case you provide a class that implements the SubstanceWatermarkPlugin interface, you can use the setDefault function of a WatermarkInfo class to specify your own default watermark. In case you specify none, STRIPES will be taken.

Note that using this option you may override the watermarks supplied with Substance base package (by specifying the same display name). This behaviour, however, is not guaranteed to be consistent across various VMs and class loaders, since the watermark plugins are processed in random order.

Retrieving information on watermarks