Switch to German language Switch to English language

Architecture Database Client modules XML modules XML panel Features Example ERP application

XML modules

XML modules offer the advantage that they can be created very easily and fast. Nevertheless they offer the ability of being changed and enhanced as desired by own code. A XML module provides a fully operational base for data processing which can be adjusted and expanded if necessary. The appearance and basic functionality of XML modules is defined by XML files in the project. Among other things the following points are defined:

Example

A very simple example demonstrates how easy and fast it is possible to create a new XML module. We assume that a project has been set up and runs. In our example we want to create a small module for managing items in a shop.

Database

We begin with defining the database table which stores the data records for the module. It looks as follows:

<table name="Article" description="Articles">
  <column name="nArticleNr"       type="int"                    nullable="false"/>
  <column name="sArticleCode"     type="varchar"  length="12"   nullable="false"/>
  <column name="sName"            type="varchar"  length="30"   nullable="false"/>
  <column name="sDescription"     type="varchar"  length="1024" nullable="true"/>
  <column name="sArticleGroup"    type="char"     length="4"    nullable="true"/>
  <column name="sDimension"       type="char"     length="2"    nullable="true"/>
  <column name="fPrice"           type="float"                  nullable="true"/>
  <column name="sStorageLocation" type="char"     length="1"    nullable="true"/>
  <column name="fInventory"       type="float"                  nullable="true"/>
  <column name="sVendor"          type="varchar"  length="30"   nullable="true"/>
  <column name="dtDate"           type="datetime"               nullable="true"/>
  <primaryKey name="pkArticle">
    <column name="nArticleNr"/>
  </primaryKey>
</table>

The information in this XML segment is likely to be self-explanatory. We define a table with the name Article. This table has several columns/fields (tag column) and one primary key (tag primaryKey) in form of a serial number for each record. Name, data type, possibly a length, and nullable state are set for each column. The table is created as defined in the database after a server restart.

Panel

Appearance and functionality of the panel (i.e. edit mask) are described in another XML file. (Swing-) components (widgets) are placed on the panel. This panel should provide the opportunity to search, modify, delete and create records. It models the classic CRUD functionality. First some general information like the name of the database table, the primary key, and the ID of a search dialog is defined.

<?xml version="1.0" encoding="UTF-8"?>
<xmlpanel>
  <configuration
    table="Article"
    searchDialog="articleSearchDialog"
    recordControlPattern="{0}"
  >
    <primaryKey>
      <column name="nArticleNr" type="INT" source="AUTO" />
    </primaryKey>
  </configuration>

It follows the definition of the search dialog which will be used to search for records in the database table. This dialog will be opened as soon as the user clicks on the search button at the panel.

<searchDialog
  id="articleSearchDialog"
  title="Article search"
  autoResizeMode="AUTO_RESIZE_OFF"
  size="670 500"
  table="Article"
  where=""
  orderBy="sName"
>
  <column title="Name"          field="sName" width="220" minWidth="10" maxWidth="300"/>
  <column title="Article code"  field="sArticleCode"  width="100" minWidth="10" maxWidth="120"/>
  <column title="Article group" field="sArticleGroup" width="100" minWidth="10"
      maxWidth="120" type="COMBOBOX">
    <item text="Book"        value="BOOK" />
    <item text="CD"          value="CD  " />
    <item text="Clothing"    value="CLOT" />
    <item text="Electronics" value="ELEC" />
  </column>
  <column title="Price"         field="fPrice" width="60" minWidth="10"
      maxWidth="120" type="NUMBER" alignment="RIGHT" pattern="#.00"/>
  <column title="Dimension"     field="sDimension" width="80" minWidth="10"  
      maxWidth="120" type="COMBOBOX">
    <item text="pieces"     value="P " />
    <item text="meter"      value="M " />
    <item text="litre"      value="L " />
    <item text="kilogram"   value="KG" />
  </column>
  <column title="Inventory"     field="fInventory" width="70" minWidth="10"
      maxWidth="120" type="NUMBER" alignment="RIGHT" pattern="#.0"/>
</searchDialog>

This section describes the appearance of the dialog, the columns, and the database table/columns. In the running client the search dialog will look like that:

Example of a search dialog: Article search

Above the table with the found records there are text fields and combo boxes in order to restrict the search results. It is also possible to use wildcards as * for any number of characters or ? for exact one character. Numerical values like the price or the inventory can be specified with a from-to range. By double-clicking a record (or choosing + Ok) the data row is transferred into the edit form and can be changed there.

Now we define the appearance of the edit mask with its components. It starts with the definition of a container (panel) in which the individual components (widgets) are placed. If no layout manager is specified for the top-level panel the default is a GridBagLayout. This arranges the widgets in form of a table. First of all there should be a label and a text field for entering the article code on the panel:

<panel id="main" widgetGroupID="">
  <label text="Article code:"
    constraints="0 0 1 1 0.0 0.0 EAST NONE 5 5 0 0 0 0"
  />
  <textField
    id="idArticleCode"
    name="Article code"
    toolTipText="Article code"
    constraints="1 0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
    obligatory="true"
    size="100 21"
    field="sArticleCode"
    type="STRING"
  />

The attribute constraints determines the placement of the widget inside the layout manager, here inside a GridBagLayout. The individual values define the parameter for a GridBagConstraints object and specify column, row, width in cells, height in cells, horizontal and vertical expansion (with automatic resizing), alignment, automatic resizing, and borders (more about that you can find in the Java documentation). Column and row can also be set relative to the previous component as you will see further down.

The text field gets an id in order to have access to this widget inside Java source code, if this should be necessary (in our example we don't need this and so we could have omitted the id). A name (for error messages), a tooltip text, and the size of the text field is set. At last the database table field for storing the entered values and the data type follows. The specified data type is important for checking and converting the values. With obligatory="true" it is defined that an input is mandatory. Without input in this field the row will not be saved and the user will get an error message.

Next follows an input field for the article name:

<label text="Name:"
  constraints="2 0 1 1 0.0 0.0 EAST NONE 5 15 0 0 0 0"
/>
<textField
  id="idName"
  name="Name"
  toolTipText="Name of the article"
  constraints="3 0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  obligatory="true"
  size="230 21"
  field="sName"
  type="STRING"
/>

The article group will be selectable via a combo box:

<label text="Article group:"
  constraints="0 +1 1 1 0.0 0.0 EAST NONE 5 5 0 0 0 0"
/>
<comboBox
  id="idArticleGroup"
  name="Article group"
  toolTipText="Article group"
  constraints="1 +0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  field="sArticleGroup"
  type="STRING"
>
  <item text="Book"        value="BOOK" />
  <item text="CD"          value="CD  " />
  <item text="Clothing"    value="CLOT" />
  <item text="Electronics" value="ELEC" />
</comboBox>

For simplicity the items in the combo box are set directly in the XML file here. Each item consists of a display and a database value. Of course it is also possible to use a database table as source for the items in the combo box. This would be reasonable in a real life implementation. Editing the master data in that table would be done in a further xml module then.

We continue with a date field in which we want to save the date when the article was added to the inventory.

<label text="Added:"
  constraints="2 +0 1 1 0.0 0.0 EAST NONE 5 5 0 0 0 0"
/>
<dateField
  id="idDate"
  name="Added"
  format="DATE"
  toolTipText="Date added"
  constraints="3 +0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  size="90 21"
  field="dtDate"
  type="DATE"
/>

Each date field has a popup calendar in which a user can select a date. Of course the user can also enter the date manually.

Date input field with connected popup calendar

The price of the article is entered into a number input field:

<label text="Price:"
  constraints="0 +1 1 1 0.0 0.0 EAST NONE 5 5 0 0 0 0"
/>
<numberField
  id="idPrice"
  name="Price"
  toolTipText="Price"
  constraints="1 +0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  obligatory="true"
  pattern="#.00"
  horizontalAlignment="RIGHT"
  size="70 21"
  field="fPrice"
  type="FLOAT"
/>

A number format is declared in order to display the price with two decimal places. Furthermore the number should be aligned to the right.

The input fields for dimension, storage location, inventory, and vendor are realized with combo boxes and text fields:

<label text="Dimension:"
  constraints="2 +0 1 1 0.0 0.0 EAST NONE 5 15 0 0 0 0"
/>
<comboBox
  id="idDimension"
  name="Dimension"
  toolTipText="Dimension"
  constraints="3 +0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  field="sDimension"
  type="STRING"
>
  <item text="pieces"     value="P " />
  <item text="meter"      value="M " />
  <item text="litre"      value="L " />
  <item text="kilogram"   value="KG" /></comboBox>

<label text="Storage location:"
  constraints="0 +1 1 1 0.0 0.0 EAST NONE 5 15 0 0 0 0"
/>
<comboBox
  id="idStorageLocation"
  name="Storage location"
  toolTipText="Storage location"
  constraints="1 +0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  field="sStorageLocation"
  type="STRING"
>
  <item text="Main storage"       value="M" />
  <item text="External storage 1" value="1" />
  <item text="External storage 2" value="2" />
</comboBox>

<label text="Inventory:"
  constraints="2 +0 1 1 0.0 0.0 EAST NONE 5 5 0 0 0 0"
/>
<numberField
  id="idInventory"
  name="Inventory"
  toolTipText="Inventory"
  constraints="3 +0 1 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  pattern="#.##"
  horizontalAlignment="RIGHT"
  size="70 21"
  field="fInventory"
  type="FLOAT"
/>

<label text="Vendor:"
  constraints="0 +1 1 1 0.0 0.0 EAST NONE 5 15 0 0 0 0"
/>
<textField
  id="idVendor"
  name="Vendor"
  toolTipText="Vendor"
  constraints="1 +0 3 1 0.0 0.0 WEST NONE 5 5 0 0 0 0"
  size="300 21"
  field="sVendor"
  type="STRING"
/>

A text area field is used for entering a description of the article:

<label text="Description:"
    constraints="0 +1 1 1 0.0 0.0 NORTHEAST NONE 5 15 0 0 0 0"
/>
<textArea
    id="idDescription"
    name="Description"
    toolTipText="Description"
    constraints="1 +0 3 1 10.0 0.0 WEST HORIZONTAL 5 5 0 0 0 0"
    size="300 80"
    field="sDescription"
    type="STRING"
/>

We conclude the panel with an invisible label which will occupy the entire remaining space on the panel. This will ensure that all other components are arranged in the upper left corner of the panel. Otherwise all components would be arranged in the center which doesn't look very nice.

    <label text=""
      constraints="0 +1 4 1 1.0 1.0 WEST BOTH 0 0 0 0 0 0"
    />
  </panel>
</xmlpanel>

This was the definition of the panel.

Module

After the panel was defined we have to add it to a module. A new XML file for the module has to be created. This file is very short and looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<module>
  <panel
    id="idArticle"
    name="Article"
    toolTipText="Module for article management"
    class="de.aviantes.jaf.client.xmlpanel.editpanel.XMLEditPanel"
    parameter="modules/article/ArticlePanel.xml"
  />
</module>

The module has only one panel here. The Java class which implements the complete panel is declared. A class from the framework is taken because we don't have any extensions in an own class. The attribute parameter specifies the class path from the XML file for the panel (i.g. the file we have created earlier).

Finally this newly defined module has to be registered in the list of all client modules so that the client gets knowledge about this module. This list is a XML file too. The corresponding entry looks as follows:

<module nr="100" id="idArticleModule" name="Article"
  class="de.aviantes.jaf.client.module.general.GeneralModul"
  parameter="modules/article/ArticleModule.xml" />

The class for the module is declared here. This is a standard class from the framework because a self-implemented module was not created. Attribute parameter specifies the path to the module XML file in the class path.

The creation of a simple new module is completed now. This module can be put into the client menu tree and provided with rights in the module management of the client.

Module management at the client

The module is fully functional and looks like this:

Example of a created module: Article module

One data row has been opened and the edit mode has been entered. The buttons in the left upper area have the following functions:

The buttons on the right side allows clicking through data records of the last search or one record can be selected directly from the results in the combo box. The buttons in the middle are used to create and search for bookmarks and to look at the history list.

It is very easy to extend this panel with more widgets now. For that more database fields have to be created in the database table and more widgets have to be added to the XML file of the panel. As soon as some panels are finished this is a pure copy & paste with minor adjustments which is completed within minutes.