Radical Usage

Release version: 0.7.1a - June 23, 2002

Running Radical as an Application

To run Radical as an application from the install directory, simply type:
    java -jar lib/radical.jar

Running Radical as a jEdit plugin

Make sure you have copied both radical.jar and rad-jedit.jar into your jEdit jars/ plugin directory and then run jEdit.

Simple Tutorial

Note: It is probably a good idea to save your work periodically to avoid losing your work to an unforeseeable (and hopefully unlikely) program crash.

This simple tutorial demonstrates how to use the basic features of Radical; at the end of this tutorial you will have created a JPanel that looks like this:

[example dialog]

First start Radical using one of the methods described above. The default layout panel for Radical uses TableLayout and its table is three cells by three cells, it looks like this:

[initial radical]

Since we know the general layout of the panel that we wish to create, we will start by quickly "roughing" in the overall layout. First, to give us a little more room for our components, right-click over the layout panel and select "Column->Insert after"; right-click over the layout panel again and select "Row->Insert after". Now we have a table that is four cells by four cells, now we can start laying out our components. To layout components, we simply drag them from the palette along the buttom of the Radical window; this is the component palette:

[palette]

Assume that we have numbered the cells of the table in the layout panel using column and row coordinates, where the top row is numbered (0, 0), (1, 0), (2, 0), and (3, 0); thus, the bottom, right-most cell is (3, 3). Using this numbering scheme, drag the following components into the specified cell locations:

This creates the roughed-in layout, the layout panel should look like this:

[rough layout]

If your layout panel does not look like this, then right-click over components that are in the wrong possition and select "Remove", then re-drag the appropriate component type to the correct position (when you re-drag the components, they will have different names, but that is okay). At this point we will resize some of the components to match our desired layout. Right-click on the text field and select "Size..."; this displays the sizing dialog box that looks like this:

[size dialog]

Change the number of columns to be 2 and then select the "Okay" button. Size the scroll pane by following the same procedure, i.e., right click on it and select "Size...", but this time make the size 2 columns and 2 rows. Lastly, resize the layout panel, making it 4 columns and 1 row. The layout window should now look like this:

[resized components]

We will continue to size and align the various components, columns, and rows so that they match are desired layout. Right-click in the first row and select "Column/row size..."; this will display the column and row sizing dialog that looks like this:

[column/row size dialog]

For the "Row" setting, select the "Preferred" size and then select the "Okay" button; this sets the row height to be the maximum preferred height of the components on that row. Right-click in the bottom row and follow the same procedure to make the bottom row height "Preferred" also. Right-click in the first column and again select " Column/row size...", but this time set the "Column" setting to "Preferred"; do the same for the last column. The layout panel should look like this:

[partially sized]

Clearly, the buttons still need resizing, so we will do that next. The top button can be resized using the same method we have been using; right-click on it and select "Column/row size..." and make its "Row" setting "Preferred". To change the size of the bottom button, right-click on it and select "Alignment..."; this displays the component alignment dialog box that looks like this:

[alignment dialog]

From the alignment dialog, select "Top" from the "Vertical" alignment options and then click on the "Okay" button; the bottom button will now be positioned right underneath the top button. The reason that we used alignment here, rather than row sizing is because we want our scroll pane to grow and/or shrink as the window is resized. If we had set the bottom button's row to be "Preferred", then both of the rows that the scroll pane spans would have been fixed sizes, thus it would not have been able to grow when the window was enlarged.

At this point our layout is starting to look pretty good, but we are still missing some components, particularly some buttons along the bottom where we have the layout panel. To add buttons there we must first "zoom in" on the layout panel; you can do this by double-clicking on the layout panel or you can right-click and select "Zoom in". Using one of these methods, zoom in on the layout panel and the nested layout panel contents will fill the Radical window. The first thing we need to do is remove some columns and rows, since this table is too big. Using the right-click context menu, remove one column by selecting "Column->Remove" and remove two rows by selecting "Row->Remove" twice. Now drag a button into the first cell and another button into the second cell. At this point you could set the row size to "Preferred" if you wanted, but it is unnecessary since the parent layout panel row is already set to "Preferred".

Now we need to align the buttons by right-clicking and using the "Alignment..." option on each; align the first button horizontally right and the second button horizontally left. Lastly, we need to adjust some of the button properties. Right-click on the first button and select "Properties..."; this displays the property dialog box that looks like this:

[properties dialog]

The first thing that we want to do is to rename the button instance; we can do this by entering our desired name in the very first field at the top of the properties dialog box. In "Instance name" field enter the name, "m_okayButton"; this is the name that will be used for the component when generating the source code. In addition to the instance name, we also want to make this component a class member; to do this simply click on the "Class member" check box underneath the instance name field. By making a component a class member, it will be available as a protected member of the generated class so that subclasses can access it directly. The last thing that we want to do in the properties dialog box is to change the text in the button; to do this, scroll down the list of properties until you find the "text" property. In the text field of the "text" property enter the string "Okay" and press the <RETURN> key (currently when editing text properties, you must use the <RETURN> key to "enter" the change, but this might change in the future). We have made all of the necessary changes to the component instance, so select the "Okay" button at the bottom of the properties dialog.

We need to repeat the process for the other button, so right-click on it and select "Properties..." again. This time, name the instance "m_cancelButton", make it a class member, and change the "text" property to "Cancel" -- do not forget to press <RETURN> . Select the "Okay" button at the bottom to dismiss the properties dialog. At this point all necessary changes to the nested layout panel are done so we can "zoom out"; to do this, right-click over the layout panel and select the "Zoom out" option. The layout panel should now look like this:

[complete nested panel]

At this point, we need to modify the properties of all other components in the layout panel. We will edit the properties of the remaining components using the same process that we used when editing the properties of the nested panel components. First edit the properties of the label component, only change the "text" property to "Name". For the text field, change its instance name to "m_nameField" and make it a class member. For the top button, change its instance name to "m_addButton", make it a class member, and change its "text" property to "Add". For the bottom button, change its instance name to "m_removeButton", make it a class member, and change its "text" property to "Remove".

Our panel is getting pretty close to our desired layout now, but we are still missing the tree component. To add the tree component to the scroll pane, drag a tree component from the palette and drop it onto the scroll pane in the layout panel. This displays the method selector dialog box that looks like this:

[method selector dialog]

The method selector dialog box is very powerful and currently is only partially implemented; it allows you to drop arbitrary components onto existing components and dynamically specify what method gets invoked for that dropped component. We will avoid the complex aspects of the method selector dialog box for this tutorial, we simply want to add the tree component to the scroll pane by selecting the "setViewportView()" method from the available methods in the selector dialog box. Select the method and finish by clicking on the "Okay" button. After adding our tree to the scroll pane, we need to give the tree a name and make it a class member so that we can access it in our subclass; to do this following the same procedure as always (i.e., right-click and select "Properties..."), although now you should see that you can edit the properties for both the scroll pane and the tree. Name the tree instance "m_tree" and make it a class member. Now our layout is almost complete and should look like this:

[almost complete layout]

The only aspect that is missing from our layout at this point is aesthetic spacing around the edges of the window and between components. It is simple to add spacing to the layout, just add columns and rows with fixed spacing where needed. For example, to create a empty border of 5 pixels around the entire layout, right-click in the top-left cell and select "Column->Insert before", then right-click again in the top-left cell and select "Row->Insert before", and then right-click again in the top-left cell and select " Column/row size..." and then enter a fixed size of 5 for both the column and row settings. Do this same set of steps again for the bottom-right cell, but instead of "Insert before" use "Insert after" for the column and row. Now there is a five pixel spacer around the edges of the layout. To complete the aesthetic spacing, insert a column after the label, insert a column after the text field, insert a row after the text field, insert a row after the top (i.e., "Add") button, and insert a row after the tree component. Now right-click on each newly inserted column or row and change its sized to be fixed at 5 pixels. For completeness, we should also zoom into the nested panel and add a 5 pixel column between the two button; we do not need to add border spacing in the nested panel because there is already spacing around the nested panel in the parent panel. The final layout panel should look like this:

[complete layout]

Note: Do not infer that the 5 pixel spacing is required for aesthetic beauty in your layouts, I actually prefer 5 pixels around the outside edge and 3 pixels in between components, but for the purposes of this tutorial, 5 pixel spacing is sufficient to demonstrate the point.

Now that the panel looks exactly like we want, we might want to add some behavior to the panel using event listeners. Right-click on the "Add" button and select the "Event listeners..." item from the context menu; the event listener dialog box will appear, like this:

[listener dialog]

This dialog box allows you to add and edit all applicable event listeners for the selected component; for the tutorial, we will add an ActionListener. Click on on the ActionListener entry in the tree control; this will put a check mark next to the event listener's name. If we were to stop here, then the event method ActionListener.actionPerformed() would be generated as an abstract method when we generate the source code for our panel; intead of an abstract method, we will create a method body.

To create a method body for our ActionListener, expand the ActionListener tree node by clicking on the tree node handle next to it; this reveals the methods in the event listener. Select the actionPerformed() method and then type (copy-and-paste) the following text into the method body text area underneath the tree control:

if ((m_tree.getSelectionCount() == 1) &&
    (m_nameField.getText().length() > 0))
{
    DefaultMutableTreeNode parent = (DefaultMutableTreeNode)
    m_tree.getSelectionPath().getLastPathComponent();
    DefaultMutableTreeNode child =
        new DefaultMutableTreeNode(m_nameField.getText());
    ((DefaultTreeModel) m_tree.getModel()).insertNodeInto(
        child, parent, parent.getChildCount());
}

The above code snippet represents the method body for the selected method in the listener tree; the code snippet adds a child to the tree using the text from the text field. By typing text into the method body text area, Radical automatically selects the event listener and makes the selected method non-abstract. Adding method bodies creates a problem for Radical, though. When it comes to generating the source code for the panel, Radical does not know which classes must be imported, so you must tell it specifically by clicking on the "Import..." button at the bottom of the event listener dialog; this displays the imports dialog box that looks like this:

[imports dialog]

In the "Package/class" text field, type "javax.swing.tree.DefaultTreeModel" and press the "Add" button. Then enter "javax.swing.tree.DefaultMutableTreeNode" into the text field and press "Add" again. Using this mechanism, we are telling Radical which classes it needs to import in the generated source code; it is also possible to import wildcard (i.e., "*") packages. We are done adding event listeners, so click on the "Okay" button of the imports dialog and then on the "Okay" button of the event listeners dialog box.

To conclude, you should save your form if you have not already. Everything is ready for generating the source code and compiling, simply select "Generate source..." from the "Tools" menu and enter a package name and specify the output file (if you are using Radical as a jEdit plugin, then the source is generated into a new buffer). To compile the code type (for Windows, modify the slashes):

    javac -d <output dir> -classpath lib/tablelayout.jar <java-file>

This assumes that you are compiling from the Radical installation directory; substitute the desired name of the output directory for your classes. To run the example, type (for Windows, modify the slashes and use a semicolon instead of a colon):

    java -cp <output dir>:lib/tablelayout.jar <class-name>

Test the program by typing something into the text field, selecting a node in the tree, and pressing the "Add" button. Please note that the frame displayed by running the above command will not be the exact size of the screenshot shown at the beginning of this tutorial; currently, setting the preferred size must be done in the subclass. This is the end of the tutorial.

Contact

Feel freel to contact me at heavy@ungoverned.org if you have any problems.

Richard S. Hall