Exporting a layout means, that RADi generates a Java source code file, sufficient for you to build upon (either by extending or by editing it).
RADi does not create the entire GUI code, but only a small class with just the necessary import declarations, member declarations, constructors, inner class code and Action/EventListener methods. (The task of actually creating the GUI is done by the RADi runtime library as it processes your layout definition files).
Note: There is nothing magic about the exported code, you could even write it by hand.
Open the
by selecting the corresponding
in the project view or by pressing the
in the toolbar.
Fill in the Package and Class name fields (a package name is not required by RADi, but you should always package classes).
Note: Since Java 1.4 mixing of packaged and unpackaged classes is discouraged. If a packaged class references an unpackaged one, the result is a compiler error.
With Automatic export checked, the class will be exported every time you save the changed layout.
Decide, if the exported class should extendJPanel, JFrame, JDialog or JApplet.
For frames and dialogs you can set various properties (see Frame settings, Dialog settings).
If your class extends JApplet, the init() method is generated automatically.
Export anonymous members: If deselected only non-anonymous components/actions will appear as fields of the exported class.
Decide, if member fields should be private, package private, protected or public.
If you selectAll methods abstract, the class is also declared abstract and you must extend it.
Pressing Export commits changes, writes the source code file and creates all directories necessary to reflect the package name. Pressing Export-Compile additionally invokes javac (the Java compiler) on the source file.
Note: At 'File | Preferences | Compiler' you can set some compiler options. By default, javac will create 1.4 compatible class files and add debug information for line numbers and source file names.
To open the
, select 'Extends javax.swing.JFrame' and click the 'Settings...' button.
The code generator will create a private void setupFrame() method which is called from all the different JFrame constructors. It sets the frame's title, location and size, the default close operation and the frame's maximized and resizable state. You can also choose to add a WindowListener to the frame. Here comes the description for the individual settings:
Maximize: If selected, the frame will be initially maximized. If unselected, no code will be generated.
Resizable: Decide if the frame should be resizable or not. If selected, no code will be generated.
Create WindowListener: If selected, the code generator will add a WindowListener to the frame which, by default, calls System.exit(0) from the windowClosing listener method.
Close operation: The frame's default close operation which, by default, is HIDE_ON_CLOSE.
Frame title: The frame's title.
Frame icon: You can specify the icon displayed in the frame's title bar and as the icon for minimized frames. If unspecified, the platform dependent default icon is used.
Initial size: Either the frame's preferred size or a fixed size. RADi will perform no plausibility check but at runtime the frame's size will be restricted to the maximum display area size which is the screen size minus the screen insets.
Initial location: Either the frame's location relative to the screen context or a fixed location. RADi will perform no plausibility check but at runtime the location will be corrected if necessary (size overrides location).
Store settings as default frame settings: Make the current settings the default settings for frames.
Note: All operations which might affect a frame's preferred size (like adding additional components to the layout) should be performed before the setupFrame method executes.
To open the
, select 'Extends javax.swing.JDialog' and click the 'Settings...' button.
The code generator will create a private void setupDialog(Window owner) method which is called from all the different JDialog constructors. It sets the dialog's title, location and size, the default close operation and the dialog's modal and resizable state. You can also choose to add a WindowListener to the dialog. Here comes the description for the individual settings:
Modal: The dialog's modal property. If unselected, no code will be generated.
Resizable: Decide if the dialog should be resizable or not. If selected, no code will be generated.
Create WindowListener: If selected, the code generator will add a WindowListener to the dialog which, by default, calls hide from the windowClosing listener method.
Close operation: The dialog's default close operation which, by default, is HIDE_ON_CLOSE.
Dialog title: The dialog's title.
Initial size: Either the dialog's preferred size or a fixed size. RADi will perform no plausibility check but at runtime the dialog's size will be restricted to the maximum display area size which is the screen size minus the screen insets.
Initial location: Either the dialog's location relative to the owning frame resp. dialog or a fixed location. RADi will perform no plausibility check but at runtime the location will be corrected if necessary (size overrides location).
Store settings as default dialog settings: Make the current settings the default settings for dialogs.
Note: All operations which might affect a dialog's preferred size (like adding additional components to the layout) should be performed before the setupDialog method executes.
There are two drawbacks implementing applets with RADi: first, the RADi runtime library requires Java 1.4 and second, radirt.jar needs to be downloaded. So, if your applet should download in minimum time or if it should run in browsers without a Java plug-in, you should write the GUI code by hand and not use RADi.
With unsigned applets, there are two restrictions:
Fields and methods of the exported class should be declared public (else you will see a java.security.AccessControlException. The required permission is java.lang.reflect.ReflectPermission "suppressAccessChecks").
The same holds true for inner classes where additionally the inner class itself should be public.
You cannot call the RadiLoader method that specifies a locale, because an applet, by default, is not allowed to change the default locale. (The required permission is: java.util.PropertyPermission "user.language", "write")
With signed applets there are no restrictions.
Applets know the concept of a code base URL. If not defined explicitely (with the CODEBASE attribute of the APPLET tag), this is the directory where the HTML file, containing the APPLET tag, is located.
If RadiLoader detects a class derived from JApplet, it tries to resolve all references relative to the applet's code base.
When exporting a JApplet class, RADi additionally exports a HTML file containing this APPLET tag:
The ARCHIVE="radirt.jar" attribute tells the browser/applet viewer: "There is a JAR file to download, its name is radirt.jar and it is located in the code base directory". (Actually you should copy radirt.jar to the project directory, which is the code base for local testing). Width and height are calculated from the layout's preferred size using the current look and feel.
Please note that this HTML file will be overwritten each time you export the layout.
If you decide to extend JApplet, follow these steps:
1) Create the GUI as usual and make sure, that all resources go to the project's resources directory.
2) Export and compile the layout class(es) (RADi will also export a HTML file containing the APPLET tag).
3) If not already done so, copy radirt.jar to your project directory.
4) If your classes are in a sub-directory (such as 'classes'), copy them to the project directory.
5) Point your browser/applet viewer to the HTML file generated (its name is <className>.html, its location is the project directory).
Note: Writing the applet code yourself and importing RADi-generated panels or dialogs will not work. The reason is, that the RADi runtime does not know the code base of your applet and therefore cannot resolve references to resources (not even to the layout definition file).
Whenever you added or removed components, whenever you added or removed Actions or EventListeners, you should re-export the layout. With 'Automatic export' selected, the layout will be re-exported every time you save changes, so the Java code will always be synchronized with the layout data.
The export tool bar button shows a layout's export status:
The layout was never exported.
The layout is in sync with the class file (at startup RADi assumes that every layout is in sync).
The layout is out of sync with the class file and you should reexport it sooner or later.
As the code generator parses a previously exported class file, it does the following:
Checks the package declaration. In case it doesn't match the expected package declaration, parsing is cancelled with this
.
Checks the class name. In case it doesn't match the expected class name, parsing is cancelled and the code remains unchanged (see
).
The code generator will silently update the extends statement if necessary.
Adds missing imports (but doesn't remove unused imports).
At 'File | Preferences | Code Generation' you can globally choose if the code generator should create an import statement for each class or import entire packages (by default it will create an import statement for each class).
Adds missing member declarations (but doesn't remove unused member declarations). If it detects a type conflict it silently changes the field type. The code generator does not update access specifiers of existing declarations.
It is legal to remove member declarations and to change access specifiers.
Adds missing methods. When changing the type of the exported class, the following methods will be removed:
main and setupFrame if type was JFrame.
setupDialog if type was JDialog.
init if type was JApplet.
It is legal to change method access specifiers.
If you change a class from non-abstract to abstract, bodies of exported methods will be removed.
If you change the type of the exported class, all constructors are removed before the new constructor code is added. You may delete constructors except the one you actually call and you may change a constructor's argument list. If you delete all constructors, constructor code is added again.
Adds missing inner classes (but doesn't remove unused inner class code). Silently updates extends statements if necessary. Static and abstract modiers will be added or removed as needed.
Note: When parsing a source file, RADi assumes that it would compile without error.
With RADi, every container can be exported as an inner class. Inner classes give you two advantages:
Your source code will become more structured.
Each inner class has its own name space.
Note: Suppose you have a tabbed pane defined as inner class and one of the tabbed pane's children is a panel, defined as inner class, too. What you get is not an inner-inner class but two parallel inner classes.
You define inner classes using the
which looks very similar to the 'Export Layout' dialog. We will only discuss three items:
Class access: Decide if the exported inner class should be declared private, package private, protected or public.
With unsigned applets you must choose public, else, if you export the enclosing class as abstract class and you plan to extend inner classes, choose protected or public, else, to protect inner classes, choose private or package private.
static: Inner classes can be static, this means you can create instances without having an instance of the enclosing class. With RADi you will rarely need to specify an inner class as being static.
All methods abstract: If selected, the inner class will be exported as abstract class so you must extend it. Note: If the enclosing class is abstract, this doesn't mean that inner classes has to be declared abstract, too.