Previous Next Contents Generated Index Doc Set Home


CHAPTER 10

Designing For Java





Introduction

This chapter describes the way Sun WorkShop Visual can generate Java code from any design. It is divided into the following sections:

  1. Requirements. This describes what you will need in order to use the generated Java code. This starts on page 321.
  2. Using Sun WorkShop Visual For Java. This section describes how to use Sun WorkShop Visual to create a Java-compliant design. This section starts on page 321.
  3. Java Version. This section describes how you can generate code for either Java 1.0 or 1.1 and how to tell which resources apply to which version. This starts on page 324.
  4. Widgets. This introduces the way in which a Motif design can be generated in Java, starting on page 328.
  5. New Widgets for Java Classes. This section describes the extra layout widgets for those Java layout components which have no Motif equivalent. See page 328.
  6. Event Model. This describes how you can use the Java 1.1 event model, complete with listener objects, in Sun WorkShop Visual. A short tutorial is provided to help you get started. This section starts on page 335.
  7. Generate Dialog. Changes have been made to the Generate dialog to allow you to generate Java code. This descriptions starts on page 340.
  8. Generated Code. This section is a discussion of the code generated for Java and starts on page 344.
  9. Moving Sun WorkShop Visual Designs to Visaj. This section describes how you can take your Java design further by saving your design in a format which can be imported into Visaj, the visual application builder for Java. See page 352.
  10. Motif Widgets to Java Classes - The MWT Library. This section describes the library of classes which map Motif widgets to Java classes. This starts on page 355.


What is Java?

Java is a programming language with elements reminiscent of C and C++ (amongst others). It has libraries specifically geared for the Internet environment. In addition, Java is highly portable, object-oriented and interpreted. It is threaded, has automatic storage management and uses exceptions. If none of this means anything to you, you may like to read the books listed in "Books on Java" on page 891 before continuing.


The Generated Java Code

The code generated by Sun WorkShop Visual can be in the form of applets or straightforward applications. An applet is a small application which is embedded in a web page and runs when the page is browsed.

The generated Java code is not restricted in any way. That is to say, the code can be taken away and used on any platform supporting Java and used any number of times. Because Sun WorkShop Visual allows you to design on Motif-based platforms regardless of your target platform, the generated code imports a library of classes implementing the mapping of Motif widgets to Java classes. This library is known as MWT and is supplied as part of the Sun WorkShop Visual release. In Java, classes can be grouped together into packages. The MWT is in a package called uk.co.ist.mwt.

"Motif Widgets to Java Classes - The MWT Library" on page 355 details the way in which Motif widgets have been mapped to Java classes.


Requirements

In order to compile and run the generated Java code, you will need a Java compiler and interpreter. See your Sun WorkShop Visual Installation Notes for details on obtaining a Java compiler and interpreter. If you intend to generate applet code, you will also need either an applet viewer or a HTML browser to view the applet.

To generate Java code from Sun WorkShop Visual, you do not need to set any environment variables other than those you already use for Sun WorkShop Visual. In order to compile and run the generated code, however, you will need to set the CLASSPATH environment variable. This, like the PATH environment variable, is a list of directories. This list must include the directory $VISUROOT/lib/java_classes - where VISUROOT is the install directory of your Sun WorkShop Visual. It should also include any directory where you have generated class definitions which will be used by your application - for example, the current working directory (.). You should also make sure that the directory containing your Java compiler and interpreter is in your PATH list.


Using Sun WorkShop Visual For Java

The way Sun WorkShop Visual is used in order to generate Java code bears some resemblance to the way Sun WorkShop Visual is used for the generation of C++ and Microsoft Windows code. This is because Java is a class-based language like C++. The way in which class instantiations, derived classes and methods are handled is the same.


Note - If, therefore, you are not familiar with the use of Sun WorkShop Visual for C++, it is strongly recommended that you refer to Chapter 8 "Structured Code Generation and Reusable Definitions".

Creating Java Compliant Designs

The "Module" menu contains a toggle labelled "Java compliant". Setting this toggle on indicates to Sun WorkShop Visual that you wish your design to be suitable for Java code generation. If your design cannot be reproduced in Java code, the Java Compliance Failure dialog is displayed.


Java Compliance Failure Dialog

The Java Compliance Failure Dialog lists all aspects of the
design which cannot be reproduced in Java code. The dialog is illustrated in Figure 10-1.

FIGURE  10-1 Java Compliance Failure Dialog

The buttons at the bottom of the dialog perform the following functions:

Go to. Pressing this button causes the widget selected in the Java Compliance Failure Dialog to become selected in your design. If the widget is in a Shell other than the currently viewed one or it is in a folded section of the hierarchy, the view changes so that the widget can be seen.
Next. Pressing this button moves the selection in the Java Compliance Failure Dialog to the next item in the list of offending widgets.
Fix. Pressing this button fixes whatever is causing the compliance failure for the selected widget in the dialog. This button is only enabled when it is possible for the compliance failure to be fixed automatically in this way.
Close. This button closes the dialog.
Help. This button displays help on the dialog.

Design Restrictions for Java Code Generation

The following is a list of user interface features which cannot be carried over to Java code:

  1. A file selection box with a parent which is not a shell.
  2. A file selection box which has a work area.
  3. A file selection box which is a class.
  A file selection box must have a shell as a parent; Java only has a modal file selection dialog.
  4. A widget which is a class between a menubar and a shell.
  This restriction is imposed so that the shell can find out what its menubar is.
  5. More than one menubar in a shell
  In Java, a shell may only have one menubar.
  6. A cascade button has no menu.
  Because there is no equivalent to a cascade button in Java (menus are added directly to menubars), a cascade button on its own is meaningless.
  7. The design contains a popup menu.
  Java does not support popup menus.
  8. There is a multi-line string in a menubar.
  Multi-line strings are not supported in menubar. They are supported elsewhere.
  9. A link source is not a class.
  The source of a link must be a class in Java.
  10. A callback source is not within a class.
  This is a restriction of the current version of the AWT event model and may be improved in later versions as this model develops.
  11. A pixmap in a menu.
  12. A Label in a menu.
  13. A menu in the main window of an applet
  The three items above are not supported in Java.

Applet Design Rules

There are some design restrictions which apply specifically to applets. These are:

  1. An applet must have an application shell as the parent
  2. The applet itself must not be a class, although its immediate child must be a class.
  3. Any other shells should be top level shells.
  4. All top level shells should be classes.

To Make a Class or Not to Make a Class...

The Java compiler applies a restriction to class methods. A class method must contain no more than 64 variables. This has a major impact on your design although this is not immediately apparent. 64 variables sounds a lot but it is easy to reach such a figure. Once you do hit this limit, you will need to start designating widgets as classes so that there are more methods, each with the 64 variable allowance. If your design does overstep this limit, Sun WorkShop Visual informs you when you generate Java code.

There is a shortcut method of making a widget a class; simply hold down the right mouse button to display a menu of useful commands, including "Make class".


Enclosing Class for Callback Declarations

Widgets in Java designs can be given callbacks in the same way as widgets in any other type of design. Unless the callback is intended to define a listener object (as described in "Event Model" on page 335), the callback should be a method. The method is declared in the enclosing class for the widget. If the widget which has been given the callback is itself a class, then the callback method is declared in the widget's class. If it is not, Sun WorkShop Visual searches up the hierarchy to find the nearest ancestor which is a class and declares the method in the class for that widget.


Java Version

By default, Sun WorkShop Visual supports Java version 1.1. You may generate code for Java 1.0 by selecting the appropriate option in the generate options dialog. This is described in "Java Version for Generated Code" on page 325.

Resources and callbacks are marked to indicate which version (or versions) of Java supports them. A full description is provided in "Version Symbols for Resources and Callbacks" on page 325.

The event model (the way messages are passed between widgets) changed with Java 1.1. Sun WorkShop Visual fully supports this model by using listener objects. All of this is detailed in "Event Model" on page 335.

You can find out which version of Java you are using by running java with the "-version" switch. The version is then printed on standard output and Java immediately exits.


Java Version for Generated Code

The Java Options dialog, shown in Figure 10-2, includes a new option menu allowing you to select the Java version for your generated code.

FIGURE  10-2 Java Options Dialog

The Java Options dialog is displayed by pressing the button labelled "Java options..." on the Java page of the Generate Overview dialog.

Whichever version was last selected is the version used when code is generated from the command line. If no selection has been made, the default of "Java 1.1" is used.


Version Symbols for Resources and Callbacks

There are three annotation symbols in the resource panels to show Java support. The coffee cup with the text "1.1" printed over it, as shown in Figure 10-3, indicates that the resource is supported in Java 1.1 only.

FIGURE  10-3 Java 1.1 Core Resources for Popup Menu

The text "1.0" over the coffee cup, also shown in Figure 10-3, indicates that the resource is supported in Java 1.0 only. A coffee cup with no text indicates that the resource is supported in both versions of the JDK. Having no coffee cup indicates that the resource has no Java support.

FIGURE  10-4 Resource Panel Annotations

Callbacks in the callbacks dialog are shown with the string "J1.0" to indicate that the callback is supported in Java 1.0 only. The string "J1.1" indicates that the callback is supported in Java 1.1 only. A simple "J" indicates that a callback is supported in both versions. As with resources, no annotation means that the callback is not carried forward into Java. Examples of these annotations are shown in Figure 10-5.

FIGURE  10-5 Callback Dialog Annotations


Widgets

The set of Java components and the set of Motif widgets are not the same. This means that two areas need to be covered to resolve the problem of generating Java code from a design built on a Motif-based platform:

  1. Map the Motif widgets available from Sun WorkShop Visual to Java classes
  2. Add widgets to represent Java classes which cannot be mapped back to Motif widgets
In order to address the first issue listed above, the MWT is supplied with Sun WorkShop Visual. This is a library of classes which mimic the Motif widgets. This library is called MWT and is located in $VISUROOT/lib/java_classes. The classes in this library have been grouped together into a package which is referred to as uk.co.ist.mwt. All code generated from Sun WorkShop Visual imports this package.

Internally, Sun WorkShop Visual decides which widgets correspond to which Java classes. A full listing of this mapping is provided in "Motif Widgets to Java Classes - The MWT Library" on page 355 along with a list of the resources which are relevant to Java code.

To satisfy the second criterion above, the following Java layout classes, which have no counterpart in Motif, are provided as widgets:

Card
Flow
Border
Grid
GridBag
These are detailed below.


New Widgets for Java Classes

There are five new widgets; each one simulates a Java layout manager. The widgets are a part of Sun WorkShop Visual and, as such, appear on the palette. The source code for them is also supplied as a part of the Sun WorkShop Visual release. This can be found in $VISUROOT/src/java_widgets (where VISUROOT is the install directory of your Sun WorkShop Visual). The directory also contains a file named README which provides more information on the widgets.

The following sub-sections provide information on how to use each of the new Java widgets and the resources associated with them.


The Card Widget

The Card widget is a Motif equivalent of the Java CardLayout class. It lays out its children so that they are all the same size as itself with only the topmost child visible. Each child can be given a "page number" and the Card widget can be told to show the child with a specified page number.

A typical use for the Card widget is multi-page dialogs controlled by an Option menu or by "Tab" buttons.

There are three resources associated with the Card widget:

horizontalSpacing
verticalSpacing
currentPage
The spacing resources are of type XtRDimension and refer to the spacing around the Card.

The current page resource determines which of the various children of the Card is currently displayed "on top". The resource is of type XtRInt.

Each child of a Card widget has a constraint resource, pageNumber, which allows you to assign a page number to the child widget. This resource is of type XtRShort.

To display any given child, set the Card widget currentPage resource to the pageNumber specified for the child.

There is a convenience function XdCardShowPage(Widget card, int page) defined in the Card widget sources for performing this within your own code.


The Flow Widget

The Flow Widget is a Motif equivalent of the Java FlowLayout class. It lays out its children in rows from left to right. When a row is full it moves onto a new row i.e. it lays out its children as a word processor lays out words in a paragraph. The rows may be left/right aligned or centred.

There are three resources associated with the Flow widget:

horizontalSpacing
verticalSpacing
horizontalAlignment
The horizontal and vertical spacing resources are of type XtRDimension. They refer to the gap between the rows and columns of child widgets.

The horizontal alignment resource is of type XdRAlignment and can be set to one of left, center or right.

The resource behaves similarly to the alignment of text in a paragraph.


The Border Widget

The Border widget is a Motif equivalent of the Java BorderLayout class. It can accept up to five children, which can be assigned to five positions: north, south, east, west and center, as shown in Figure 10-6. The Border widget can have more than five children but the surplus ones are simply added at a default location and not laid out.

FIGURE  10-6 Schematic Depiction of BorderLayout

The north and south children expand to fill the width of the Border widget. The west and east children fill the space between the north and south children vertically and the center child fills any space left over. The Border widget makes a good replacement for the MainWindow widget as it does not suffer from many of the MainWindow's problems and peculiarities. Any of the five positions may be left empty.

There are two resources for the Border widget:

horizontalSpacing
verticalSpacing
Both of these resources are of type XtRDimension and refer to the gap between the children.

Each child of the Border widget has a constraint resource which is the borderAlignment. This is of type XdRBorderAlignment, and can be set to north, south, east, west, or center.


The Grid Widget

The Grid widget is a Motif equivalent of the Java GridLayout class. The Grid widget makes all its children the same size and lays them out in a grid pattern. The number of columns in the grid is specified by a resource - the number of rows is calculated. Resizing the Grid widget will cause all its children to resize to fit.

There are three resources for the Grid widget:

horizontalSpacing
verticalSpacing
numColumns
The horizontal and vertical spacing resources are of type XtRDimension and refer to the gap between the rows and columns of the children.

The numColumns resource is of type XmRShort, and this refers to the number of columns to display in the grid.


The GridBag Widget

The GridBag widget is a Motif equivalent of the Java GridBagLayout class. The GridBag widget is complicated but provides the greatest flexibility of all the Motif and Java layout widgets. The GridBag incorporates the idea of a grid - with widgets in cells laid out in rows and columns. The rows and columns of the GridBag, unlike those of the Grid widget, can be different heights and widths to accommodate the different types of widget. The size of a row or column is determined by the tallest or widest child widget in that row or column respectively. Child widgets can also be expanded to fill any number of rows and columns and can be aligned to a specified geographical location within the cell(s) that they occupy. The GridBag also allows you some control over the way children resize when the GridBag itself is resized. This is explained in "Resizing the GridBag" on page 333.

When children are added to the GridBag, they are placed to the right of the previously added widget. To change their position in the grid, you will need to use the constraints dialog on each individual child widget.


GridBag Constraints Dialog

The Constraints dialog for the child of a GridBag is shown in Figure 10-7.

FIGURE  10-7 Constraints Dialog for GridBag

The top of the Constraints dialog shows two option menus. The cellAlignment resource tells the GridBag where the widget should be placed geographically in the group of cells that it occupies - North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest or Center. The cellFill resource makes the widget resize to fill part or all of the group of cells that it occupies. Selecting Horizontal makes the widget fill all the columns that it occupies, selecting Vertical makes it fill all the rows. Selecting Both makes the widget expand to fill all the rows and columns that it has been given. The None option keeps the widget at its original size at the geographical location specified by the cellAlignment resource.

The row and column resources allow you to tell the GridBag where you wish the selected widget to appear in the grid. The similarly sounding rows and columns resources tell the GridBag how many rows and columns the widget will occupy. The widget does not expand to fill the specified number of rows and columns - that behavior is controlled by the cellFill resource described below. There are two "special" values which can be entered in the rows and columns textbox:

  1. A value of 0 (zero) in the columns or rows textbox indicates that the widget should occupy all columns or rows respectively from its current position to the edge.
  2. A value of -1 (minus one) in the column or row textbox indicates that the widget should remain vertically or horizontally next to the previously added widget, respectively.
The rowWeight and columnWeight resources refer to the resize policy and are explained in "Resizing the GridBag" on page 333.

The padX and padY resources specify internal padding to add on each side of the component horizontally and vertically respectively.

The inset resources (insetLeft, insetRight, insetTop and insetBottom) specify the margins to appear on each side of the selected widget.


Resizing the GridBag

The Constraints dialog for the children of a GridBag contains the rowWeight and columnWeight resources. These resources affect the way the rows and columns will resize when the GridBag is resized.

Although each widget child of a GridBag can be given a rowWeight and a columnWeight, the GridBag searches for the highest number in each row and column and uses that number for its calculations for the whole row or column. For this reason there is no need to set a weight on every widget, just one in each row and column.

The easiest way to describe the effect of setting row and column weights is through examples.


rowWeight Example

This first illustration considers rowWeights. Imagine that you have set row weights as shown in Figure 10-8. The top row has a highest rowWeight setting of 3, the middle 2 and the bottom row 1. These "highest" settings are the only ones that matter - we can now ignore the other rowWeights in each row.

The GridBag now calculates the sum of all rowWeights - in our case, this is 6. Now imagine that the GridBag is stretched downwards. Any extra space is allocated to the rows as follows:

The row with a rowWeight of 3 receives one half of the extra space (because 3 is one half of 6)
The row with a rowWeight of 2 receives one third of the extra space (because 2 is one third of 6)
The last row, with a rowWeight of 1 receives the remaining one sixth of the extra space (because 1 is one sixth of 6)

FIGURE  10-8 Example rowWeight Settings


columnWeight Example

The GridBag calculates how to resize its columns in the same way as it calculates the rows, explained above. Imagine a GridBag containing widgets which have been given columnWeights as illustrated in Figure 10-9. This is the same illustration as that shown in Figure 10-8 except that the figures now refer to columnWeight instead of rowWeight. The highest columnWeight value in the left column is 2 and the highest value in the column on the right is 3. The GridBag is only interested in the highest figure in each column and ignores any other columnWeights that you may have set. The sum of these "highest" columnWeights is 5. With all of these figures, the GridBag can perform some percentage calculations when there is extra space available.

Now imagine that the GridBag depicted is stretched outwards to the right. It allocates the extra space to its columns as follows:

The left column, with a columnWeight of 2 receives two-fifths of the extra space (because 2 is two-fifths of 5)
The right column, with a columnWeight of 3 receives the remaining three-fifths of the extra space (because 3 is three-fifths of 5)

FIGURE  10-9 Example columnWeight Settings


GridBag Resources

There are two resources for the GridBag widget:

horizontalSpacing
verticalSpacing
Both of these resources are of type XmRInt and refer to the gap between the rows and columns.


Event Model

The event model (the way messages are passed between objects) changed between versions 1.0 and 1.1 of Java. If you select "Java 1.1" as the version to generate, the new event handling mechanism is used.

Whichever mechanism is being used, if you have registered a callback method (as opposed to a function), your method is called when the event is triggered. The main difference between the two versions is in the way callback functions are handled.

If you generate Java 1.0 code, all callback functions are ignored. They are not generated. Java deals with classes and therefore only supports the concept of methods.

When generating Java 1.1 code, however, your callback functions are treated as calls to an external listener object which can be generated by Sun WorkShop Visual. This means that if you are moving from C++ to Java and your code uses functions, you can generate Java 1.1 code and maintain equivalent behavior.


Note - The buttons in a Java File Selection Box do not fire events when pressed. For this reason, links from a File Selection Box will not work in the generated Java code.

Listener Objects in Sun WorkShop Visual

When generating code for Java 1.1, Sun WorkShop Visual interprets callbacks which have been defined as functions (as opposed to methods) as listener objects. A listener object is an instance of a class which implements an interface between an action occurring in the user interface front end and the rest of the application. These are also called "helper" and "adapter" classes.

Sun WorkShop Visual can follow one of two strategies when generating listener objects from callback functions. This is controlled by the following resource:

visu*javaWrapFunctions:true

The default is "true". This causes Sun WorkShop Visual to generate a wrapper object, as explained in the following subsection. Set this resource to "false" if you wish to handle the listener object code yourself, as described in "Controlling Listener Objects Yourself" on page 338.


Using Callback Objects

When Java 1.1 is generated, callback functions are treated as references to listener objects. A callback object is generated into its own file using the name of the function with "callback" appended. If, for example, you have a callback function named "myFunction", the following class is generated in a separate file called myFunctionCallback.java:

public class myFunctionCallback
{
        static myFunctionCallback me = null;




        public void doit( AWTEvent e, Object context)
        {
		// write your code here
        }




        static myFunctionCallback getInstance()
        {
		return new myFunctionCallback();
        }




        static myFunctionCallback get()
        {
		if (me == null)
			me = getInstance();
		return me;
        }
}
The file is only generated if it does not already exist. You can safely add to it because this file is not overwritten.

There is only one instance of each callback's object. If you have added the same callback function to a number of different widgets, they will share the one callback object by calling a get() method which returns the single instance. The object is created the first time get() is called.

The callback object has a doit() method which is similar to a standard callback stub - this is where you add your own code. The doit() method is called from the listener object in the enclosing class of the object with the defined function. The context object and the event itself are passed into the doit() method. For example:

{ // Java `global' callback object
	final myFunctionCallback myFunctionHandler = 
		myFunctionCallback.get();
	if ( myFunctionHandler != null )
		button1.addActionListener(
			new ActionListener()  {
				public void actionPerformed(ActionEvent event)  	
				{
					myFunctionHandler.doit(event, 
						XApplication.this);
				}
			}
		);
}
This is the default behavior. Changing the javaWrapFunctions resource to "false" results in the behavior described in the following section.


Controlling Listener Objects Yourself

If the javaWrapFunctions resource is set to "false", none of the callback object code described above is generated. In the example of the Activate callback on a button, the following is generated into the enclosing class:

if (myFunction != null)
	button1.addActionListener( myFunction );
Where "button1" is the name of the widget which has a callback function defined for it and "myFunction" is the name of the callback function.

The code as generated is intentionally incomplete; it will not compile as it is. There are two pieces of code which you need to add:

  1. The declaration of the listener object "myFunction".
  2. The definition of the class of which "myFunction" is an instance.
The first piece of code is relatively simple. It would look like this:

EventListener myFunction = new EventListener();
  This declares the listener object "myFunction" as an instance of the class "EventListener" which is a class that you are about to define.
The second piece of code is a little more complex:

class EventListener implements TextListener, ActionListener {
public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == button1)
            // Add the code to do something here...
}

}
This is the definition of the new EventListener class. The method "actionPerformed" is called when an event occurs in button1. You may wish to define classes like this in their own file with "public" access so that they may be used by any component. You will then need to make sure that you can access the component (in this case "button1").


Note - Only callbacks which are marked as Java compliant in the Callbacks dialog are generated. Those without the Java mark in the Callback List are ignored when Java code is generated.

X Events as Listener Objects

Selecting "Event Handlers..." from the Widget menu, when you have a widget selected, displays the Event Handlers dialog which is described in "Event Handlers" on page 209. Any procedures added here are treated the same as callback functions when Java code is generated if you have specified Java-compliant event masks. Event masks which are not Java-compliant are ignored when Java code is generated.

Sun WorkShop Visual assumes that you have a listener object with the name given for the procedure, in the same way it does for callback functions. Sun WorkShop Visual registers the listener object for each Java event type corresponding to each X event mask. For example, Figure 10-10 shows an event handler with the following event mask:

PointerMotionMask | KeyReleaseMask | EnterWindowMask
for a procedure called "exampleHandler" on a widget named "MyButton".

FIGURE  10-10 Example Event Handler

For such an event handler, Sun WorkShop Visual would generate the following Java code:

if ( MyHandler != null )
	MyButton.addMouseMotionListener( myHandler );
if ( MyHandler != null )
	MyButton.addKeyListener( myHandler );
if ( MyHandler != null )
	MyButton.addMouseListener( myHandler );
You would then be expected to add a line to the generated code file declaring that myHandler is an instance of a class defined elsewhere, for example:

MyHandler myHandler = new MyHandler();
To compile this code, you would need to define the class MyHandler. This class would have the following signature (it could also be "public" if so required):

class MyHandler implements MouseMotionListener, KeyListener, 
								MouseListener {
The MyHandler class would contain definitions of all the methods of the three listener classes.


Version Incompatibility for Callback Method Signatures

Callback methods for Java 1.0 have the signature:

void foo( Event x )
and for Java 1.1, they have the signature:

void foo( AWTEvent x )
The result of this is that if you generate a new Java 1.1 file on top of an existing Java 1.0 one, new stubs are generated for all of your callback methods. The old ones are, of course, retained, but they are no longer the methods which will be called. When upgrading your design from Java 1.0 to Java 1.1, you should move any code from the old methods to the new, adapting any code which uses the event objects.


Generate Dialog

The Generate Dialog is quite different when "Java" is selected from the Language option menu. A list of files which can be generated is displayed, as shown in Figure 10-11.

FIGURE  10-11 Java Generation Dialog

The text box labelled "Directory" shows where the files will be generated. To change this either type the name of the directory directly into the text box or press the "Browse" button and use the File Selection dialog.

Only files which are selected (or highlighted) will be generated. To select or deselect a file, click over it. Use the Shift key modifier to extend the selection list and the Control key modifier to add individual files to the selection. For more details on the files listed in this dialog, see "Java Files" on page 344. "Using the Generated Files" on page 350 explains how to compile and run the generated code.

The button labelled "Java Options" displays a dialog containing options which are relevant to Java code generation, as shown in Figure 10-12. For a description of the Code Options dialog, which is produced when the button labelled "Options" is pressed, see "Code Generation Options" on page 224.

FIGURE  10-12 Java Generation Options Dialog


Java Generation Options Dialog

The Java Generation Options Dialog allows you to control the following five areas associated with Java code generation:

  1. Whether you wish to create an application or an applet.
  2. The name of the base class of the application.
  3. Which version of Java code you wish generated.
  4. Whether you wish your design to use GIFs or not.
  5. The name of the package to create, if you wish your classes to be bundled together into a package.

Application or Applet

By default, Sun WorkShop Visual will generate an application from your design. If you prefer to generate an applet, select the appropriate option from the option menu. If you select "Applet", the generated main code file will contain extra code to allow the application to run inside an HTML browser.


Changing the Base Class

The main code file contains one class which, effectively, links together your design. The name of this class is whatever you have specified as the application class in the Code Options dialog (or XApplication by default). This can be extended from another class by typing its name in the text box labelled "Base class". If you are generating an application and you do not specify a base class, the application class is not extended. If you are generating an applet and you have not specified a base class, the Java class "Applet" is used by default.


Using GIFs

The GIF options section of the dialog takes on one of two forms, depending on whether you are generating an application or an applet. In both cases, there is a toggle labelled "Use GIFs for images" at the top of the section. If this toggle is not selected, the rest of the section is insensitive. When it is selected and you are generating an application, the code generated for pixmap objects assumes that all of the pixmaps are stored in separate GIF file. When the "Use GIFs for images" toggle is not set, the pixmap objects are stored in a file named <ApplicationClassName>PixmapObjects.java as arrays of integers. When the "Use GIFs for images" toggle is set, that file contains code to load the GIF files. Also in this case, an extra file is added to the list of Java code files. This is the property file and is named <ApplicationClassName>Properties. In this file, the GIFs are referenced as follows:

<ApplicationClassName>.<ApplicationImagesName>.<PixmapObjectName>

where "ApplicationImagesName" is the value entered into the text field in the GIFs options section of this dialog. For example, if you are using the default application class name, XApplication, and you have created a pixmap object named "TreeIcon" and you have entered the value "MyApplicationImages" into the text field, then the property name for the TreeIcon pixmap would be:

XApplication.MyApplicationImages.TreeIcon

and if you had another pixmap object, this time named "LeafIcon", the property name would be:

XApplication.MyApplicationImages.LeafIcon

If you are generating an applet and you have set the "Use GIFs for images" toggle, the GIFs section of the dialog contains a text box which allows you to specify a directory (relative to the document base) where the GIF images can be found.

If you wish to use GIFs in your application or applet, you will need to create the GIF files. Sun WorkShop Visual provides some help by allowing you to generate XPM files for all your pixmap objects in one go. To do this, go to the "Pixmaps" page of the Generate Dialog. This contains a list of the pixmap objects in your design. Pressing "Generate" creates a XPM file for each object giving it the name <PixmapObjectName>.xpm. You can choose whether you wish to generate XPM2 or XPM3 format. Once you have generated the XPM files, you will need to convert them to GIF using a conversion utility. There are a number of freely distributed conversion utilities available including pbmplus and netpbm.


Specifying a Package

The last section of the Java Generation Options Dialog contains a text area where you can specify the name of a package. A package is a group of classes that are bundled together. If you choose to generate your classes as a package, your main code file will contain a statement to import it.


Note - There are some conventions which should be followed in the naming and organizing of packages. Your Java documentation will have more details on this.


Generated Code

Java code differs substantially from C or C++ code in its structure. All code in Java must be contained within a class. Each separate class must be contained within its own file. The "main" procedure is a method of the application class. The Java interpreter will locate this method and start the application.


Java Files

In the generate dialog, when "Java" is selected from the menu of language flavors, a selectable list of files is shown. Depending on the structure of your design, these will be as follows (names in angle brackets indicate a variable name according to the names you have used in the design):

  1. <ApplicationClassName>.java. This is the principal code file for the application which is a class defining the application. One method of this class is the "main" procedure. The name of the file is determined by the name of the application class - by default "XApplication". You can change this in the Code Options Dialog.
  2. <ApplicationClassName>Links.java. This is the file containing code to implement the dynamic links between widgets. You do not need this file if you have not made any links.
  3. <ApplicationClassName>PixmapObjects.java. If you have specified any pixmap objects, they will appear in a separate file.
  4. <ApplicationClassName>FontObjects.java. If you have specified any font objects, they will appear in a separate file.
  5. <ApplicationClassName>ColourObjects.java. If you have specified any colour objects, they will appear in a separate file.
  6. <ApplicationClassName>StringObjects.java. If you have specified any string objects, they will appear in a separate file.
  7. <WidgetClassName>_c.java. Every widget you have designated as a Java class (from its Core Resource Panel), must have its own code file containing the class definition. There will, therefore, be as many of these files as there are classes in your design. Unless you have a good reason for ignoring one of the widgets in your design, you will always need to generate these files.

Command Line Code Generation

For generating Java code from the command line, an extra flag has been added to Sun WorkShop Visual. The flag is `-J'.


Example Code

The code generated by Sun WorkShop Visual for the hierarchy and design shown in Figure 10-13 is listed below. To generate the code yourself, follow these steps:

  1. Select a Shell widget.
  2. Name the Shell "MyShell".
  3. Make "MyShell" an Application Shell.
  This is done in the Shell resource panel.
  4. Add the DialogTemplate to the Shell.
  5. Name the DialogTemplate "MyMessageBox".
  6. Select three PushButtons and a Form widget.
  7. Select a ScrolledText as the child of the Form.
  8. Name the ScrolledText "MyScrolledText".
  9. Select the ScrolledText , press the right mouse button and select "Make class" from the menu which is displayed.
  This is a quick way of changing the structure of the selected widget. Alternatively, you could display the Core Resource panel, go to the "Code Generation" page and change the "Structure" option menu to "C++/Java class".
You should now have the hierarchy shown in Figure 10-13.

FIGURE  10-13 Hierarchy and Design for Example Code

This simple design has no resources set as we are only interested in the code which is generated from it. In the generate dialog, when "Java" is selected, we are offered the files shown in Figure 10-14.

FIGURE  10-14 Generate Dialog for Example Code

Because we have not specified an application class name, the default (XApplication) is used in the filenames. You will need the file XApplication.java as this is the main entry point for the application and you will also need the file MyScrolledText_c.java as this is the class definition of the ScrolledText widget. So, what you should do breaks down as follows:

  10. Make sure that XApplication.java and MyScrolledText_c.java are both selected.
  11. Check the "Directory" shown at the top of the dialog. The files will be generated there so change it as necessary.
  12. Press "Generate".
For important information on when to make widgets into classes see "To Make a Class or Not to Make a Class..." on page 324.

Below is a listing of the file XApplication.java:

/*
** Generated by Sun WorkShop Visual/Java(tm) Edition
*/
import java.awt.*;
import uk.co.ist.mwt.*;
/*
** Sun WorkShop Visual/Java(tm) Edition - main program
*/
/**
 * A class representing the user interface specified by the entire
 * design.
*/
public class XApplication  {
	protected MyScrolledText_c MyScrolledText;
	protected Panel MyMessageBox;
	DlogTemplateLayout MyMessageBoxLayout = new 
		DlogTemplateLayout();
	protected Frame MyShell;
	public XApplication()  {
		Button button3;
		Button button4;
		Button button5;
		Panel form2;
		FormLayoutManager form2Layout = new 
			FormLayoutManager();
		MyShell = new Frame();
		MyMessageBox = new Panel();
		MyShell.add( "Center", MyMessageBox );
		MyMessageBox.setLayout( MyMessageBoxLayout );
		button3 = new Button( "button3" );
		MyMessageBox.add( button3 );
		button4 = new Button( "button4" );
		MyMessageBox.add( button4 );
		button5 = new Button( "button5" );
		MyMessageBox.add( button5 );
		form2 = new Panel();
		MyMessageBox.add( form2 );
		form2.setLayout( form2Layout );
		MyScrolledText = new MyScrolledText_c();
		form2.add( MyScrolledText );
		FormLayoutConstraints MyScrolledTextConstraints = 
				new FormLayoutConstraints();
		form2Layout.constrain( MyScrolledText, 
				MyScrolledTextConstraints );
		MyShell.pack();
		MyShell.layout();
		MyMessageBox.layout();
		form2.layout();
		MyScrolledText.layout();
		MyShell.show();




        }




        public static void main( String args[] )  {
		new XApplication();
        }




}  /* ...class XApplication (main application class) */
/*
** (end of Sun WorkShop Visual/Java(tm) Edition generated main 
program)
*/
/*
** (end of Sun WorkShop Visual/Java(tm) Edition generated code)
*/
Now, this is MyScrolledText_c.java:

/*
** Generated by Sun WorkShop Visual/Java(tm) Edition
*/
import java.awt.*;
import uk.co.ist.mwt.*;
/**
 * A class represented by the widget MyScrolledText_c in the design 
file
 */
// Private: classHeader Sun WorkShop Visual-generated code - do not 
edit >>>
class MyScrolledText_c extends TextArea  {
// Private: classHeader <<< Sun WorkShop Visual-generated code ends.




// Private: instanceVars Sun WorkShop Visual-generated code-do not 
edit >>>
// Private: instanceVars <<< Sun WorkShop Visual-generated code ends.
/**
* The constructor method for MyScrolledText_c
*/
// Private: constructor Sun WorkShop Visual-generated code - do not 
edit >>>
	public MyScrolledText_c()  {




	}
	// Private: constructor <<< Sun WorkShop Visual-generated code 
ends.
// Private: endClass Sun WorkShop Visual-generated code - do not edit 
>>>
}
// Private: endClass <<< Sun WorkShop Visual-generated code ends.
/*
** (end of Sun WorkShop Visual/Java(tm) Edition generated code)
*/
These files can be taken away and used in any way you see fit. The only caveat is the inclusion of the MWT. The line:

import uk.co.ist.mwt.*;
imports into your Java program all of the Java class library provided with Sun WorkShop Visual. This means that if you wish to take the generated files to a different platform and run the resulting application there, you will need to take the Java class library, MWT, as well.


Using the Generated Files

Once you have your Java code files you are free to use it on any platform which supports Java as long as you have the MWT library on that platform. Follow these steps to build a Java application from your generated files:

  1. Make sure that your CLASSPATH environment variable is set as explained in "Requirements" on page 321.
  2. Make sure that the directory containing any classes you have just generated is included in the CLASSPATH list.
  This may be your current working directory, in which case you should check that . (dot) is in the CLASSPATH list.
  3. Make sure that your PATH environment variable includes the directory containing your Java compiler.
  4. Type: javac <ApplicationName>.java
  This will give you a file <ApplicationName> with a ".class" extension.
  5. Type: java <ApplicationName>
  Your Java application should appear on the screen.

Callback Stubs

All code in a Java code file must appear within a class. This means that the callback stubs are generated as part of the class to which they belong. There is no separate callback file as there is with other flavors. This is not a problem, however, because all code added to the generated code is retained as long as the new code is outside of the guard comments. This subject is explained in the following section, "Retaining Edits" on page 351.


Retaining Edits

The sample code above contains the following section:

/**
* The constructor method for MyScrolledText_c
*/
// Private: constructor Sun WorkShop Visual-generated code - do not 
edit >>>
	public MyScrolledText_c()  {




	}
// Private: constructor <<< Sun WorkShop Visual-generated code ends.
This section contains a number of comments and illustrates how comments are used to retain any code you add. The first comment is for your information only. The second and third, however, are special. Any comment which begins "// Private: ..." - do not edit" indicates that the following lines must be left as they are. There is a corresponding "//Private: ... ends" which indicates the end of a section to be left untouched.

Any code or comment that you add outside of the special comments detailed above, will be retained when the file is regenerated. This means, for example, that you can add code to callback methods which will always remain.


Javadoc

Along with the Java compiler and interpreter you also have javadoc, an automatic documentation tool. Javadoc looks at .java files, parses the declarations and comments beginning with "/**" and produces HTML pages detailing the chain of class inheritance and all the public fields in a class along with any extra information contained in the special comments. The special comment mechanism is there for you to add to the documentation that javadoc creates. Code generated by Sun WorkShop Visual includes some basic information for Javadoc.


Moving Sun WorkShop Visual Designs to Visaj

Sun WorkShop Visual allows you to import your Sun WorkShop Visual designs into Visaj, the Java development tool. This gives you the ability to move your legacy Motif C/C++ designs quickly to Java.

You can, of course, use Sun WorkShop Visual's Java code generation facility to convert your design to Java. This would allow you to maintain a common code base covering Java, C/C++ for Motif and MFC for Microsoft Windows. If, however, you intend to use Java only, you may wish to move on to Visaj, IST's visual application builder for Java.

Moving your design from Sun WorkShop Visual to Visaj is simple and involves only the following steps:

Save the design in a special format using Sun WorkShop Visual's Save As dialog.
Load the file using Visaj's Import dialog.
This section describes how to achieve this from both sides - Sun WorkShop Visual and Visaj. The section ends with some troubleshooting hints.


From Sun WorkShop Visual

To save a file for Visaj, select `Save as...' from the File menu and then select `Visaj bridge format' from the `Save format' option menu.

Specify a filename and press "OK". This name will not be used as the default filename for your design.

If the design is not Java 1.1-compliant, the compliance dialog appears. This is the same dialog displayed when you generate Java form a non-compliant design. Fix the errors and try saving again.

As the file is generated, windows may flash up on the screen.


To Visaj

The Import pullright menu in the File menu contains the item "X-Designer bridge file" (X-Designer and Workshop Visual save files are fully compatible). When this is selected, a file dialog appears. Type the name of the file saved from Sun WorkShop Visual.

If you have used a feature in Sun WorkShop Visual which has no equivalent in the version of Visaj which you are using1, a dialog is displayed describing what has been found. The possible items in this dialog are as follows:


One or more classes were expanded into simple component hierarchies

In Sun WorkShop Visual, you can make any component a class. In Visaj, classes are separate hierarchies in different designs. To use them together in a design:

  1. Generate code for each class.
  2. Compile the code.
  3. Add the compiled classes to the palette as beans.
  4. Use the newly added beans in a larger design.
This method of conversion from Sun WorkShop Visual to Visaj allows you greater control of the way classes are used than if Sun WorkShop Visual made those decisions for you.

While importing, Visaj "expands" classes. You can, of course, refine this by cutting subhierarchies and pasting them into new Visaj designs after importing the design.


One or more frames were moved into their own classes

Visaj supports one frame per class. If your design contains multiple application shells or top-level shells, it is converted into several Visaj class files - one for each shell.

Dialogs, by contrast, are all reparented to the application shell (or a top-level shell if there is no application shell). However, if there is no application shell and there are no top-level shells, but if there are multiple dialogs, then each dialog is placed into its own class.


String/font/color objects in your design were expanded into simple property settings

Visaj has no equivalent to these objects, so all references to objects are expanded into simple resource values. For example, if you have a label myLabel whose text is <myObject>, where <myObject> is a string object with the value "Hello", then after import, myLabel has the text "Hello", and <myObject> is no longer used.


All XmForms in the design were changed to absolute positioning using a null layout

In Visaj, there is no layout manager com.pacist.mwt.FormLayoutManager. Components whose layout is controlled by this manager are positioned absolutely as a result.


Note - You are recommended to change your design to use one of the Java layout managers.

After Import

Once imported into Visaj, your design reflects exactly the Motif design in Sun WorkShop Visual. This is the same as if you had generated Java code directly except that, with Visaj, you can continue your Java application development.


Motif Widgets to Java Classes - The MWT Library

You may design your application user interface using Sun WorkShop Visual on a Motif-based application and then generate both C/C++ code for Motif and Java code. Sun WorkShop Visual allows you to do this by providing a library of Java classes, called the MWT, which map Motif widgets to Java classes. Some Motif widgets have a direct counterpart in Java, others do not. Where there is no clear mapping, the MWT library attempts to mimic the Motif widget using available Java classes. The following subsections list the Motif widgets available on Sun WorkShop Visual's widget palette and show which Java or MWT class is being used in the Java code generated.


Shell

If the Shell is set to be an application shell or top level shell, it is mapped to the Java Frame class. If it is set to be a dialog shell, it is mapped to the Java Dialog class. If, however, the child of the shell is a FileSelectionBox, then both the shell and the FileSelection box are mapped to the one Java FileDialog class.


MessageBox

The MessageBox widget can be mapped to three different Java classes according to the value of the XmNdialogType resource, which can be set in the Settings page of the MessageBox resource panel. The three mappings are:

The dialog type is set to Error, Information, Question, Warning or Working. In these cases the widget is mapped to the IconMessagePanel class which is part of the MWT library.
The dialog type is set to Message. In this case the widget is mapped to the MessagePanel class which is part of the MWT library.
The dialog type is set to Template. In this case the widget is mapped to the Java Panel class combined with the DialogTemplateLayout class from the MWT library.

MainWindow

The MainWindow widget is, essentially, a composite widget with particular resource settings. To mimic this Sun WorkShop Visual maps the MainWindow to various combinations of Panel and BorderLayout classes according to which resources have been set on the MainWindow and the number of children it has.


DrawingArea

The DrawingArea widget maps to the Java Panel class combined with the DrawingAreaLayout from the MWT library.


DialogTemplate

The DialogTemplate widget maps to the Java Panel class combined with the DialogTemplateLayout class from the MWT.


MenuBar

This maps to the Java MenuBar class.


BulletinBoard

The BulletinBoard widget is mapped internally to the Java Panel class combined with the BulletinBoardLayout class from the MWT library.


Command

This is mapped to the CommandPanel class from the MWT library.


Menu

The Menu widget is mapped to the Java Menu class. Note that this is a Pulldown menu - Popup menus are not mapped to a Java class.


Form

The Form widget maps to the Java Panel class combined with the FormLayoutManager class from the MWT library.


SelectionPrompt

The SelectionPrompt widget is based on the SelectionPanel class from the MWT library. To differentiate this widget from the SelectionBox, which also maps to the SelectionPanel class, internal class methods are called.


RadioBox

This widget maps to the Java Panel class combined with the Java CheckBoxGroup class and a layout manager.


PanedWindow

The PanedWindow widget maps to a Java Panel class combined with the PanedWindowLayout class from the MWT library.


SelectionBox

This maps to the SelectionPanel class from the MWT library.


RowColumn

The RowColumn widget maps to the Java Panel class combined with the ColumnPackedRCLayout class or the TightPackedRCLayout class (both from the MWT library) according to whether the packing resource has been set to "Column" or "Tight" respectively.


ScrolledWindow

If the scrolling policy resource for the ScrolledWindow is set to "Automatic", the widget is mapped to the ScrolledPanel class from the MWT library. If the scrolling policy is not set to "Automatic", the widget is mapped to the ScrollablePanel class, also from the MWT library.


FileSelection

The FileSelection widget maps to the Java FileDialog class. Since the Java class is a dialog, the Shell parent of the FileSelection widget is included in this mapping; both widgets become the one Java class.


Label

If the label type resource is set to "Pixmap", the widget is mapped to the ImageArea class from the MWT library. Otherwise, the Label widget is mapped to the Java Label class.


CascadeButton

This widget is not mapped at all. The label string resource of this widget becomes a resource of its Menu child.


TextField

This is mapped to the Java TextField class.


PushButton

If the label type resource is set to "Pixmap", the widget is mapped to the ImageButton class from the MWT library. Otherwise, the mapping of the PushButton widget is dependent on whether it is in a menu or not. If the PushButton is not in a menu, it is mapped to the Java Button class. If it is in a Pulldown menu, it is mapped to the MenuItem class. If the PushButton widget is in an OptionMenu, the label string resource is retained as a resource of the parent Choice class.


OptionMenu

If the Label widget of the OptionMenu has a label string resource set, then the OptionMenu is mapped to the Panel class with one Label and one Choice as its children combined with the FlowLayout class. If, however, the Label child of the OptionMenu has no label string set, then the OptionMenu is mapped to the Choice widget. All of these widgets are from the standard Java classes.


Text

The Text widget is mapped to the Java TextArea class.


ToggleButton

If the ToggleButton widget is not in a menu, it is mapped to the Java CheckBox class. If it is in a menu, it is mapped to the Java CheckBoxMenuItem class.


Separator

If the Separator widget is in a menu, it is mapped to the Java MenuItem class with its label set to dash (-). If the Separator is not in a menu, it is mapped to the Separator class from the MWT library.


ScrolledText

The ScrolledText widget is mapped to the Java TextArea class.


DrawnButton

The DrawnButton widget is mapped to the ImageButton class from the MWT library.


Scale

If the Scale widget has no children it is mapped to the Scale class from the MWT library. If it does have children, it is mapped to the ScalePanel class, also from the MWT library.


List

The List widget is mapped to the Java List class.


ArrowButton

The ArrowButton widget is mapped to the ArrowButton class from the MWT library.


ScrollBar

The ScrollBar widget maps to the Java ScrollBar class.


ScrolledList

The ScrolledList widget maps to the Java List class.



1 This applies to version 2.0 of Visaj.


Previous Next Contents Generated Index Doc Set Home