Skip to main content

skip to main content

developerWorks  >  Rational  >

Using the graphical user interface features of Rational Business Developer Extension for migrated Informix 4GL applications

developerWorks
Document options

Document options requiring JavaScript are not displayed

Sample code


Rate this page

Help us improve this content


Level: Intermediate

Greg Dietrich (gdietric@us.ibm.com), EGL development, IBM
Arlan L Finestead (jarlanf@us.ibm.com), EGL development, IBM

20 Nov 2007

Learn how you can use the GUI in IBM® Rational® Business Developer Extension Version 7.0 and later to migrate Enterprise Generation Language (EGL) console user interface (CUI) IBM® Informix® 4GL applications into the EGL environment. This article covers only the GUI controls available to CUI developers and the rich client platform (RCP) for running and deploying CUI GUI applications as RCP applications.

Since the release of IBM® Rational® Business Developer Extension Version 7.0 in 2007, there is functionality that enables Enterprise Generation Language (EGL) console user interface (CUI) applications to use a more modern graphical user interface (GUI). Although the CUI GUI is appropriate for all EGL application developers, this article focuses on the migration of IBM Informix 4GL applications into the EGL environment, the GUI controls that are now available to CUI developers, and the rich client platform (RCP) environment for running and deploying CUI GUI applications as RCP applications.

IBM Informix 4GL

We begin by very briefly describing the interactive features of IBM Informix 4GL (hereafter referred to as I4GL). This is a mature, fourth-generation language that is commonly used to write applications for the Informix database products. It was introduced in the 1980s and has been improved along with the database technology over the years. Recently, EGL has been further developed by IBM as a more modern platform for such applications. It includes a module that duplicates the features of I4GL and support for conversion of existing I4GL programs into EGL. The aim is that I4GL users can very easily run their existing applications, while also having a path to the newer technologies that are now available or on the horizon.

Note:
If you already familiar with I4GL, you can skip the following section.

User interface features of I4GL

  • Window: An I4GL window is a rectangular portion of the display that can contain text and various interface elements. Many windows can exist, and they can overlap each other. Windows may be created with or without borders The I4GL program can rearrange the stacking order of the windows. You always interact with the topmost (active) window (see Figure 1).

Figure 1. I4GL Windows
I4GL Windows screen capture

  • Displaying text: Various commands exist in I4GL to display text, with attributes such as color and highlighting.
  • Prompt: An I4GL prompt command presents a message to the user, who then enters a response (Figure 2a).

Figure 2a. I4GL Prompt
 I4GL Prompt screen capture

  • Menu: I4GL provides a ring menu system, inspired by the likes of IBM® Lotus® 123. A list of options is presented on one line in the active window (Figure 2b). You can page through the options if there are more than will fit on a single line. An option can be selected by moving the selection to the desired item and clicking Enter or by typing the first letters of the name of the option until the letters uniquely match one of the available options, at which point the option is incorporated.

Figure 2b. I4GL Menu
I4GL Menu
  • Form: An I4GL form is defined in a text file with the extension .per. It includes a section that has the static content of the text in the display, along with the specification of attributes of fields defined in the form. It specifies which fields are grouped into screen records and screen arrays (described here later), and other information. The form definition file is compiled into a binary file with a .frm extension that can be loaded and used in the I4GL application.
  • Screen record: A screen record is the designation of a set of fields for a simple input form, where you fill out the fields the make up a data record. You can define various kinds of formatting and input validation in the form definition for individual fields to provide meaningful behavior (also see Figure 3):
    SCREEN RECORD sr_person (FORMONLY.id THRU FORMONLY.info)
    


Figure 3. I4GL Form – Screen Record
I4GL Form – Screen Record

  • Screen array: A screen array in I4GL is a scrolling table of data. It can work either in a read-only mode for displaying a set of data or in an editing mode, where data can be updated, inserted, or deleted. The I4GL programmer writes code to populate the screen array with data and to perform necessary actions as the data is edited (also see Figure 4):
    SCREEN RECORD sa_children[3] (FORMONLY.child_fname THRU FORMONLY.child_gender )
    


Figure 4. I4GL Form – Screen Array
I4GL Form – Screen Array

  • Event handling: Each type of command has a set of events defined for which the I4GL programmer can write code (a handler) to take action when the associated conditions are encountered in the running program. Examples are a command initializing or terminating, selecting a menu option, moving the cursor from one field to another, inserting or deleting a screen array row, and so on.
  • Help: I4GL provides a context-sensitive Help feature. The various commands can be associated with an entry in a message file that you can call upon while the command runs. The Help text appears in the display so that you can page through it, and when you close it, the application returns to where you it was before. The Help text is defined in a plain text message (.msg) file, which is compiled into a binary .iem file that the application uses (Figure 5):
    OPTIONS HELP FILE "demo.iem" INPUT vid FROM sr_id.* HELP 6
    


Figure 5. I4GL Help Message Display
I4GL Help Message Display

I4GL platforms

I4GL runs on various UNIX® platforms. It is not supported on Microsoft® Windows®, because it is strictly character-based and uses the curses library to manage the display.

As for database access, I4GL is translated into Informix Embedded Structured Query Language for C (ESQL/C), which ultimately becomes a C language program compiled into a native binary executable.

I4GL also provides an interpretive runner for its intermediate code, as well as a rudimentary interactive debugger that works with the intermediate code. The debugger interface is much like an I4GL program.

Example of an I4GL program

As you go through the sequence of tasks here to migrate an application from I4GL to the EGL graphical user interface, you will be working with a small demonstration (demo) application (see Downloads). The application comprises only about 150 lines of code, but it does quite a bit. It includes all of the user interface elements mentioned previously in this article.

It starts with a menu. You can retrieve a (dummy) data record for a person, shown in a form. You can choose to edit the person's data. You can also display and edit the list of "children" data for the person. A prompt is shown as the application exits. Help is available for all of the commands.

I4GL starts with a procedural language base, with typical data types, control flow constructs, a MAIN method, and other functions. To this is added the ability to embed SQL commands and to run interactive commands as described previously. I4GL includes these interactive commands:

  • FGL_GETKEY()
  • DISPLAY .. AT
  • MENU
  • PROMPT
  • INPUT
  • CONSTRUCT
  • DISPLAY ARRAY
  • INPUT ARRAY

When those commands have control, I4GL becomes event-driven. That is, the application runs specific application code in response to the user's actions while interacting with the current command.

A typical I4GL program will present a menu at the top level that represents the tasks that can be performed using the application. As you choose to perform individual tasks by activating the menu options, other commands are run to perform the work or further interact with you. It is also not uncommon to have several layers of nested menus and for one interactive command to invoke another, several levels deeper, for nontrivial applications.

Binding of variables to form fields

The purpose of the interactive commands is to display or edit data, or both, or to give a response. This is accomplished by binding program variables holding the data to the command.

A prompt is given a single variable to hold the user's response that is typed in, as follows:

DEFINE ans CHAR(1)PROMPT "Press a key..." FOR CHAR ans

In the case of a form, each field must be associated with a variable. The INPUT command can get its initial field values from the variables, and, as you edit the form, the variables are updated with the changes that you make:

DEFINE vid INT INPUT vid FROM sr_id.id

A screen array takes an array of records, one record per row in the table:

  DEFINE vchildren ARRAY[20] OF RECORD ... END RECORD
  DISPLAY ARRAY vchildren TO sa_children.*

Attributes

Most commands can be given particular text attributes to use, such as color, boldface, or reverse video:

DISPLAY "Hello, world" AT 5,5 ATTRIBUTE( BLUE, REVERSE )

Event handlers

When certain predefined actions occur in the current command, I4GL code can be run that responds to the event. These event handlers are part of the I4GL command itself. For instance, here is how you would run code when the cursor enters a specific field in a form:

INPUT vid FROM sr_id.id BEFORE FIELD id -- do something
  END INPUT

Screen captures: I4GL


Figure 6. Menu with displayed form
Menu with displayed form


Figure 7. Form with data
Form with data


Figure 8. Screen array command
Screen array command


Figure 9. New window with prompt
New window with prompt

I4GL conversion to EGL console user interface

The first objective is to translate your I4GL program into EGL. This is accomplished using the I4GL to EGL conversion tool supplied with the EGL product. The EGL runtime environment for converted I4GL programs is called the Console User Interface, or CUI.

Our goals for migrating to CUI have been to support as close to 100% of I4GL behavior as possible and to automatically convert as close to 100% of I4GL code, as well. The runtime behavior should be nearly identical from a visual standpoint, as well as being keystroke-compatible.

Although we can't describe the entire I4GL to EGL conversion process in detail in this article, it is documented in the Help section of Rational Business Developer Extension under "Installing and Migrating." For this simple example, all that is necessary, in the IBM® Rational® Application Developer workbench, is to complete these steps:

  1. Select File > New > Other to bring up the New wizard.
  2. Select I4GL to EGL Conversion > I4GL Application Conversion.
  3. Specify a new project where you want to put the converted EGL.
  4. Navigate to the I4GL source files and select them.
  5. Proceed to the end of the wizard, accepting the default settings.

Platforms

If all goes well, you now have a functioning EGL application, and you have already expanded the platforms that it runs on to include these:

  • Various UNIX®, Linux®, IBM® AIX® on character terminals, using curses. This provides a path for those who wish to retain their terminal-based configurations.
  • Windows or UNIX graphical displays. When a graphical display such as Windows or X-windows is available, the runtime uses a Java™ graphics window and paints the display to mimic the appearance and behavior of the legacy I4GL application. In this case, the curses library, if it exists in the environment, is not used at all.

Note:
The same EGL code runs using curses on UNIX or Linux character terminals and graphical displays. At runtime, EGL detects which mode it should run in without requiring any code changes.

Form definitions in EGL

The definition of a form in EGL is different from I4GL. Rather than having a separate source file type with the form definition, the form is declared as a special type of EGL record. Listing 1 shows part of the definition of the form used by the sample application.


Listing 1. Excerpt from the definition of the form used by the sample application
                

Record demoformForm type ConsoleForm 
{
  formSize = [14,41], showBrackets = yes, delimiters = "[]|" 
}

  /* CONSTANT FIELD (Label) */
  * ConsoleField 
{ 
   position = [2,6],
  value = "Person - Screen Record" 
};

  /* INPUT FIELD */
  id ConsoleField 
{
  position = [4,15], fieldLen = 5, dataType = "int",
  comment = "Serial number", validValues = [[1, 4]],
  name="id" 
};
  child_fname ConsoleField[3] 
{
  segments = [[12,14,13], [13,14,13], [14,14,13]],
  dataType = "unicode", name="child_fname" 
};

  /* SCREEN RECORD */
  sr_person Dictionary 
{
  id=id, fname=fname, lname=lname, gender=gender, info=info 
};

  /* SCREEN ARRAY */
  sa_children arrayDictionary 
{
  child_fname=child_fname, child_age=child_age,
  child_gender=child_gender 
};
  end


Although the fields are positioned using numeric coordinates rather than being visually arranged in the .per file as in I4GL, the other attributes translate into the EGL form in a straightforward manner.

The EGL OpenUI statement

Each of the interactive statements mentioned above, with the exception of DISPLAY AT and the FGL_GETKEY() function, translate into a variation of the EGL OpenUI statement.

Although this article cannot go into great detail, Listing 2 is an example of code from the sample I4GL.


Listing 2. Example of code from the sample I4GL
                

  OPEN FORM demoform FROM "demoform"
           DISPLAY FORM demoform
           INPUT vid FROM sr_id.* HELP 5
                 BEFORE FIELD id
                 LET vid = 1
            END INPUT

 


It looks very similar in EGL, as Listing 3 shows.


Listing 3. EGL code
                

registerConsoleForm( "demoform", "demoform");
displayFormByName( "demoform");
OpenUI 
{ 
setInitial=YES, helpMsgKey="5"
}
  activeForm.sr_id
  bind vid
  onEvent(BEFORE_FIELD:"id")
  vid = 1;
  end;

  


The sample program converted to EGL

After conversion, there is still one small housekeeping task to perform. The message file, demo.msg, was changed into a Java properties file called demo.properties under the MessageSource folder in the new EGL project:

MessageSource/en_us/8859-1/demo.properties

Therefore, you need to copy the demo.properties file to the root folder of the JavaSource folder so that it is available to the Java program at runtime. The Java builder then copies it from the source folder into the folder that contains the Java .class files.

Running and debugging your EGL application

At this point, you can generate and run or debug the EGL program as Java, if you wish.

Reading and debugging the generated Java can be difficult. Instead, you can use the EGL debugger to debug the program at the EGL source level. That allows you to set break points and to examine and change values of EGL variables, as you might expect.

There are two differences between I4GL and EGL:

  • EGL code is translated to Java, not to C
  • The database is accessed through Java™ Database Connectivity (JDBC), rather than ESQL/C. As a result, the program can be modified easily to communicate with any of several supported databases.

Screen captures: I4GL and EGL CUI


Figure 10. I4GL Screen Array Command
I4GL Screen Array Command


Figure 11. I4GL EGL CUI Screen Array Command
I4GL EGL CUI Screen Array Command


Figure 12. I4GL New Window with Prompt
I4GL New Window with Prompt


Figure 13. I4GL EGL CUI New Window with Prompt
I4GL EGL CUI New Window with Prompt

Adding graphical features to the EGL console user interface

Now we get to the heart of what this article is about. EGL CUI provides a way to reuse your investment in I4GL application development, while you gain more platform and database independence, as well as a more modern development environment. No one would argue that the user interface is modern or appealing. Nonetheless, it is a faithful reproduction of 1980s I4GL technology.

Those who are interested in moving forward and doing new development in EGL tend to be looking more at web or GUI applications, for obvious reasons. The last two major releases of EGL have Web forms based on Java™Server Pages (JSP) or Java™Server Faces (JSP) technology, but no intrinsic GUI capability.

As the first step in correcting this, the version 7.0 release of EGL introduces a GUI-based runtime for CUI applications.

Goals

  • To run existing EGL CUI applications (no code changes!) with a graphical rather than a text presentation
  • To preserve as much as possible of the interactive behavior of the original I4GL application
  • To allow additional graphical elements (widgets) to be added to CUI forms
  • To provide a platform for additional graphical extensions to CUI in the future

Platform: Eclipse rich client platform

The EGL development environment is based on Eclipse, so it was a natural choice to base our EGL GUI on the Eclipse rich client platform (RCP). Other alternatives exist -- Java's Swing and AWT framework among others -- but RCP won out.

Rich client platform architecture: Pluggable functionality

The Eclipse workbench is the fundamental element of an RCP application. It provides a generic GUI framework -- the application window and support for common GUI elements, such as menus, toolbars, status bars, and so forth -- along with many useful features, such as version management for application components, background task scheduling and management, and others.

Specific application behaviors are added by Eclipse plug-ins that extend the basic workbench functionality.

The widget set used in the RCP user interface is provided by the Eclipse Standard Widget Toolkit, or SWT. This widget set uses native widgets when possible, and SWT applications have excellent look-and-feel compatibility with native applications on the various platforms, plus good performance.

EGL graphical console UI architecture

The EGL GUI runtime provides a set of Eclipse plug-ins that provide an empty application window, based on the RCP workbench. Also included are the usual EGL runtime support components. Basically, this is a blank space that the console application can fit into.

The EGL application is built into another Eclipse plug-in that works together with the EGL GUI runtime plug-ins to complete the puzzle. All of the parts of the EGL user interface are created as SWT widgets that appear in the EGL application window.

Most of the UI constructs of I4GL and CUI map nicely to SWT widgets, as the following figures show.

  • Windows become Canvas objects that can be rearranged, drawn upon, and may contain other widgets

Figure 14. Windows
Windows screen capture

  • Static fields become Label widgets

Figure 15. Static fields
Static fields

  • Entry fields become Text widgets. If a field has multiple segments, it becomes a Text widget that displays more than one line of text.

Figure 16. Entry fields
Entry fields

  • Screen Arrays are made up of a related group of individual fields. This arrangement is kept in the GUI, because it provides the best compatibility with I4GL and CUI.

Figure 17. Screen Array fields
Screen Array fields

There is no straightforward mapping of the I4GL ring menus to an existing widget. Instead, you'll find a set of buttons in the toolbar that can be paged like the I4GL ring menus.


Figure 18. Toolbar with buttons for mapping
Toolbar with buttons for mapping

Running an EGL CUI application as RCP

The first step in running an EGL console UI application as an RCP application is to convert the EGL project containing the console UI application into an EGL plug-in project.

  1. In the EGL perspective, right-click the EGL project in the Project Explorer that you wish to convert, and select the menu option Convert to EGL Plug-inProject.

Figure 19. Converting to an EGL Plug-in Project
Converting to an EGL Plug-in Project

Tip:
If this option does not appear in your pop-up menu, enable this capability by checking the EGL Developer check box in the Capabilities window. This can be displayed by selecting Window > Preferences > General > Capabilities. This step will create the necessary files that are required for RCP development and execution. Specifically, the config.ini, META-INF/MANIFEST.MF, and product.ini files will be created. Additionally, the EGL properties for the project will be modified to reference EGL libraries, such as fda7.jar and jasper.jar from the com.ibm.etools.egl.java.resources plug-in, rather than referencing the Java™ Archive (JAR) files directly.

One important manual step that you will need to perform at this time is to copy any externally reference JAR files into this project.

  1. After copying these JAR files into your newly converted RCP project, open the META-INF/MANIFEST.MF file that was just created, and select the Runtime tab at the bottom of the displayed dialog box (Figure 20).

Figure 20. Runtime Tab for MANIFEST.MF
Runtime Tab for MANIFEST.MF

Click here to view the larger image.


  1. Next, click Add next to the ClassPath panel, browse to your JAR files that you've copied into your project, and click "OK". Your JAR files should now be displayed in the ClassPath pane of the dialog.
  1. After converting the EGL project into an EGL plug-in project, you must re-generate your EGL source files.

Important:
This is a crucial step. It is required because this step creates the necessary RCP "glue" that will bind your generated EGL and Java files to the RCP environment. It also creates a new file at the project level, called "plugin.xml". This file provides the list of applications that may be executed in your RCP project. (More details on the contents and functionality of this file follow.)

All that is left now is to run your newly created application as an RCP application. Executing an EGL program as an RCP application is slightly different from executing it as a Java program.

  1. To execute your application as an RCP application, right-click your main EGL source file (the one that contains the main() function definition), and then select the Run As RCP menu option (Figure 21).

Figure 21. Running the EGL application as RCP
Running the EGL application as RCP

  1. Likewise, you can debug your EGL application using the EGL debugger by selecting the Debug EGL Program as RCP menu option.

Figure 22. Debugging the EGL application as RCP
Debugging the EGL application as RCP

Ways to improve your EGL RCP application

There are several changes that you can make to improve your EGL RCP application, such as changing the font, adding graphic widgets, adding a startup splash screen, and so on. Many of the subsections that follow outline the necessary steps.

Choosing a font

The default font chosen may not be exactly what you want. It is probably a proportional, rather than a fixed-width font, so that text will not align exactly as it did in the original application. In our example, the headers for the screen array illustrate this. Note the alignment of the Name, Age, and Sex labels (Figure 24). The space characters that are present are much narrower than other characters, thus the words are squeezed together in comparison to the fixed-width terminal font (Figure 24).


Figure 23. CUI proportional font
CUI proportional font


Figure 24. I4GL terminal font
I4GL terminal font

Set EGL runtime parameters in the startup properties files (rununit.properties, application.properties, and user.properties). For the graphical CUI, two new properties are supported in these files (also see Figure 25):

  • egl.ConsoleGUI.FontTypeface=Courier New
    

  • egl.ConsoleGUI.FontSize=10
    


Figure 25. CUI fixed-width font
CUI fixed-width font

Using a fixed-width font improves the graphical console UI's appearance, but further adjustments might be necessary. Any font can be used, which can yield interesting results.


Figure 26. Using a Custom Font
Using a Custom Font

Interacting with EGL RCP applications

In general, the application will behave exactly as before. However, there are some things that are a little different:

  • When entering data in console fields, the customary mouse gestures and keystrokes are used to select and edit text. Rational Business Developer Extension does not support the I4GL-style editing keys, such as Control-A, Control-X, and so forth.

This can result in confusion, potentially. For instance, in a text field in Microsoft Windows, Control+C is the keystroke for Copy Text. In UNIX, it is often the keystroke used to generate an INTR signal from a terminal. In EGL, you can redefine the keystroke that is interpreted asINTR to avoid the conflict.

  • You are no longer restricted to keyboard input only. Now, you may use a mouse to select and manipulate form items. For instance clicking in any input field moves the cursor to that field. The AFTER FIELD handler, if any, will run on the field that is being deactivated and the BEFORE FIELD handler for the new field. If the handlers perform actions such as NEXT FIELD someField or EXIT INPUT, those commands continue to work as they did before and may force the cursor to move to a location other than where the mouse click occurred.

If the program is written assuming that the order that fields are visited is restricted to what was possible in I4GL, it is possible that problems could result. In such a case, it is necessary to implement handlers to force the order that fields are visited.

  • Attributes such as color and reverse video are supported for many things, such as displaying text. The default color of a window as set by the program is the color that is used by default for the text in its widgets. However, the attributes of input fields are not changed after the field is created; therefore, displaying text into an input field with attributes will continue to use the attributes in effect, rather than what was specified.

Screen captures: EGL in CUI and RCP mode


Figure 27. I4GL Window with Form and Screen Array
I4GL Window with Form and Screen Array


Figure 28. EGL RCP Window with Form and Screen Array
EGL RCP Window with Form and Screen Array

Click here to view the larger image.


Figure 29. I4GL New Window with Prompt
I4GL New Window with Prompt


Figure 30. EGL RCP New Window with Prompt
EGL RCP New Window with Prompt

Click here to view the larger image.

Adding other widgets to the application

So far, this application is generic CUI. It can be run on UNIX character terminals using curses, on a graphical display using the classic text presentation, or as a true graphical application in RCP -- all without changing a line of code in the EGL application or even generating the Java application again.

We still haven't really improved the repertoire of the CUI runtime, although it is dressed in better clothes at this point. But you probably want ito be able to add more graphical elements other than the text widgets that you now have.

Tip:
We have provided for additional RCP widgets to be used in forms in graphical CUI applications. Using these widgets reduces the application's flexibility, because there is no implementation for them in the classic CUI environment. Therefore, using them will prevent the application from being fully functional in the other environments -- it may run, but those widgets will simply not appear in the program. If you really want to be able to run the program in GUI or text mode, avoid adding things that are not supported in both environments.

The list of widgets is not long yet, but the design of the EGL language and the widget framework makes it easy to add more widgets in the future. The widgets are implemented as external Java™ objects in EGL. Each one has particular attributes and events that can work with the EGL program.

EGL variables are bound to the widgets in the same way as for text fields, and the widgets have events that can be handled in the OpenUI statement very much like existing form events. We go into this in detail later in this article, but the following widget descriptions summarize the behavior of each widget type with regard to data binding and which events they support.

These are the widgets that are available as of this writing (late 2007):

  • ConsoleWidget: This is the basis for all of the following widgets. All CUI widgets will support these properties plus any other attributes that the widget has in addition to the basic ones.
    • Name
    • Bounds int[] (row, column, height, width): A rectangular area in the display containing the widget (kept in units of character positions in the display)
  • ConsoleButton (Figure 31):
    • Text: Label displayed in the button
    • PUSHED: Event handler ID
    • Data binding: None

Figure 31. ConsoleButton
ConsoleButton

  • ConsoleCheckbox (Figure 32):
    • Text: Label displayed with the check box
    • STATE_CHANGED: Event handler ID
    • Data binding: Boolean, numeric or text variable
    • ? Boolean: True means that the check box is selected
    • ? Numeric: Non-zero means selected
    • ? Text: Values such as t, true, y, or yes mean selected

Figure 32. ConsoleCheckbox
ConsoleCheckbox

  • ConsoleRadiogroup (Figure 33): A group of buttons, selected one at a time
    • Items: Array of labels displayed with each button
    • SELECTION_CHANGED: Event handler ID
    • Data binding: Numeric or text variable
    • ? numeric variable: The index 1..N of the selected item
    • ? text variable: The label of the selected item

Figure 33. ConsoleRadiogroup
ConsoleRadiogroup

  • ConsoleList (Figure 34): A list, single or multiple selection
    • Items: Array of labels displayed in the list.
    • multipleSelect: Attribute for a list allowing multiple items to be selected.
    • SELECTION_CHANGED: Event Handler ID.
    • Data binding (single selection): Numeric or text variable.
      1. ? numeric variable: The index 1..N of the selected item.
      2. ? text variable: The label of the selected item.
    • Data binding (multiple selection): Numeric or array variable.
      1. ? numeric: The value is a bit flag for which items are selected; bit zero for the first item, bit 1 for the second, and so forth.
      2. ? Boolean array: Flags for the selection state of each item; the first element is the first item, and so on.
      3. ? numeric array: Each array element is the index of a selected item. The first item's index is 1 (one). If any of the array elements is zero, it is ignored.
      4. ? text array: Each array element is the label of a selected item.

Figure 34. ConsoleList
ConsoleList

  • ConsoleCombo (Figure 35): A drop-down list
    • Items: Array of labels displayed in the combo
    • SELECTION_CHANGED: Event Handler ID
    • Data binding: Numeric or text variable
    • ? numeric variable: The index 1..N of the selected item
    • ? text variable: The label of the selected item

Figure 35. ConsoleCombo
ConsoleCombo

Extensibility

There are many other widgets that could be added to this basic collection. CUI widgets have been designed as EGL external Java objects. This is a powerful and flexible way to add functionality to EGL. As a result, it is possible to create new CUI widgets based on the same principles, and we plan to do so over time.

The widgets that we selected to start with are what we consider the fundamental set that is useful for applications.

Adding widgets to the EGL console form

Using widgets in CUI form is not much different from using existing fields. Let's say that you want to use a ConsoleCombo widget rather than the text field for the person's gender in your application. Because there are a small number (2) of valid values, this is a widget good choice.

All that it requires is for you to change the definition of the gender field in demoformForm.egl from this:


  gender ConsoleField 
{
  position = [5,40], fieldLen = 1, dataType = "unicode",
  caseFormat = upper, initialValue = "M",
  comment = "Gender", validValues = ["M", "F"],
  name="gender" 
};


to this:


  gender ConsoleCombo 
{
  bounds = [5,40,1,3], items = ["M", "F"],
  name="gender" 
};

  

For this example, that is all there is to it! Figures 36 and 37 show the result of running the modified application.


Figure 36. Before
Before screen capture


Figure 37. After
After screen capture

There are a couple of usability benefits of this kind of change . First, it is clear what values are possible. Second, it is impossible for you to enter invalid data into this field. Previously, you could type an x into the field by mistake and receive a validation error message.

Including widgets in the OpenUI statement

The available options for including widgets in the input list of an OpenUI statement are the same as for EGL console fields.

First, they are part of the default Screen Record simply because they are defined in the form, just like console fields. Therefore, this OpenUI statement will include any widgets defined in the form:

OpenUI activeForm...

Also, they can be included in other Screen Records (dictionaries, in EGL), along with console fields. In this example, when you changed Gender from a ConsoleField to a ConsoleCombo, the existing dictionary for the sr_person I4GL Screen Record did not require modification, because the widget name remained the same as the field that it replaced:

SCREEN RECORD sr_person ( ..., FORMONLY.gender, ... };

Also, this OpenUI statement still works as you would expect:

OpenUI activeForm.sr_person ...

Finally, widgets can be specified explicitly on the OpenUI command. For example:

OpenUI activeForm.somefield, activeForm.somewidget, ...

OpenUI binding list

After you have the widget in the list of active form items, you need to supply it with data that it can display and modify. This is called data binding, or just binding.

Each widget type has its own data binding rules, which were detailed previously for each widget. A compatible EGL variable must be placed in the list of variables on the OpenUI statement, in the position corresponding to the order of the form item.

In the case of a widget that does not bind to data, such as a ConsoleButton, there is no corresponding item in the variable list for that widget. It is simply skipped when EGL matches the form items and variables together.

Event handlers

Each widget also has events that the programmer can attach code to, so that when a button is pushed, an item is selected in a list, and so on. The EGL event handlers have been designed to fit naturally into the existing OpenUI statement. Each widget description (previously) also lists the event types for which handlers can be written.

The general syntax of event handlers in EGL is this:

OnEvent( <event type> )
  OnEvent( <event type> : <specifiers> )

For example, existing CUI code might have code similar to this:

  OnEvent( BEFORE_OPENUI )
  OnEvent( ON_KEY : "F1" )
  OnEvent( AFTER_FIELD : "field1", "field2" )

In the case of BEFORE_OPENUI, that stands by itself. But when you are talking about a field or a key, you must specify which field or keys you mean. That is what the specifiers do.

Each widget type defines its own event types in addition to the existing ones, and the specifiers are used to identify, by name, which widget the event came from. For example, if you had two ConsoleButtons, you might see:

 
OnEvent( ConsoleButton.PUSHED : "button1" ) 
//do something 
OnEvent( ConsoleButton.PUSHED : "button2" ) 
// do something else

Here is an example of an OpenUI statement with an event handler for a gender ConsoleCombo widget like you introduced earlier. It simply prints a message any time the value of the widget changes:

  
   OpenUI activeForm.sr_person
  bind vid, vfname, vlname, vgend, vinfo
  OnEvent (ConsoleCombo.SELECTION_CHANGED : "gender")
  ConsoleLib.displayLineMode( "Gender=" :: vgend );
  end;

Interacting with widgets

Widgets are included in the tab order according to their position in the screen record or OpenUI input list, similarly to how fields operate. In the example program, tabbing takes you to first name, last name, gender, and info, in that order (see Figure 38).


Figure 38. Example Form Array
Example Form Array

You can also use your mouse to select and manipulate widgets, of course. Generally speaking, when a widget has focus, it will process keystrokes as that kind of widget customarily does, In some cases, that behavior is unchangeable, so you cannot even define an OnKey event handler to override the widget's behavior.

Focus can be forced to an active widget, as is done for input fields. If the name of a widget is supplied to ConsoleLib.gotoFieldByName( name ), the focus will move to the specified widget.



Back to top


Deploying your console RCP application

Rational Business Developer Extension uses the Eclipse export functionality to deploy an EGL RCP plug-in project as a separate, standalone application. This deployment process copies the RCP plug-ins and EGL RCP project plug-ins into a common application folder. This folder contains everything needed to run the application. A launcher executable file for the current platform will be created that users can use to run the EGL application (a description of multiple platform support follows).

A product configuration file, named projectName.product, defines what constitutes your deployed application. The file contains this information:

  • Which EGL projects and RCP plug-ins are included in the deployed application.
  • The primary application used for the startup process. In EGL V7, this application is named:
    com.ibm.etools.egl.rcp.consoleui.player.ConsoleUI_Player
    

  • A smattering of customizable settings.

A product configuration file is automatically created during the EGL RCP plug-in project creation or conversion.

Configuration editor

To export your EGL RCP plug-in, open the product configuration file in your Rational Business Developer Extension workbench (Figure 39) by double-clicking on it.


Figure 39. Product Configuration Array
Product Configuration Array

The product configuration editor contains four tabs:

  • Overview
  • Configuration
  • Launcher
  • Branding

The Overview tab contains several sections, but Testing and Exporting are the primary ones to be concerned with.

Important:
The Product Definition section is predefined to use the EGL RCP console UI player as the main application. Do not change this information, because EGL RCP plug-in projects require the console UI Player to operate properly.

Test the application


Figure 40. Launch the Product
Launch the Product

  1. To verify that your EGL RCP plug-in project is ready for export, click the Launch the product link in the Testing section (Figure 41). This shows that the application can be run, and it is what the product will look like when it is fully deployed.

Figure 41. Export the Product
Export the Product

Export the application

  1. To export the project, from the Overview tab, click the Eclipse Product Export wizard link in the Exporting section (Figure 42). This will bring up a dialog box where you can specify the location and application name of the product that you are exporting.

Figure 42. Export Dialog
Export Dialog

Tips:

  • Ensure that the product configuration file that is specified in the product configuration area is the same one defined for your EGL RCP plug-in product.
  • Also, it is very important that the "Synchronize before exporting" check box is unchecked. Failure to uncheck this box will lead to an export error stating that the console UI player is not found in your workspace, thus it could not be synchronized.

  1. Browse to the location where you want the application folder to be created, and then click Finish.

After the export operation has successfully completed, the folder you specified will contain, at a minimum, an executable file (named based on what you specified), a startup.jar file, a configuration, a plug-ins folder, and an .eclipseproduct file.

  1. Double-clicking on the executable file will launch your application.

Exporting EGL RCP projects to multiple platforms

You can configure your EGL environment to deploy your EGL RCP plug-in project for a different platform. Rational Business Developer Extension platform support is slightly less than what the base Eclipse product supports. Currently, EGL supports Windows, Linux, Solaris, AIX, and HP-UX. Eclipse supports these platforms, as well as the Mac OS X.

To configure your EGL environment to deploy to any or all of the supported Rational Business Developer Extension platforms, you will need to download the Eclipse RCP Delta Pack, Version 3.2. (Version 3.2.1 is available as of this writing and can be used instead).

  1. Go to the Eclipse Platform downloads page, click the Version 3.2 link in the Latest Releases section, and then download the RCP Delta Pack which is at the bottom of the RCP SDK section. This downloaded file will contain all of the necessary libraries for all of the platforms supported by Eclipse.

Important:
Perform the next step with your RBD environment not running.

  1. Next, extract the contents of the Eclipse directory within the .zip file to the same location as your RBD installation. In other words, extract the Features and Plugins directories within the .zip file's Eclipse directory to the same-named directories in your RBD installation. If you are prompted to overwrite any existing files, click OK.
  2. Start Rational Business Developer Extension, which will then recognize the new additions.
  3. Now, when you perform a product deployment, there will be a check box called Export for multiple platforms in the Export Options section of the Export dialog. Checking this box will allow you to click the Next button in the dialog.
  4. The next screen of the dialog will enable you to select the platforms for which to create executable files. You can select as many platforms as you wish. The final folder that is created will contain a subfolder for each of the platforms selected (Figure 43).

Figure 43. Exporting to Multiple Platforms
Exporting to Multiple Platforms

The plugin.xml file

In your EGL RCP plug-in project, there is a plugin.xml file. This file is initially created during the generation step on EGL source files and subsequently updated after each generation step. This file provides the console UI player plug-in with a list of applications that may be executed.

If your EGL project contains only a single "main" EGL program, then there will be only a single program entry in the plugin.xml file. A project that contains multiple EGL programs will have an entry for each program in the plugin.xml file.

At deployment time, the plugin.xml file is copied into your deployment folder. When the launcher program is run, if there is more than one EGL program listed in this file, then a dialog box appears so that you can choose which of the EGL programs to execute. If there is only a single EGL program in the plugin.xml file, then the console UI RCP player will choose and execute that one by default (Figure 44).


Figure 44. RCP Program Selection Window
RCP Program Selection Window

The config.ini properties defined

An EGL RCP plug-in project will also contain a config.ini file, which is automatically created with the project. This file provides the RCP runtime with some configuration information needed during the application execution. It also allows for property definitions that help control where data created and used by Eclipse RCP is stored.

Many of the default settings are required by the EGL environment and should not be modified. There are also numerous properties that are not defined by default. Properties that are not specified in the config.ini file default to the Eclipse runtime value. The Eclipse Plug-in Developer Guide contains a complete listing of the valid properties, their definitions, and default values. Here are two that you may need to modify, depending on your deployment situation:

  • osgi.user.area: This property defines the location where preferences and other user-specific information is stored. It is also used by Jasper reports as the starting directory location where reports are created if the specified report file is defined as a relative path. The EGL default setting is @user.home/Application Data/EGL/<project name>.
  • osgi.splashPath: This property defines the location of the splash screen that is displayed when the EGL RCP application is launched. Further details are defined in the "Customizing your EGL RCP product" section that follows.

Customizing your EGL RCP product

There are numerous opportunities to customize or brand your EGL RCP application. A few of the more common ways are outlined below. Further documentation can be found in the Product Configuration document for Eclipse RCP.

Splash screen

Modify the config.ini file in your EGL RCP plug-in project. Change the value of osgi.splashPath to the location of a BMP (Windows bit-mapped graphic format) file. Note: Even though BMP is Windows standard, it is a portable format and can be read on any platform.

For portability, it is easiest to change the location of the BMP image to be a relative file system path (that is, if you are using a file from the local file system), where the starting directory location is the exported application folder. The value must be defined in Java™ URI (Universal Resource Identifier) format. For example:

osgi.splashPath=file:plugins/sampleProject_1.0.0

Tips:

  • If you include the image in your project, you need to modify the build.properties file to export the splash.bmp file so that it is included in the deployment folder.
  • An EGL RCP plug-in project is exported into the Plugins directory with the version number appended to the name.
  • The splash screen must be named splash.bmp.

Graphic for the executable icon

  1. In the Product Configuration editor, select the Launcher tab. Under this tab, you can specify an image that is used when Eclipse creates the application executable. Notice that each platform has a separate image type requirement (Figure 45).

Figure 45. Customizing the Product Launch
Customizing the Product Launch

Runtime arguments

In the Product Configuration editor, select the Launcher tab (Figure 46). Under this tab, you can specify special arguments that are passed to your running EGL RCP application. You can further specify arguments for specific platforms, if required.


Figure 46. Adding Arguments to the Launch
 Adding Arguments to the Launch

Note:
To pass arguments to your application during development, you can modify your launch configuration by choosing the menu option Run > Run....

  1. In the wizard, select the launch configuration for your project. (This launch configuration won't exist until you've actually run your application at least once.).
  2. Go to the Arguments tab, and supply the desired values for the arguments (Figure 47).

Figure 47. Launch Configuration Dialog
Launch Configuration Dialog

Linking EGL RCP projects with other EGL projects

It is possible to link EGL RCP plug-in projects together to share common code. To do this, there are a few steps that you need to follow for all of the projects to recognize each other and export correctly at deployment time.

  1. Each of your EGL projects that you want to use with other EGL RCP projects must be EGL RCP plug-in projects.
  2. Each of the EGL projects must have their manifest.mf files modified to export whatever EGL code you use in the other projects.
  3. The manifest.mf file in the main program project needs to include all of the other EGL RCP projects in its dependency section.
  4. After adding or modifying such project dependencies to your main project, remove any existing current launch configurations associated with the main EGL project. This is necessary because these earlier launch configurations will not have the correct EGL RCP project dependencies required for execution. Removing these launch configurations will ensure that they will be re-created with the correct settings when you select the Run as RCP menu option.

Tip:
After performing these steps, if you receive Java compilation errors saying something similar to "There are duplicate Entries in your Java Path." You will need to edit your Java build path property:

  1. Right-click on your project and select the Properties menu option.
  2. Then select the Java Build Path section, and remove the EGL projects that you are linking together. (This can be done safely because these EGL projects are now referenced in the manifest.mf file. Having them in both the manifest.mf file and in the Java Build Path setting causes the Java compilation error.)
Share this...

digg Digg this story
del.icio.us Post to del.icio.us
Slashdot Slashdot it!

For further information

Most of the RCP behavior is exposed within the EGL environment in one way or another. Although not required, it is suggested that you develop a good understanding of Eclipse RCP if want to become very proficient at using RCP from EGL. The Eclipse Rich Client Platform Wiki (see Resources) is a good starting point.




Back to top


Download

DescriptionNameSizeDownload method
Sample application code for this articleSample_Application_Code.txt7KBHTTP
Information about download methods


Resources

Learn

Get products and technologies

Discuss


About the authors

Greg works in the Information Management brand of IBM's Software Group and focuses on EGL language development.


Arlan works in the Information Management brand of IBM's Software Group and focuses on EGL language development.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top