JDNC XML Markup Tutorial

JDesktopTM Network Components (JDNC) simplify the task of creating rich, sophisticated Java desktop clients that leverage the power of Swing and the Java platform. JDNC clients can be created using Java or by using an XML markup language that requires no Java or Swing programming.

The data for this demo comes from a file generated by a WebService that accesses global weather data from weather stations all over the world at the moment of the query. Information about each weather station, including country of origin, geographical coordinates and elevation, is included as well as temperature (in Celsius), visibility, humidity, and wind strength and direction at the moment of sampling. Click on the following image to launch this simple JDNC demo using Java Web Start:

The simpleTable example

This demo required only the following few lines of XML code:
  <?xml version='1.0'?>
    <om:resource xmlns:om="http://www.openmarkup.net/2004/05/om"
                 xmlns="http://www.jdesktop.org/2004/05/jdnc">
      <table>
        <tabularData source="data/weather.txt"/>
      </table>
    </om:resource>
This tutorial describes how to use the JDNC XML markup language to incorporate JDNC components into Java clients that are then deployed using Java Web Start or as an applet in a standard browser. This document does not describe the programmatic interface to JDNC — a tutorial that describes how to use the programmatic interface is in the works.

The examples that follow illustrate the power and ease-of-use of JDNC. The first demo is a basic table; subsequent examples build in complexity and highlight other component types, such as tree table, form, and editor. As you are learning JDNC, it's a good idea to start with an existing jdnc file and modify it to suit your needs — you can practice this using the exercises that follow most of the examples. The exercises are small, independent tasks that don't have to be done all at once.

The examples included in this tutorial are:

The sections in this tutorial are:

What You Need to Get Started

The software that you need to download and install is described in JDNC Downloads on the JDNC website. The download includes this tutorial and its examples.

Demo: simpleTable

The first demo, simpleTable, demonstrates how much functionality you can get for free when using JDNC. As previously mentioned, the data for this demo comes from a file generated by a WebService that accesses global weather data from weather stations all over the world.

The simpleTable example


Try this: 
  1. Run simpleTable using Java Web Start. You can also run it from the command line (using run demo\simpleTable.jdnc [on Microsoft Windows] or run.sh demo/simpleTable.jdnc [on Unix]).
  2. The contents of the weather file, generated from a weather service, appear in the table.
  3. Resize the window to make it wider.
  4. The columns have generic columnN style names, and can be dragged and resized. Move the columns around.
  5. The data is currently unsorted. Click on column0 — an upwards-arrow appears and the entries are sorted in ascending order.
  6. Click on column0 again. A downwards-arrow appears and the entries are sorted in descending order.
  7. Click on column4 — this floating point column indicates the elevation of the weather station. Note that the numbers are sorted alphabetically rather than numerically, so that the rows with values of 101.0 appear between the rows with values of 1109.0 and 1011.0.
  8. Double-click on a table entry. By default, the table entries are editable but any changes you make are temporary.

As mentioned before, this demo requires only these lines of XML:

<?xml version='1.0'?>
  <om:resource xmlns:om="http://www.openmarkup.net/2004/05/om"
                  xmlns="http://www.jdesktop.org/2004/05/jdnc">
    <table>
      <tabularData source="weather.txt"/>
    </table>
  </om:resource>
Let's examine the code, line by line. You might want to refer to simpleTable.jdnc and the JDNC Schema.
The <xml> tag is a standard XML declaration.

The <om:resource> element is called the root element. The prefix in the <resource> tag, in this case om, defines the namespace of the root element. This start tag is matched by an </om:resource> end tag.

The <table> tag indicates that the data will be displayed in an instance of a high-level JDNC component, a JNTable, and is also matched by the </table> end tag.

The <tabularData> tag describes where the data comes from. In this case, it specifies the location of a text file, though it could also be a URL. The URL might point to a file or a servlet that talks to a database or an Enterprise JavaBeansTM component. No other information is provided about the format of the data, so JDNC doesn't know, for example, that several columns contain floating point numbers or that column7 contains time stamps or that column10 contains integers. The data is displayed without any sort of processing or filtering.

Given its minimal specification, this demo performs fairly well. But our next demo illustrates that, with some additional XML, the JDNC table component can be more powerfully leveraged.

Demo: betterTable

The betterTable example extends the simpleTable example by processing and filtering the incoming data to improve readability. Improvements include:

Version note:  The changes made while running the demo are temporary — they are not written back to the data source. Writing data back to the data source will be available in the next release.

The betterTable example


Try this: 
  1. Run betterTable using Java Web Start. You can also run it from the command line (using run demo\betterTable.jdnc [on Microsoft Windows] or run.sh demo/betterTable.jdnc [on Unix]).
  2. Double-click a Temperature value and enter random text, such as foo. The box is outlined in red and the focus remains on the text field. JDNC automatically validates the temperature and rejects non-numeric values.
  3. Re-enter the Temperature in a numeric format. Since the column is defined as floating point, any integer or decimal value is accepted.
  4. Double-click a Country value. Nothing happens since this column is defined to be read-only. If this column weren't defined to be read-only, a combo box would appear with all the possible enumerated values to select from.
  5. A button with a column image, The column display button, is displayed at the end of the row of column names, also called the column header. This feature becomes available when the table is defined with the attribute columnCloakEnabled="true".
  6. Click on the The column
    display button button. A combo box containing a list of the columns appears. A check next to a column name indicates that the column is currently displayed. Select a value, such as Code. The column is removed from the table.
  7. Select the Code value again. The column reappears, in the last column position.
  8. Select a compass icon. Because this column is writable, a combo box appears allowing you to select another wind direction. Select a new compass direction.

The betterTable.jdnc file contains everything necessary to define the demo. It uses the <metaData> tag to inform JDNC about the specific types and formats of the incoming data:
<tabularData source="data/weather.txt">
    <metaData>
	<columnMetaData name="ICAO"/>
	<columnMetaData name="STATION"/>
	<columnMetaData name="REGION"/>
	<columnMetaData name="COUNTRY"/>
	<columnMetaData name="ELEVATION" dataType="float"/>
	<columnMetaData name="LATITUDE" dataType="float"/>
	<columnMetaData name="LONGITUDE" dataType="float"/>
	<columnMetaData name="TIMESTAMP"/>
	<columnMetaData name="TEMPERATURE" dataType="float"/>
	<columnMetaData name="DEWPOINT" dataType="float"/>
	<columnMetaData name="HUMIDITY" dataType="integer"/>
	<columnMetaData name="VISIBILITY_QUAL"/>
	<columnMetaData name="VISIBILITY" dataType="float"/>
	<columnMetaData name="WIND_DIR"/>
	<columnMetaData name="WIND_DEG" dataType="integer"/>
	<columnMetaData name="WIND_SPEED" dataType="float"/>
	<columnMetaData name="GUST_SPEED" dataType="float"/>
    </metaData>
</tabularData>

All the columns of data must be defined in the <metaData> block and in the correct order of arrival. Later when the data is displayed in the view, the ordering can be changed and any columns can be ignored if they aren't relevant to the application. The "name" attribute provides a handle to a particular column. Supported data types are:

An <enumeration> can be defined for the values in a table's column and, for an editable column, the values are displayed in each cell inside a combo box. An enumeration maps one set of strings to another set of strings and/or images. For example, on a column containing values from "1" to "5", the values "1", "2", "3", "4", and "5" can be remapped in the view to "Mild", "Medium", "Spicy", "Very Spicy", and "Four Alarm", respectively. Or, these values can be remapped to images — the "1" represented by a blank image, the "2" by an image of one chili, the "3" by two chilis and so on. In the betterTable example, the Country column is mapped to both text (a sometimes-shortened version of the country name) and images (the country's flag), and the Wind Direction column is mapped to images of a compass pointing in the appropriate direction.

When defining an enumeration, typically inside a <defs> block, the "value" attribute must be literal (no metacharacters) and are tested against the incoming values. This is a snippet of the flag enumeration used in the betterTable example:

  <om:defs>
      <enumValues xml:id="flags">
        <enumeration value="Afghanistan" title="Afghanistan"
			icon="images/flags/afghanistan.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
	<enumeration value="Albania" title="Albania"
	                icon="images/flags/albania.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
        <enumeration value="Algeria" title="Algeria"
	                icon="images/flags/algeria.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
        <enumeration value="Angola" title="Angola"
	                icon="images/flags/angola.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
        ...
	<enumeration value="Yugoslavia" title="Yugoslavia"
	                icon="images/flags/yugoslavia.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
	<enumeration value="Zaire" title="Zaire"
	                icon="images/flags/zaire.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
	<enumeration value="Zambia" title="Zambia"
	                icon="images/flags/zambia.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
        <enumeration value="Zimbabwe" title="Zimbabwe"
	                icon="images/flags/Zimbabwe.gif"
			horizontalAlignment="trailing"
			horizontalTextPosition="leading"/>
      </enumValues>
  </om:defs>
The <defs> element is the place to define elements that will be referred to by ID and possibly shared across elements elsewhere in the jdnc file. All tags defined within the <defs> element must have an "xml:id" attribute or they can't be referenced.

Note:  The "id" is used only in the jdnc file, it isn't assigned to anything in the instantiated object. The "name" attribute, however, is assigned as a property value on the instantiated object. This distinction becomes more important when combining the programmatic I/F with a JDNC markup file.

The "title" and "icon" attributes are optional, but if you want text to be displayed in the column, the "title" attribute is required. When both an icon and text are present, the "horizontalAlignment" and "horizontalTextAlignment" attributes determine whether the icon appears before (leading), or after (trailing) the text. In the previous code snippet, the text is positioned before the icon.

Once the incoming data has been specified, all that remains is to define how the data will be displayed. This is accomplished using the <columns> block:

    <columns>
	<column title="Station" binding="STATION"/>
	<column title="Country" binding="COUNTRY" isReadOnly="true"
	        enumValues="#flags"
		prototypeValue="this is a really really long field"/>
	<column title="Code" binding="ICAO" horizontalAlignment="center"/>
	<column title="Time" binding="TIMESTAMP"
	        prototypeValue="this is a really really long field"/>
	<column title="&#176;C" binding="TEMPERATURE"
	        horizontalAlignment="center"/>
	<column title="Wind Direction" binding="WIND_DIR"
	        enumValues="#compass"/>
	<column title="Direction" binding="WIND_DEG"
	        horizontalAlignment="center"/>
	<column title="Wind Speed" binding="WIND_SPEED"
	        horizontalAlignment="center"/>
	<column title="Gust Speed" binding="GUST_SPEED"
	        horizontalAlignment="center"/>
    </columns>
The order of the <column> tags determines the display order of the columns. The "binding" attribute ties the table column to a specific column in the data. The "enumValues" attribute ties the flag enumeration to the Country column and the compass enumeration to the Wind Direction column. By default, all columns are writable. When a column is defined with an enumeration, clicking on an entry in that column brings up a combo box with all the possible values in the enumeration. To make the country column read-only, the isReadOnly="true" attribute is used. Some columns, such as Time, specify a "prototypeValue" attribute; if set, this value is used to calculate the preferred width for that column. Any column omitted from the <columns> block is not displayed.

Note that HTML can be used in the string literals. For example, the title for the temperature column is defined as &#176;C, which produces °C. It's necessary to use the ISO numeric code rather than the character name — &deg; causes build errors.

The <highlighters> block specifies custom highlighting for table cells:

    <highlighters>
        <alternateRowHighlighter oddRowBackground="#EEEEFF" evenRowBackground="#CCCCFF"/>
    </highlighters>
The <alternateRowHighlighter> tag highlights every other row, and the optional "evenRowBackground" and "oddRowBackground" attributes allow you to specify the colors. The default color for odd rows is white, and the default color for even rows is beige. Some flags have a white background, so the default white background on the odd rows was visually distracting; changing the default white to light blue causes the flags to stand out rather than fade into the background.

Note:  Colors may be specified either in hexidecimal, such as "#EEEEFF", or by SVG name, such as "white" or "lightgray". You can find a complete list of supported color names on the SVG website.

The status bar displays the number of rows and columns in the table in a view underneath the table. To enable the status bar, use the <statusBar> tag inside the <rootPane> block:

  <rootPane>
    ...
    <statusBar/>
  </rootPane>
The <rootPane> tag is probably familiar to most Swing developers as the JRootPane instance. This is the block where the view's components are defined. Each application has one and only one <rootPane>.

[BUG: Currently there is a bug when you specify a <statusBar> in the jdnc file. The bar is displayed, but it has no statistics. This will be fixed soon.]

Hands On: Modify betterTable Example

Now it's time to test your newly acquired knowledge. To proceed you must have your development environment configured, as explained in What You Need to Get Started. It is also suggested that you create a copy of betterTable.jdnc, called betterTableEx1.jdnc, for example, and make your changes to that file. When you run your modified demo, make sure you specify the new name on the command line:
            run demo\betterTableEx1.jdnc     [Microsoft Windows]
	    run.sh demo/betterTableEx1.jdnc  [Unix]

These exercises use tags that you haven't seen before, so you will want to reference the JDNC Schema.


Exercise 1: Column Alignment and Colors 

For these exercises you might find the SVG color name table useful.

1A: The values in each displayed column can be constrained to the center, leading, or trailing positions. In a column that contains both an image and text, such as Country, you can control whether the image is before or after the text. In the Country column, position the text after the icon for Canada only. [5 minutes] Solution

1B: The table header, where the column names are displayed, is typically displayed with a gray background. Change the color of the header background to any shade of blue. [5 minutes] Solution

1C: The background colors of the table rows alternate between light blue and medium blue. Change the background colors to yellow and orange. [5 minutes] Solution


Exercise 2: Pattern Matching 

The <patternHighlighter> tag allows you to specify custom highlighting based on regular expressions. JDNC supports the regular expression syntax defined in the 1.4 release of the Java 2 Platform, Standard Edition. See the Regular Expressions lesson in The Java Tutorial for more information.

You might also want to look up <patternHighlighter> in the JDNC Schema.

2A: Use the <patternHighlighter> tag inside of the <highlighters> block to assign red text to any country with a name beginning with B or M. Note that the regular expression is matched to the incoming data string, not the enumerated string. [10 minutes] Solution.

2B: Change the text color all Canadian weather samples to royal blue. [5 minutes] Solution.


Version note:  At this time pattern matching can be performed on strings only, so it isn't possible to assign colors to temperatures, for example, unless you are willing to treat the temperature column as a string — the drawback to this approach is that sorting would then occur alphabetically, rather than numerically. Future releases will support pattern matching on other data types.

Exercise 3: Sorting 

By default, JDNC's table component supports interactive column sorting so that users can dynamically click on columns to control the sorted view. Sometimes a client may want to define an initial sort order to be displayed when the table first appears. This can be done using the <sorter> tag.

You can look up the <sorter> element in the JDNC Schema.

3A: Use a <sorter> tag inside a <filters> block to sort the rows based on temperature. [10 minutes] Solution

3B: Run the demo. By default, the rows are sorted in ascending order. Change the demo to sort in descending order using the "direction" attribute. [5 minutes] Solution

3C: Now that the temperatures are sorted, it might be interesting to sort within a temperature value based on latitude to see which of the -29°C temperature samples is nearest the North Pole, for example. Add the Latitude column to the view and add a secondary sort on that column. [5 minutes] Solution


Demo: tabTable

This final table example, tabTable, illustrates these features:

Tab #1: Countries Beginning with 'E'

The data source for this table is the same flat file we've seen in other examples but now the <filters> tag filters the data based on a regular expression. In this case, the weather stations from countries beginning with the letter 'E' only are displayed.

The tabTable example: the first tab

Tab #2: Search Panel on Rows with Latitude >= 60

The data source for this table is a flat file containing weather samples from weather stations with a latitude equal to or greater than 60 degrees. A search panel allows you to interactively filter the data based on Country.

The tabTable example: the second tab

Tab #3: Search Panel on all Weather Samples

Once again, the data source is the flat file containing all weather samples. A search panel allows you to interactively filter the data based on ICAO Code.

The tabTable example: the third tab


Try this: 
  1. Run tabTable using Java Web Start. You can also run it from the command line (using run demo\tabTable.jdnc [on Microsoft Windows] or run.sh demo/tabTable.jdnc [on Unix]), if you prefer.
  2. The data source for the table under the first tab, "Stations in Countries Beginning with 'E'", is the same flat file we've used before but a filter in the XML file causes any sample taken in a country not beginning with the letter 'E' to be ignored.
  3. Select the "Northern Stations (Latitude >= 60)" tab.
  4. The data for this table comes from a flat file that has limited the samples to those from stations at latitudes nearer the North Pole. When pulling data from a live data source, it is possible that the source will allow some form of query to be specified within the tabularData tag. This table displays the Latitude column.
  5. Use the search field to search on the Country column. Select Country "contains" and enter "an". As you type the a, all the rows that don't contain 'a' in the country's name are filtered out. As you type 'n', the rows are further filtered.
  6. Select Country "begins with" and enter "s". All of the rows from "Sweden" appear.
  7. Click on the "Match Case" check box. All the rows disappear unless you typed "s" in upper case.
  8. Select the "All Weather Stations" tab. This table uses the original flat file containing all the weather samples.
  9. Use the search field to filter rows on the Code column. Select Code "begins with" and enter "p". All the rows with an ICAO code beginning with "P" appear.

The tabTable.jdnc file contains the XML code to specify the demo. The <tabbedPane> tag creates the tabbed pane. Within the <tabbedPane> block, three tables are defined one after another — JDNC places each table in its own tab:
  <tabbedPane>
    <table title="Stations in Countries Beginning with 'E'"...>
      ...
    </table>
    <table title="Northern Stations (Latitude >= 60)"...>
      ...
    </table>
    <table title="All Weather Stations"...>
      ...
    </table>
  </tabbedPane>
The table in the first tab, Stations in Countries Beginning with 'E', uses the <patternFilter> tag inside a <filters> block to display only rows that match a specific criteria, in this case rows where the Country column begins with E.:
  <filters>
    <patternFilter expression="E.*" match="caseInsensitive unicodeCase"
                   testColumn="COUNTRY"/>
  </filters>
The "expression" value can be any regular expression recognized by java.util.regex.Pattern.compile. The "match" attribute can be one or more of the following: The "testColumn" attribute specifies the name of the column in the <metaData> block.

The second tab contains the Northern Stations (Latitude >= 60) table. The data comes from a pre-filtered flat file, northernlatitudes.txt — a custom servlet will probably support specifying a query in the URL to fetch the rows of interest.

In addition to pre-filtering the data, the table uses a search field to allow the user to dynamically filter the data. This requires two simple steps:

That's all there is to it. The search field will now appear in the view above the table. The column name appears as a label, a combo box allows the user to select "begins with", "contains", "ends with" or "equals", and a "Match case" check box allows the user to restrict case sensitivity.

The third tab contains the All Weather Stations table which uses the complete weather.txt flat file for the data. In this case, the search field searches on the ICAO Code string:

  <filters>
    <patternFilter xml:id="codeFilter" testColumn="ICAO"/>
  </filters>
  <toolBar>
    <searchPanel patternFilter="#codeFilter"/>
  </toolBar>

Hands On: Modify tabTable Example

It's time to test some of the concepts introduced in the tabTable example. See the introduction to Hands On: Modify betterTable Example if you haven't already done any of the exercises.

Exercise 4: Data Filtering 

The following exercises require some knowledge of regular expressions. See the Regular Expressions lesson in The Java Tutorial for more information on the regular expression support introduced in the 1.4 release of the Java 2 Platform, Standard Edition.

4A: Modify the <patternFilter> in the first table to display only samples from countries beginning with letter 'A' through letter 'J'. [10 minutes] Solution.

4B: Modify the <patternFilter> in the first table to display only samples from weather stations identified as airport locations. [10 minutes] Solution.


Exercise 5: Searching 

5A: Modify the search field in the third table (All Weather Stations) to search on the Station column. Run the demo and, in the All Weather Stations table, search on "Station contains Air". Compare the results to the results from Exercise 4B. They should be the same. [10 minutes] Solution.


Demo: treeTable

This demo introduces a new high-level JDNC component — the hierarchical tree table. The <treeTable> example displays a process tree for a particular server. Although a custom servlet could be used to provide live access to this data, the example uses a generated flat file, pstree.txt.

The treeTable example

[BUG/PENDING: There is currently a bug where the custom icons aren't displayed. Update this screenshot when the bug is fixed.]


Try this: 
  1. Run treeTable using Java Web Start. You can also run it from the command line (using run demo\treeTable.jdnc [on Microsoft Windows] or run.sh demo/treeTable.jdnc [on Unix]), if you prefer.
  2. Click the first down-arrow in the Process ID column. The entire tree table collapses. A right-arrow replaces the down-arrow indicating that this node can be expanded.
  3. Double-click the same Process ID. The tree table expands. Double-clicking the Process ID is the same as clicking the arrows.
  4. Move the columns around. The hierarchical column, Process ID, can appear in any location.

The treeTable.jdnc file contains the XML code to specify the demo.

You may have noticed that the treeTable example displays a custom title, Server Process Tree, in the window's title bar. This was accomplished using the <app> tag inside the <defs> block:

  <om:defs>
    <app xml:id="pstree" title="Server Process Tree" versionString="1.0"/>
    ...
  </om:defs>
The <app> tag allows customization of the following application-level properties: Once the <app> tag is defined, it is referenced in the <rootPane> tag:
    <rootPane app="#pstree">

The high-level tree table component is defined using the <treeTable> tag:

    <treeTable preferredSize="704 528" columnMargin="0"
               rowHeight="28" source="data/pstree.txt"
	       expandedIcon="images/close.png" collapsedIcon="images/open.gif"
	       containerIcon="images/gears.png" leafIcon="images/gear.gif">
The "source" attribute is required. In this demo, the data source is a flat file that was created from a WebService, but a live URL may also be specified. The <metaData> for this demo is fetched from the data source. You can examine the <metaData> specification in the pstree.txt file. This format is loosely based on the WebRowSet schema defined by JSR114. A future version of JDNC will migrate to use the WebRowSet APIs, at which time the official WebRowSet schema will be supported.

The tree table icons are specified using the "expandedIcon", "collapsedIcon", "containerIcon", and "leafIcon" attributes. JDNC provides default images so this step is optional.

The <hierarchicalColumnHighlighter> tag in the <highlighters> block calls attention to the hierarchical column (in this case, the Process ID column) by painting its background in slightly darker values:

  <highlighters>
    ...
    <hierarchicalColumnHighlighter/>
  </highlighters>

Hands On: Modify treeTable Example

It's time to test some of the concepts introduced in the treeTable example. See the introduction to Hands On: Modify betterTable Example if you haven't already done any of the exercises.

Exercise 6: xxx 

6A: Remove the custom icons from the treeTable demo. Run the demo to see what the standard provided icons look like. Solution.


[PENDING: Stay tuned.]

Demo: editorDemo

The editorDemo example introduces the high-level JDNC text editor component. This component extends Swing's editor pane and supports:

The editorDemo example


Try this: 
  1. Run editorDemo using Java Web Start. You can also run it from the command line (using run demo\editorDemo.jdnc on [Microsoft Windows] or run.sh demo/editorDemo.jdnc [on Unix]), if you prefer.
  2. Click in the "Jabberwocky" string so that the insertion cursor appears. The "centered paragraph" icon is selected.
  3. Click in the "Lewis Carroll" string. The italic and underline icons are now selected, as well as the centered paragraph. [BUG: Currently, in these two steps the left-aligned paragraph icon is actually selected.]
  4. Click Format to bring up the text-formatting submenu. The Italic and Underline menu items are checked and the center paragraph menu item is selected. The menu items and the tool bar icons are in synch thanks to JDNC's actions framework.
  5. Select some text. Type control-X. The text is moved to the clipboard and removed from the text area.
  6. Move the insertion cursor and type control-V. The text is copied from the clipboard to the new location. [BUG: There is some weird formatting problems when I do this.]
  7. Select the "Find" button - this is depicted as a pair of binoculars.
  8. Enter "Jabber" into the text field of the search panel and find all the instances of this string.

The editorDemo.jdnc file contains the XML code to specify the demo; the primary work in this file is setting up the actions, such as cut, paste, italicize, and then using those actions to create the menu and toolbar. Then the data file, jabberwock.html, is specified — everything else is handled by JDNC.

Here's the action tag for the File menu:

  <om:defs>
    <action xml:id="file-menu" title="File" mnemonic="F"
            description="File Operations"/>
    ...
  </om:defs>
The value of the "title" attribute is used as the string in the GUI, and the value of the "description" attribute is used for the tool tip. The "mnemonic" attribute is a keyboard shortcut — when the user types alt-F, the File submenu is displayed.

The EditorKit has built-in support for the following actions:

The value of the "xml:id" attribute for these actions matches the id keys in the ActionMap:
  <action xml:id="cut-to-clipboard" title="Cut" mnemonic="C"
          smallIcon="/toolbarButtonGraphics/general/Cut16.gif"
          icon="/toolbarButtonGraphics/general/Cut24.gif"
          accelerator="control X" description="Cut to clipboard"/>
The "accelerator" attribute describes the value of the keyboard accelerator. The accelerator is for the power user — this action is always available even if not presently displayed in the GUI. For further discussion of accelerators versus mnemonics, see Enabling Keyboard Operation, a section in The Swing Tutorial.

The "icon" attribute is the 24x24 image used in the tool bar. The "smallIcon" attribute is the 16x16 image used in the menu. When the path is prefixed by "/", as in icon="/toolbarButtonGraphics/general/Print24.gif", then JDNC looks in the resources of the classpath for the image. These images are part of the Java Look and Feel Graphics Repository (jlfgr-1_0.jar), which is included in the bundle for this tutorial.

For more information on loading resources, see the documentation for java.lang.Class.getResource(String).

The StyledEditorKit has built-in support for the following actions, most of which are toggle actions:

The action "xml:id" attribute is specified using these strings:
    <action xml:id="right-justify" isToggle="true" title="Right Align"
            group="paragraph-align" mnemonic="R"
	    smallIcon="/toolbarButtonGraphics/text/AlignRight16.gif"
	    icon="/toolbarButtonGraphics/text/AlignRight24.gif"
	    description="Adjust the placement of the text along the right side"/>
The "group" attribute tells JDNC that the grouped actions, which are toggle actions, are mutually exclusive — selecting one will de-select the others.

Defining the actions in the <defs> block makes it easy to share them between tool bars, menus and popups. The menuBar block is used to build the menu, using the actions already defined as well as new (placeholder) actions for New and Open:

  <menuBar>
    <menu actionRef="#file-menu">
       <action xml:id="new-command" title="New" mnemonic="N"
                smallIcon="/toolbarButtonGraphics/general/New16.gif"
		description="Create a new document (dummy command)"/>
       <action xml:id="open-command" title="Open" mnemonic="O"
                smallIcon="/toolbarButtonGraphics/general/Open16.gif"
		description="Open an existing document (dummy command)"/>
    </menu>
    <menu title="Edit" mnemonic="E" description="Edit Commands">
      <action actionRef="#cut-to-clipboard"/>
      <action actionRef="#copy-to-clipboard"/>
      <action actionRef="#paste-from-clipboard"/>
      <separator/>
      <action actionRef="#undo"/>
      <action actionRef="#redo"/>
    </menu>
    <menu title="Format" mnemonic="O" description="Text Formatting Commands">
      <action actionRef="#font-bold"/>
      <action actionRef="#font-italic"/>
      <action actionRef="#font-underline"/>
      <separator/>
      <action actionRef="#left-justify"/>
      <action actionRef="#center-justify"/>
      <action actionRef="#right-justify"/>
    </menu>
  </menuBar>
The <menu> block defines each submenu. The <separator> tag tells JDNC to paint a line dividing the menu items.

The <toolBar> is defined in the same manner as the menu:

  <toolBar>
    <action actionRef="#font-bold"/>
    <action actionRef="#font-italic"/>
    <action actionRef="#font-underline"/>
    <separator/>
    <action actionRef="#cut-to-clipboard"/>
    <action actionRef="#copy-to-clipboard"/>
    <action actionRef="#paste-from-clipboard"/>
    <action actionRef="#undo"/>
    <action actionRef="#redo"/>
    <separator/>
    <action actionRef="#find"/>
    <action actionRef="#print"/>
    <separator/>
    <action actionRef="#left-justify"/>
    <action actionRef="#center-justify"/>
    <action actionRef="#right-justify"/>
    <separator/>
    <action actionRef="#about"/>
  </toolBar>
Finally, the <editor> tag uses the "source" attribute to specify the location of the source file:
  <editor source="jabberwock.html">
In the <editor> block an optional <popupMenu> is specified in the same manner as the menu and tool bar:
  <editor source="jabberwock.html">
    <popupMenu>
      <action actionRef="#cut-to-clipboard"/>
      ...
    </popupMenu>
  </editor>

Note:  The <popupMenu> tag is supported in all the high-level JDNC components: tree, table, treetable, form and editor.
For the actions that require customization, such as open, new, print, and about, the properties of the action (ie: command name, icon, keyboard shortcuts) are configured using the XML file. But the work, or semantics, of the action is implemented in Java code. A tutorial featuring the programmatic interface for JDNC is in the works.

Hands On: Modify editorDemo Example

It's time to test some of the concepts introduced in the editorDemo example. See the introduction to Hands On: Modify betterTable Example if you haven't already done any of the exercises.

Exercise 8: Configuring Actions 

For the following exercises, you will find the Java Look and Feel Graphics Repository (jlfgr-1_0.jar) useful.

8A: An action is defined for the built-in "Find" support of the editor kit but it's been added only to the toolbar. Add searching support to the menu and popup menu. [15 minutes] Solution

8B: The New and Open items were placed in the menu only. Add them to the tool bar and popup menu. [20 minutes] Solution

8C: Add a refresh action that reloads the source file on demand. [15 minutse] Solution


Demo: formDemo

[NOTE: This section is still under development.]

The formDemo example introduces the high-level JDNC form component — this component makes it easy to construct forms by binding a form to named fields on a data model, such as a column on a TabularDataModel (or RowSet), a property on a JavaBeans component, or a key on a map of named values.


Note:  Currently, the XML form supports binding only to a single data model, but this will be changed in a future release to support binding to multiple data models. The programmatic I/F does support binding to multiple data models.

The formDemo example

[PENDING: Update this screenshot.]


Try this: 
  1. Run formDemo using Java Web Start. You can also run it from the command line (using run demo\formDemo.jdnc [on Microsoft Windows] or run.sh demo/formDemo.jdnc [on Unix]), if you prefer.

The formDemo.jdnc file contains the XML code to specify the demo. The GUI is implemented as a split pane with a table in the top view and the form in the bottom view. Unlike previous examples, the tabularData tag is placed inside the defs tag — this allows the data to be shared by the form and the table. The overall structure of the demo is like this:
  <om:defs>
    <tabularData xml:id="weatherdata">
      <metaData>
        ...
      </metaData>
    </tabularData>
  </om:defs>
  <rootPane>
    <splitPane>
      <table>
        ...
      </table>
      <form>
        <components>
	  <component>
	  <component>
	  ...
	</components>
      </form>
    </splitPane>
  </rootPane>
The first component defined in the <splitPane> block appears in the top view (or left view, depending upon orientation) and the second component appears in the bottom (or right) view. The orientation is specified as an attribute:
  <splitPane orientation="vertical" background="#EEEEEE">
The <table> definition is much like what you've seen before, except this time it references the data defined in the <defs> block:
  <table xml:id="weathertable" data="#weatherdata" title="Weather Stations"
        showHorizontalLines="false" showVerticalLines="false"
        preferredSize="550 200" background="#EEEEEE">
Here is the declaration for the <form>:
  <form data="#weatherdata" tracks="#weathertable" background="#EEEEEE"/>
The form uses the information in the <metaData> block to determine which columns accept input, how wide to make the text field, and the text used for the label. For example:
  <metaData>
    <columnMetaData name="ICAO" displaySize="4" title="Code"/>
    <columnMetaData name="STATION" displaySize="25" title="Station"/>
    <columnMetaData name="REGION" isReadOnly="true" title="Region"/>
  </metaData>
The "title" attribute is used as the label for the form's text field. The "displaySize" attribute determines the preferred width of the text field. The isReadOnly="true" statement causes that column's value to be displayed, but non-editable. Other attributes allow you to specify the minimum and maximum values for numeric columns.

The "reset" and "submit" buttons are created automatically in the form:

Note that these actions are only partially implemented. Use the programmatic I/F to complete the implementation.

Hands On: Modify formDemo Example

It's time to test some of the concepts introduced in the formDemo example. See the introduction to Hands On: Modify betterTable Example if you haven't already done any of the exercises.

[PENDING: Stay tuned]

Where to Find More Information

Last updated: 5/28/04.