home
products
education
support
partners
company

introduction

get started

articles

manual

tutorials

reference docs

case studies

knowledge base

goodies

screenshots

demos

echoes

Carousel zone


SourceForge.net Logo

home

forums

downloads

bugs

mailing list
XUI Zone - articles

number of ratings 0
average rating 0.00

Adding Components

27-June-2005

XUI has always been extensible. Users had considerable flexibility in terms of adding new components and changing the was in which XML was used to generate the components. However some Java coding was required and having to create and register a component factory was perhaps a bigger step than some would have liked.

XUI 2.0 extends the component registry introduced in XUI 1.0.4. To complement this registry we now have an interactive editor for building the registry files. So, using this editor you can rapidly add additional components to XUI.

Using the registry editor

The Integrated Component Registry Editor is a new feature in XUI 2.0 The component registry editor can be accessed by clicking the ‘*’ button in the component palette toolbar. Almost all of Carousel’s non-core components are added via this registry so you can see how the properties of the indvidual components are configured. The editor assumes that the components are held in Jar files and are represented as Java Beans. Upon opening the editor you may add or delete Jar libraries.


The editor then scans the Jar for suitable components and displays a hierarchical view of the available components. It is important to note that the editor does not automatically include and of the components or any of the component properties. It is up to you to tell the editor what to use.

The component properties are shown as an individual component is selected. You may rename the components so as to give a tag that is suitable for use in an XML file. Then you can choose which methods to use as properties of an individual tag. Normally only the setter methods are used in the XML but you may also use the getter methods.

The methods may also be configured to be visible in various modes: Mode Usage Novice A minimal set of properties for new users Normal A set of properties for normal everyday use Expert A fuller set of properties for detail component configuration. Component configuration modes The idea of these modes is that reducing the number of visible properties makes it easier to locate commonly used properties. Fewer options may also make it easier for a novice to make use of the component.

Once the component and its properties have been chosen the editor generates a new components.xml file for the application. The component palette is also updated and the components can be used in the application.

The registry file for each project also acts as an overlay for the built-in registry files. Both the XuiEditor and Carousel include registry files for their own components. These registry files are loaded as the first page is loaded after startup of the project. Each project has its own configuration file so that its configuration is independant of other projects even though it loads data from the shared sources of built-in registry files.

Carousel itself uses the registry for loading files and therefore an individual application may uses components registered via several configuration files. Carousel and the XuiEditor each register files, while the application itself may add another. However, for the most part you need not worry about these details as they are all catered for by the buil-in regsitry editor.

Once the components have been registered they should then appear in the updated components palette and should be usable within the form editor:


Some of Java.net's SwingX components in action following registration in XUI.

Extra Components:

Swing and SwingX components.
In XUI 2.0 we plan to include a registration of most of the Swing components that are not wrapped by the existing XUI component set. In addition we hope to add registration of the SwingLabs SwingX components. The SwingX components can be downloaded and tried with Beta 2 of XUI 2.0. The screenshot above shows a very quick attempt at using these components. Check this page for further updates and demos as XUI 2.0 reaches its full release.

Carousel components
Carousel also provides wrappers for some of the extra Swing components and adds a few more. Carousel includes wrappers for JMF for audio and video playback, various text animations, manipulations, flowed text (flowed around other components and regions) and so on.

 
 Text flowed around components

 

Build your own components

To demonstrate how easy it is to include a new component in Carousel we have included the source for a test component in the XuiEditor source distribution at test.xoetrope.components.TestShape. The component doesn’t do very much except paint a few trivial shapes. Here’s the source code

Listing 1 - TestShape.java
package test.xoetrope.components;

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;

import net.xoetrope.xui.XAttributedComponent;


/**
 * Draws a simple shape
 * Copyright: Copyright Xoetrope Ltd. (c) 2001-2005
 * License: see license.txt
 * $Revision: 1.1 $
 */
public class TestShape extends JComponent implements XAttributedComponent
{
  protected int shape = 0;

  public static final int RECTANGLE = 0;
  public static final int ORTHO_LINE = 1;
  public static final int EXTRABOLD_HORIZONTAL = 2;
  public static final int BOLD_HORIZONTAL = 3;
  public static final int NORMAL_HORIZONTAL = 4;
  public static final int THIN_HORIZONTAL = 5;
  public static final int EXTRABOLD_VERTICAL = 6;
  public static final int BOLD_VERTICAL = 7;
  public static final int NORMAL_VERTICAL = 8;
  public static final int THIN_VERTICAL = 9;
  public static final int RIGHT_TOP_LINE = 10;
  public static final int LEFT_TOP_LINE = 11;
  public static final int ELLIPSE = 12;
  public static final int SOLID_ELLIPSE = 13;
  public static final int SOLID_DIAMOND = 14;
  public static final int DIAMOND = 15;

  /**
   * Constructor for a new XShape
   */
  public TestShape()
  {
  }

  /**
   * Fills the shape with the background color
   * @param g the graphics context
   */
  public void paintComponent( Graphics g )
  {
    super.paintComponent( g );

    Dimension d = getSize();

    g.setColor( getForeground());

    switch( shape ) {
      case RECTANGLE:
        g.fillRect( 0, 0, d.width, d.height );
        break;
      case ORTHO_LINE:
        g.fillRect( 0, 0, getSize().width, getSize().height );
        break;

      case EXTRABOLD_HORIZONTAL:
        g.drawLine( 0, 0 +3, d.width, 3 );
      case BOLD_HORIZONTAL:
        g.drawLine( 0, 0 +2, d.width, 2 );
      case NORMAL_HORIZONTAL:
        g.drawLine( 0, 0 +1, d.width, 1 );
      case THIN_HORIZONTAL:
        g.drawLine( 0, 0, d.width, 0 );
        break;

      case EXTRABOLD_VERTICAL:
        g.drawLine( 3, 0, 3, d.height );
      case BOLD_VERTICAL:
        g.drawLine( 2, 0, 2, d.height );
      case NORMAL_VERTICAL:
        g.drawLine( 1, 0, 1, d.height );
      case THIN_VERTICAL:
        g.drawLine( 0, 0, 0, d.height );
        break;

      case RIGHT_TOP_LINE:
        g.drawLine( d.width, 0, 0, d.height );
        break;
      case LEFT_TOP_LINE:
        g.drawLine( 0, 0, d.width, d.height );
        break;

      case ELLIPSE:
        g.drawOval( 0, 0, d.width, d.height );
        break;
      case SOLID_ELLIPSE:
        g.fillOval( 0, 0, d.width, d.height );
        break;

      case SOLID_DIAMOND:
      case DIAMOND:
        {
          int[] xpts = new int[ 4 ];
          int[] ypts = new int[ 4 ];
          xpts[ 0 ] = 0 + d.width / 2;
          xpts[ 1 ] = 0 + d.width;
          xpts[ 2 ] = 0 + d.width / 2;
          xpts[ 3 ] = 0;
          ypts[ 0 ] = 0;
          ypts[ 1 ] = 0 + d.height / 2;
          ypts[ 2 ] = 0 + d.height;
          ypts[ 3 ] = 0 + d.height / 2;
          if ( shape == SOLID_DIAMOND )
            g.fillPolygon( xpts, ypts, 4 );
          else
            g.drawPolygon( xpts, ypts, 4 );
        }
        break;
    }
  }

  /**
   * Get shape identifier. The ID is an enumerated constant
   * @param shapeId the new shape ID.
   */
  public void setShape( int shapeId )
  {
    shape = shapeId;
    repaint();
  }

  /**
   * Get shape identifier.
   * @return the enumerated constant for this shape
   */
  public int getShape()
  {
    return shape;
  }

  /**
    * Set one or more attributes of the component. Currently this handles the
    * attributes:
    *
    * shape, value=1 to 15
    * 
    * @param attribName the attribute name
    * @param attribValue the attribute value
    */
   public void setAttribute( String attribName, String attribValue )
   {
     if ( attribName.compareTo( "shape" ) == 0 )
       shape = new Integer( attribValue ).intValue();

     repaint( 100 );
   }
}

There isn’t an awful lot to say about this component as it does so little and the details of the painting are unimportant. What is important though is the interface it offers for programming within Carousel.

The component paints a shape which is dictated by the shape property. This property has a getter and a setter method (getShape and setShape).

The component also implements the XAttributedComponent method to assist the setting up of the component via XML. The setAttribute method required by this interface sets the value of an attribute, in this case the ‘shape’ attribute.

If we then build this component into a Jar file for redistribution it can be used within Carousel. Using the component registry editor we can add the file and select the Shape property for inclusion. This process generates the following XML:

Listing 2 - components.xml
 
    
       
    

    
        
            
        
    
 

comments


If you were logged in you could rate this article or add a comment.