Work in progress : more to come soon! Please feel free to add/amend/and so on!

Components/Capabilities in Wonderland#

What's a component as opposed to a simple module?#

This blog post describes what a Capability is. Please note that capabilities and Components are synonymous in Wonderland. Here is an explanation from Nicole in the forum:
[...] I just wanted to clarify the terminology. We use the term "capability" in the user interface. 
For example, when you examine an object's properties, you'll see the list of capabilities applied 
to that object and you can click on the "+" to add new capabilities such as tooltips, clickable links, 
and so forth. From the programmer's perspective, I think mainly for historic reasons, capabilities are 
referred to as "components." At some point we changed the terminology in the UI to make the concept 
easier for users to understand, but the corresponding change was not made to the code, hence two names 
for the same thing.

Some more on Components and how to write your own here.

And here is Nicole explaining Components in a video.

How do a CellComponent and a Cell compare?#

The source code#

We will be using the source code for the Tooltip component, created by Jordan Slott, that can be found in the unstable folder of the wonderland-modules project. link

Jordan also wrote a post in Wonderblog describing the use of the tooltip component.

First look at the code : this is just me (jos) having a first read of the code and taking notes... feedback welcome!

The Java code is distributed in packages as per the following screen shot:

The packages#

TODO: General intro

Server package#

The Managed object in this component extends CellComponentMO as opossed to CellMO.

CellComponentMO is formed by:

    protected ManagedReference<CellMO> cellRef;
    protected CellID cellID;
    /* True if the component is live, false if not */
    private boolean isLive = false;

The component itself is written as a normal MO, with two properties here:

    // The tooltip text
    private String text = null;

    // The timeout (in milliseconds) to hide the tooltip even if the mouse has
    // not moved. If -1 then no timeout.
    private int timeout = -1;

And the usual 4 methods to override (note that the return types are components too):

    protected String getClientClass();
    public CellComponentClientState getClientState(
            CellComponentClientState state, WonderlandClientID clientID,
            ClientCapabilities capabilities);
    public CellComponentServerState getServerState(
            CellComponentServerState state);
    public void setServerState(CellComponentServerState state);
The component can be set Live by using the method in the parent setLive(boolean live).

Common package#

Component Server State

The only difference with a module server state is that TooltipCellComponentServerState extends CellComponentServerState. Same code that for a module, using JAXB for XML mapping and annotating the class with @ServerState, and completed with getters and setters:

    // The text of the tooltip
    @XmlElement(name = "text")
    private String text = null;

    // The timeout (in milliseconds) to hide the tooltip...
    @XmlElement(name = "timeout")
    private int timeout = -1;

    public String getServerComponentClassName() {
        return "org.jdesktop.wonderland.modules.tooltip.server.TooltipCellComponentMO";

Component Client State

The client state is written as usual in modules, with the exception that TooltipCellComponentClientState extends CellComponentClientState:

    // The text of the tooltip
    private String text;

    // The timeout (in milliseconds) to hide the tooltip even if the mouse has
    // not moved. If -1 then no timeout.
    private int timeout = -1;

Completed with setters and getters for each of the attributes.

Client package#

and resources

Classes needed:

The Plugin

- a Plugin to register the component: --> annotation @Plugin

In showTooltipHUDComponent it creates the HUDComponent which in this case is a small JPanel with a JLabel (plain Swing), and hides it after a timeout. This is called from commitEvent, within the TooltipHoverListener class registered as a listener of the SceneManager.getSceneManager().addSceneListener(listener); in plugin's initialize/activate method.

The private inner class TooltipHoverListener is listener for the scene manager hover event, and it might be a more difficult to understand? It is actually business logic specific, not a part of a ComponentCell but part of what this particular example does.

The Cell Component Class

- a Cell component class (the Cell in this module): extends CellComponent as all components should do (from the code: CellComponents provide dynamic extensions to the Cell infrastructure). A CellComponent has two attributes, a Cell object and a CellStatus object.

TooltipCellComponent Overrides setClientState as in a normal Cell extension, and defines getters for the particular attributes defined, in this case a text field and a timeout to hide the tooltip.

The Factory

- a Cell Component Factory --> annotation @CellComponentFactory

It also implements CellComponentFactorySPI, and provides a display name and a description for the objects editor:

    public String getDisplayName() {
        return BUNDLE.getString("Tooltip_Cell_Component");

    public String getDescription() {
        return BUNDLE.getString("Tooltip_Cell_Component_Description");

When instantiated, it returns a new Component Server State, as normal modules would do:

    public <T extends CellComponentServerState> T getDefaultCellComponentServerState() {
        TooltipCellComponentServerState state = new TooltipCellComponentServerState();
        return (T) state;

The GUI bits

There are two Swing classes (JPanels) that have been created with Netbeans (can be viewed as source code in any other IDE). One is the properties panel that appears in the object editor inworld, and the other one is the tooltip itself.

The Cell Component Properties Panel

- a Cell component properties JPanel that is integrated with the object editor, and it is used to input the text for the tooltip. It implements PropertiesFactorySPI and it is annotated as follows:


Attributes are:

    // The editor window
    private CellPropertiesEditor editor = null;

    // The original value for the tooltip text, before any editing
    private String originalText = null;

    // The original value for the tooltip timeout, -1 if there is no timeout
    private int originalTimeout = -1; 
The layout is a bit more complex than that, with two panels nested, but it is plain Swing. It does a lot more stuff with the 'dirty' state of the tooltip that I haven't had a look yet, but it all seems to be Swing listeners and state synchronisation.

What is CellPropertiesEditor? also check the methods open, apply and restore.

The Tooltip

- a HUDComponent which is the tooltip itself and it's created from the file which is just a JPanel with a JLabel.

    private javax.swing.JLabel tooltipLabel;


    public void setText(String text) {

Add new attachment

Only authorized users are allowed to upload new attachments.

List of attachments

Kind Attachment Name Size Version Date Modified Author Change note
add_tooltip_component.png 45.1 kB 1 29-Jan-2012 17:04 Josmas Flores
cell_cellcomponent.png 10.2 kB 1 18-Jan-2012 16:20 Josmas Flores
client_package.png 10.0 kB 1 26-Jan-2011 17:24 Josmas Flores Client package shot
common_package.png 13.3 kB 1 26-Jan-2011 17:24 Josmas Flores common package shot
package_distribution.png 7.4 kB 1 12-Jan-2011 17:28 Josmas Flores package_distribution shot
server_package.png 15.1 kB 1 26-Jan-2011 17:24 Josmas Flores server package shot
« This page (revision-19) was last changed on 21-Sep-2015 12:13 by Abhishek Upadhyay