GUI Commands 2.0 has arrived! Find out what's new and improved.
Command Faces

All commands allow the various attachments (buttons and menus) to be created with different appearances (faces).  The following XML fragment shows a different face for the menus of a particular command.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE commands SYSTEM "commands.dtd">
<commands version="1.1.0">
   <command id="my.command">
      <action-command>my-command</action-command>
      <face>
         <text>My _Command</text>
      </face>
      <face name="menu">
         <text>My _Command on a Menu!</text>
      </face>
    </command>
</commands>

The "menu" face is special in that all commands know about it and will use it by default for all the menus they create. There are a number of faces defined and automatically used by commands, these are "button", "menu", "toolbar", "popup" and "html". It is also possible to define faces with any name you desire, these can be used by calling the various command factory methods, eg command.createButton(String faceId) . The command also has a default that is used for all faces that aren't explicitly defined. The default face is determined by the following.

  1. If any face has the name "default", it will be used.
  2. If there are no faces with the name "default" then the first face is used.

All commands and groups must contain at least one face. The following sections describe the configuration of the various face properties.

Configuring Text

The text element configures both the text of the face as well as how it appears on buttons and menus. The following attributes are allowed.

  • mnemonic or mnemonic-index
  • horizontal-position
  • vertical-position

The button or menu mnemonic can be specified one of three ways.

  • specifying a character using the mnemonic attribute.
  • specifying the position using the mnemonic index.
  • Using the '_' character in the button text. Thus <text>Save _As</text> would use the second 'a' as the mnemonic.

Please note that prior to release 1.1.33 specifying the mnemonic index would not work unless you also specified the mnemonic. In subsequent releases, the the mneomonic will be ignored if the mnemonic index is specified.

The horizontal and vertical positions control the positioning of the text relative to the icon. The vertical position overrides the horizontal postion. The position options only affect buttons that have icons.

Examples

  • <text>Ok</text>
  • <text>Save _As</text>
  • <text mnemonic="s">Save</text>
  • <text mnemonic-index="5" vertical-position="bottom">Save As</text>

Icons

There are a number of icons available to faces, these all share the same attributes. The icons available are as follows.

  • icon
  • selected-icon
  • pressed-icon
  • rollover-con
  • selected-rollover-icon
  • disabled-icon

Generally only icon and selected-icons are required. The remaining icon types are provided for completness. It must also be noted that not all look and feels will support all icons on all buttons and menus.

The type attribute of icons specifies the way inwhich the icon will be loaded. The available options are file, url, classpath, bean and factory.

Examples

The icon will be loaded from the specified file.

<icon type="file">/home/andrewp/icons/my-icon.png</icon>

Load the icon from a URL.

<icon type="url">http://my-server/images/my-icon.png</icon>

Load the icon using the ClassLoader.getResource(...) method. The exact class loader used can be controlled using CommandManager.setClassLoader().

<icon type="classpath">images/my-icon.png</icon>

Use a Bean as the icon. You must specifiy fully qualified name of a class that implements javax.swing.Icon. The class must have a public no-arg constructor

<icon type="bean">org.pietschy.icons.IconBean</icon>

Use a factory to create a Icon. The factory must be specified by the fully qualified class name and the factory method separated by '#'. The factory method must be a public static no-arg method of the factory class.

<icon type="factory">org.pietschy.icons.IconFactory#createBlueIcon</icon>

Accelerators

Accelerators are used to configure menu items created by the face and can be specified one of two ways.

  1. Using the key attribute and specifing 0 or more modifiers (such as control and alt).
  2. Using the keyStroke attribute to specify a keystoke string compatible with KeyStroke.getKeyStroke(String).

Examples using key

Please note that the useDefaultModifier attribute is provided to allow one line definitions of accelerators that use Toolkit.getDefaultToolkit().getMenuShortcutKeyMask().

The following creates an accelerator using the Insert key.

<accelerator key="insert"/>

The following creates an accelerator using the default shortcut modifier for the platform, this is usually control.

<accelerator key="s" useDefaultModifier="true"/>

The following example creates an accelerator that uses the Alt-F1 key stroke.

<accelerator key="f1">
   <modifier value="alt"/>
</accelerator>

The following example creates an accelerator for Ctrl-Shift-Insert .

<accelerator key="insert">
   <modifier value="shift"/>
   <modifier value="control"/>
</accelerator>
   

Examples using keyStroke

The following creates an accelerator using the Control Insert. Not that the INSERT is capitalized to work correctly with KeyStroke.getKeyStroke(String). A runtime exception will be thrown if the specified string doesn't produce a non null KeyStroke.

<accelerator keyStroke="control INSERT"/>

The following creates an accelerator using the keyStroke definition from a resource bundle.

<accelerator keyStroke="i18n:accelerator"/>

Descriptions

There are two description elements for faces, description and long-description. Of the two, the description element is used directly by the library to generate tooltips. The long description is only used to set Action.LONG_DESCRIPTION on Action adapters created by the command. Possible alternative uses of the long-description are covered further in Hovering.

There are two special strings recognised by the decription elements, these are @text and @accelerator. If either of these are present in the content of a description, they will be replaced with the appropriate values as described below.

  • @text - replaced with text value of the face.
  • @accelerater - replaced with a textural representation of the face accelerator.

Example

<face>
   <text>Bold</text>
   <accelerator key="b" useDefaultModifier="true"/>
   <description>@text (@accelerator)</description>
</face>

The tooltip from the above face will be renderer as "Bold (Ctrl+B)".

Controlling Tooltips on Menus

By default, tooltips are disabled for menus and menu items. The behaviour can be changed:

  • Gobaly by calling CommandManager.setMenuTooltipsEnabled
  • On a per face level by specifying the menu-tooltips attribute to either enabled or disabled
  • On a per face level by calling setMenuTooltipsEnabled on the face.

Example

<face menu-tooltips="enabled">
   <text>Tooltip Text</text>
   <description>You will see this tooltip on menus</description>
</face>

The above face will display tooltips on menus regardless of the global configuration set by the CommandManager.

Using HTML

Displaying HTML on buttons and menus is as simple as wrapping the attributes with html tags. The main issue when using HTML is that swing will not automatically render the alternate states of the button. This is particularly noticable for selected and disabled menu items.

You must use CDATA elements when specifying HTML within a face configuration, as the following example shows.

Example

<face>   
   <text>
      <![CDATA[<html>Some <b>HTML</b></html>]]>
   </text>
   <description>
      <![CDATA[<html>More <u>HTML</u></html>]]>
   </description>
</face>

Extending other Faces

One of the nicer features of the libary is that faces can extend other faces. This allows you to define a base face (usually the default) and then derive other faces that add or remove properties. This is achieved by defining the extends attribute of the face.

The syntax for value of the extends attribute is <command-id> [<face-name>]. If the command id is ommitted, the named face from the current command will be extended.

Example

  • <face extends="my-other-command[menu]"> - Extends the 'menu' face of 'my-other-command'.
  • <face extends="[default]"> - Extends the default face of the same command.

Derived faces may choose to add, remove or override attributes of the extended face. To add a new attriubute or override an existing ones you simple define the attribute in the normal manner. To remove an existing attribute you must specify it with an empty tag, eg <text/>.

The following example taken from the GUI Commands Demo application defines a different face for buttons, menus and toolbars. The menu face adds an icon to the default face. The toolbar face extends menu and clears the text content.

Example

   <command id="toggle-page.toggle-bold">
      <face>
         <text>Bold</text>
         <accelerator key="b" useDefaultModifier="true"/>
         <description>@text (@accelerator)</description>
         <long-description>
            Toggles the @text status of text.  Activate using @accelerator
         </long-description>
      </face>
      <face name="menu" extends="[default]">
         <icon type="classpath">toolbarButtonGraphics/text/Bold16.gif</icon>
      </face>
      <face name="toolbar" extends="[menu]">
         <text/>
      </face>
   </command>

Defining Global Faces

Global faces allows you define faces that are not bound to any particular command. This feature is intended for defining faces like "Ok", "Close" and "Cancel" that may be used multiple times within your application.

Global faces are no different from regular faces except that they are defined within a <face-defs> element as opposed to commands or groups. Global faces are extended in the same manner as other faces except that the command-id is replaced with the face-def-id.

Examples

   <face-defs>
   
      <face-def id="global-ok">
         <face>
            <text>Ok</text>
         </face>
      </face-def>

      <face-def id="global-cancel">
         <face>
            <text mnemonic="c">Cancel</text>
         </face>
      </face-def>
            
   <face-defs>
Then using these faces in other commands is as simple as the following:
   <command id="ok-command">
      <face extends="global-ok[default]"/>
   </command>