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,
Matrix inspired Katakana, Bubbles,
Mosaic, Binary,
Latch, Metal Wall,
Office 12 inspired Crosshatch, Null
and None.
- Noise-based watermarks: Copperplate Engraving,
Fabric, Magnetic
Field, Marble Vein, Maze,
Plankton and Wood
- Image-based watermark.
Regular watermarks:
The Null watermark draws translucent fill:
The None watermark draws nothing:
Noise-based watermarks:
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:
The SubstanceConstants.ImageWatermarkKind enum defines the following kinds of image watermark:
- SCREEN_CENTER_SCALE - the default behaviour. The image is centered
in the screen and scaled down if necessary.
- SCREEN_TILE - the image is tiled starting from the screen top-left corner
and not scaled.
- APP_ANCHOR - the image is anchored to the top-left corner of the
application frame and not scaled.
- APP_CENTER - the image is anchored to the center of the
application frame and not scaled.
- APP_TILE - the image is tiled starting from the top-left corner of the
application frame and not scaled.
In order to set the image watermark kind use
- SubstanceLookAndFeel.setImageWatermarkKind(ImageWatermarkKind)
- -Dsubstancelaf.watermark.image.kind VM property. The value
should match the name of one of the SubstanceConstants.ImageWatermarkKind
enum values.
An example of APP_TILE image watermark kind:
The default opacity of the image watermark is 0.2 and can be changed by
- SubstanceLookAndFeel.setImageWatermarkOpacity(float).
The value should be a float in 0.0-1.0 range.
- -Dsubstancelaf.watermark.image.opacity VM property. The value
should be a float in 0.0-1.0 range.
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
- Call SubstanceLookAndFeel.setCurrentWatermark() with one of the
above watermarks, for example SubstanceLookAndFeel.setCurrentWatermark(new
SubstanceKatakanaWatermark())
- Call SubstanceLookAndFeel.setCurrentWatermark() with the fully
qualified name of one of the above watermarks, for example
SubstanceLookAndFeel.setCurrentWatermark("org.jvnet.substance.watermark.SubstanceKatakanaWatermark")
- 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:
- String watermark display name
- String watermark class name
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
- Use SubstanceLookAndFeel.getCurrentWatermarkName() to retrieve
the display name of the current watermark.
- Use SubstanceLookAndFeel.getCurrentWatermark() to retrieve
the current watermark - returns SubstanceWatermark object.
- Use SubstanceLookAndFeel.getAllWatermarks() to
retrieve information on all available watermarks - returns map from watermark display name
(String) to watermark information object (WatermarkInfo above).