THIS PAGE IS PRINTED FROM www.revasoft.com |
UI Engine |
In addition to the half objects there is the real widget, which often already exists and needs to be adapted to be used for ULC. The development of a ULC extension is demonstrated based on PieChart widget, which is shown in the following figure. ![]() Implementing a new ULC widget requires the following steps:
The real widget and the UI half must be implemented in Java. It is assumed that the reader is familiar with developing Java user interfaces. The faceless half must be implemented for each language supported by ULC (Smalltalk and Java). Note: All the strings that are used as tags/keys in the ULC protocol between UI and faceless half must contain 8-bit characters (16-bit Unicode is only supported for data and not for the internal ULC protocol). Implementing the widget
The pie chart widget was implemented from scratch and is called PieChart. A PieChart supports setting the values to be shown, their names, and colors. Clicking on a pie segment sends an action with the name of the clicked segment as an argument. For simplicity PieChart is not implemented as a model-based widget. Implementing a model-based widget would require implementing a corresponding half object which accesses and tracks changes of a model object. Implementing the UI half
The UI half objects of an extension to the base ULC widgets can be placed in one or more separate packages. It is important to follow the rules described below (i.e. provide a typeString method that returns the fully qualified class name). Do not modify the existing ULC Java packages! In this example the package is called com.ibm.ulc.examples.pieExtension. Note: Inside VAJava the project that contains this extension must be added to the Project path of the UI class before starting the UIEngine. Outside VAJava the extensions must be placed on the classpath of the UIEngine. The simplest way of doing this is to export the extension to the UIEngine/lib directory. When the UI Engine needs to instantiate an object it uses the following rules:
Note: In this case The association of the two half objects is based on the name of the widget. The convention is to use the UI prefix for the UI half object (UIPieChart) and the ULC prefix for the faceless half (ULCPieChart). The ULC protocol uses the base widget name (PieChart) to identify the widget if the typeString method is not implemented in the ULCPieChart class. Each UI half object must initialize its state from the faceless half. In addition, the PieChart offers the following API:
UIPieChart descends from com.ibm.ulc.UIComponent. UIPieChart adapts PieChart so that it can be used by the UI Engine. To do so, it keeps a reference to the PieChart widget. Here is an excerpt from the class definition of UIPieChart:
public class UIPieChart extends UIComponent implements ActionListener { To restore its state from the faceless half object UIPieChart overrides restoreState.
public void restoreState(ORBConnection conn, Anything args) { A call to the inherited restoreState method restores the inherited state. The PieChart widget is created and initialized with the restored state. The ORBConnection argument isn't used in this example and is just passed on to the base class. The communication of data between the UI Engine and the faceless widgets is based on data objects called Anythings. An Anything is a dynamic data structure which can be transferred between processes. The method restoreState receives an Anything as its argument and uses Anything accessor methods to retrieve the individual arguments. Anythings can either contain a simple data type or arrays and dictionaries of Anythings. To retrieve the arguments requires that the faceless and the UI half objects agree on how they package their arguments into an Anything. In this case the Anything is a dictionary and restoreState retrieves the arguments by name. For example, args.get("w") retrieves the width argument of the pie chart. In the same way the method setData restores the pie chart's data from the Anything and passes it on to the PieChart widget. Since UIPieChart wants to inform the faceless widget when a pie segment is clicked it implements the ActionListener interface. It also registers itself as an action listener of PieChart. Requests sent from the faceless object are dispatched to handleRequest. This method receives the name of the request together with its arguments packaged as an Anything. UIPieChart implements only a single request named setData to set the pie chart's data:
public void handleRequest(ORBConnection conn, String request, Anything args){ The method handleRequest uses the method setData to extract the data from the Anything and install it into the PieChart. Invoking the inherited handleRequest allows the base classes to handle its requests. UIPieChart needs to send an event to the faceless widget when the user clicks a pie segment. To do so it implements the ActionListener method actionPerformed and calls sendEventULC to send the event. public void actionPerformed(ActionEvent e) { SendEventULC takes the name of the event, its type name, and an argument. The event's argument is wrapped into an Anything. In this case it is a simple string which corresponds to the label of the clicked pie segment. Implementing the faceless half
The above example has shown how to handle requests and send events in the UI half. This section describes how to implement the faceless half of the PieChart. Since the PieChart widget needs to be usable from both Java and Smalltalk there are implementations for both languages. Implementing the faceless half in Java
The Java half of PieChart is defined in the class ULCPieChart. In contrast to the UIPieChart you can define the ULCPieChart in a package of your choice. The ULC implementation uses the convention prefixing faceless widgets with the prefix ULC. Internally, when the faceless widget wants to create its UI counterpart it passes the type name of the widget to be created to the UI Engine. By default the type name corresponds to the class name without the ULC prefix. If desired, this default can be changed by overriding the method typeString defined in ULCProxy. The faceless half objects have to retain the state of the corresponding UI half. To do so ULCPieChart stores the values, labels, and colors of the pie chart widget in its instance variables.
public class ULCPieChart extends ULCComponent { The ULCPieChart needs to tell the UI the location of its proxy class. This is done by implementing the typeString method that returns the fully qualified class path. public String typeString() { The ULCPieChart has to implement the UI Engine requests symmetrically. First it needs to transfer the widget state to the UI engine. This is done by overriding saveState to fill the arguments kept in its instance variables into an Anything.
public void saveState(Anything a) { The setData request is implemented in the following ULCPieChart method.
public void setData(String[] labels, double[] values, String[] colors) { A request method only needs to package its arguments into an Anything. In this case the arrays with the values, labels, and colors are wrapped into the Anything structure which is expected by the UI half. Then, the request is sent to the UI with sendUI,which transmits the request name and the Anything argument to the UI Engine. The last step is to handle action events from the UI pie chart. To handle requests you override handleRequest. This method receives the name of the request together with an Anything that stores the request data. public void andleRequest(ORBConnection conn, String request, Anything args) { These are steps to be implemented in handleRequest:
Implementing the faceless half in Smalltalk
The Smalltalk implementation of ULCPieChart is conceptually identical to the Java one. The saveState: method packs the widget data into the Smalltalk version of Anythings.
saveState: aUlcAnything Below is the implementation of the setData request:
setData: aValuesCollection colors: aColorsCollection labels: aLabelsCollection In Smalltalk the type name used to request the creation of UI half objects is defined by overriding the method typeString.
typeString In the case of ULCPieChart you simply return the fully qualified class path to the UI proxy. |
The End |