Component Writer's Guide


The Architecture of Components

Xelfi Components

    The Xelfi components are java classes that, in addition, implement some functionality to support development of applications which use them. 
    Please note that there is no direct connection between the "Xelfi component" term and the java Component class (except that most Xelfi components are java Component subclasses). 
    The "design" functionality of components: 
    • implement properties - getting property count, names of properties, setting and getting property values.
    • supply component icon - to show component in the ComponentPalette - the icon should be 24x24 (4-bit) image.
    • move and resize component in design time by mouse.
    The xelfi components consist of 2 parts: 
    • the functional part - the component itself - the class that provides the runtime functionality of the component (e.g. the AWT Button class for a Button component) - this (and only this) class will be used in the final (generated) java source code.
    • the design part which implements the "design" functionality - this will be used during xelfi design-time only.
    To implement this, following architecture is proposed: 
      The functional part is implemented as normal java class without worrying about xelfi. 
      The design part is implemented as addition to the functional class by writing the functional class's subclass which implements a XelfiDesignComponent interface (or one of its descendants - XelfiVisualComponent, XelfiVisualContainer

    XelfiDesignComponent interface

      This is the interface that should be implemented by non-visual components (e.g. Timer). Other components implement its descendants. 

      There are these methods: 
        generateCode(int) 
        generateEventCondition(int) 
        getClassName() 
        getEvent(int) 
        getEventCount() 
        getEventNames() 
        getIcon() 
        getName() 
        getParentForm() 
        getProperty(int) 
        getPropertyCount() 
        getPropertyNames() 
        getPropertyString(int) 
        getPropertyValueNames(int) 
        getPropertyValueValues(int) 
        getPropertyViewerType(int) 
        getSelection() 
        loadFromStream(DataInput) 
        neededImports() 
        parentUpdate() 
        saveToStream(DataOutput) 
        setEvent(int, String) 
        setName(String) 
        setParentForm(XelfiDesignForm) 
        setProperty(int, Object) 
        setSelection(int) 
        specialPropertyInput(Frame, int) 

    XelfiVisualComponent interface

      This interface extends interface XelfiDesignComponent. It should be implemented by visual components which are not containers. 

      In addition in this interface are these methods: 
        getPosition() 
        getSize() 
        handleEvent(Event) 
        setPosition(int, int) 
        setSize(int, int) 

    XelfiVisualContainer interface

      This interface extends interface XelfiVisualComponent. It should be implemented by visual components which are also containers, that is they are descendants of AWT class Container. 

      In addition in this interface are these methods: 
        getDesignLayout() 
        getSubComponents() 
        setDesignLayout(XelfiDesignLayout) 

Non-visual Components

    Non-visual components implement interface XelfiDesignComponent

    They have only one special property - string Name -which is accessed by methods getName(), setName(). 

Visual Components

    Visual components can be of 2 types: 
    • non-container components - these are components that cannot contain other components - they should implement interface XelfiVisualComponent - They have these special properties (in add. to the Name): Position (ClientX, ClientY properties) and Size (Width, Height properties).
    • container components - these are components that act (also) as containers - they should be descendants of java Container class and should implement interface XelfiVisualContainer - They add one more special property (in addition to that of XelfiVisualComponent) - LayoutManager - this is property of type XelfiDesignLayout (which is interface for layout managers that can be used during design-time)

    AWT Components

      These are components that are already implemented (by AWT). So, only the design part should be necessary to implement. But, the problem is that it is not possible (in JDK 1.02) to intercept mouse events for AWT components. So we decided to insert all AWT components into special panel, which is called XAWTPanel and this panel has special area for dragging the component. 

User Components

    The Xelfi system has a support for "user" components - i.e. the user can create completely new component and use it in Xelfi just as the "stock" components. 

    When user writes new component, he must write two classes: 
    • the component class itself - this is the functional part of the component - it is completely independent from Xelfi - just regular java class (for visual components subclass of java Component class)
    • the design class - this is subclass of the component class, and it implements one of the design interfaces: 
    By implementing the methods from xelfi design interfaces, user specifies properties of the component (with methods getPropertyCount, getPropertyNames) and their connection to the component class' functionality (with methods get/setProperty). 

    For easier implementing we create XAWTPanel which has implemented common part of methods of XelfiVisualComponent. So you can use it and implement just the rest of methods which dependend on each component. 

The Component's Icon

    The component's icon is used in ComponentPalette and for non-visual components as their "visual" representation on a Form. 

The Property Types

Special Input Dialog

    SpecialInput dialog is a dialog for setting complicated property types (as Font, Color, ...). It is invoked by clicking on a small button in ComponentInspector (or a double-click on property in CI). 

    The user, who wants to implement his own SpecialInput dialog, must do two things: 
    • write the dialog itself (a modal dialog)
    • write a new extension to Thread class, which (in the run() method) starts the dialog and then waits in an "infinite" loop for some variable of the dialog to be set. This must be done in JDK 1.02 because of a bug which does not allow the show() method of the modal dialog to block calling thread, instead it returns immediately. The new thread must be created just because it is not possible to block AWT thread (which is likely the one from which the dialog will be called - from method action(), ..) by calling an infinite loop in it.


    • This thread must also call a setProperty method on given component with given proprty index and value set in the dialog. 
    For all common AWT types the SpecialInput dialog will be already implemented and you can find it in package xelfi.design.components.properties

Property Type Classes

    These are classes in package xelfi.core.design.property. They are not necessary, but could be helpful, so as they encapsulate the "behaviour" of a property type - when the user writes new component he does not have to care about how to invoke (and what) specialInput Dialog or how to translate to String known property types (however, if the property type is some "new" type (e.g. some new class) then the user must care) 

    They support one of (or both) methods: 
    public static void invokeSpecialInput(Frame parent, XelfiDesignComponent xdc, int propNum);
    public static String viewString(Object property);
    The invokeSpecialInput method invokes apropriate SpecialInput dialog on given property of given component. The parent parameter is a parent of the dialog. 

    The viewString method translates given property value (which should be of the same type as the type described by this class) to textual representation which can be shown in ComponentInspector. 

    The reason why the methods are static is clear - their functionality depends only on the class in which they are defined - so, the user does not have to make instances of a Property Type classes, instead he (or she???) calls it statically (e.g. XFontPropertyType.viewString(...)). 

    For more information see the programming documentation.