JArtifex: Build Java-applications through XML-Tags

  • Introduction, Overview
  • Commandline arguments
  • System variables
  • The Application-Generator (from Database to XML)
  • Applets
  • The Structure
  • The GUI, Layout-managing
  • Communication between Controls
  • The Model/View/Controller Concept
  • The Menu and the Controls
  • Basic Swing-Tags
  • Basic Tag-Properties
  • Events
  • Mouse-Double-Clicks
  • Element-Positions
  • Editfields with validation
  • Timer-Buttons
  • Control-Links, Control-Content
  • Setting or Getting control-properties on Runtime
  • Generic Controls
  • Dynamic Controls
  • Creating own Controls
  • Commands
  • Dynamic calls of java-methods
  • Resulthandling (Linking)
  • Result-handling on Items,Buttons
  • If-clauses and Loops
  • Autostart
  • Dialogcreation
  • Client/Server(RMI)
  • Embedding own Business Objects
  • Creating the help-system
  • New Features
  • Hints, Howto's, FAQs
  • Sample xml-Files
  • Sql-Example
  • Table1: Syntax and special keywords
  • Table2: Common properties
  • Table3: Short feature-reference
  • Introduction, Overview

    Use: Prototyping, Tool/Applet/Application-creation (and Business-Application-creation)
    This program helps you creating a client/server java-application/applet with graphical interfaces and simple logik, very fast and without any Compiler . But it is also possible to create complex applications using JArtifex as a framework and including own classes. Using JArtifex, You have to create a configuration 'xml'-file defining Components with actions und result-Components (=links). So you link each Component to some other.In an abstract way it is possible to write if-clauses, loops and so on. If you want to do something special, it is possible to import your own java-code. So You have three ways to implement your application: xml-file, xml-file with importet java-code, using JArtifex as a framework. JArtifex is able to work with sql-statements, filling the results automatically to components like a jtable. Components (in the xml-file) are defined in the following manner:
     
    <Swing-Component name = "myName"
      cmdtype = "SQL"
      command = "select * from table1"
      link = "swingComponent, NOTNULL:anotherSwingComponent"
      >....embedded  Swing-Components.... 
    </Swing-Component>    

    All properties are optional, so if you want, you are able to generate only a Swing-GUI.
    The xml-File will be read and the elements will be built, the references will be stored and Autostart-Elements will be executed. Now, your elements in your program are able to communicate firing events to other elements.You see in the following lines a short structure of the elements:

    tslObject-> fill
        execute
        onEvent
        getProperties

    If you have to write complex applications, you have to define your own tsl-object, wich will be bounded dynamically (knowing the name) on runtime.
    You can use JArtifex as a framework , then you have to derive the class ' BasicControl ' in the package tsl.controls. The classname is the same you will use in the 'xml'- file as Tagname. You have to override at least the method initspecials(...). There you define, wich JComponent the class shows. For further information, look into the javadoc file of tsl.controls.BasicControl ( BasicControl.html ), the help.txt or send me an email ! The source of Combo.java shows you, how to implement a new Control.

    Program-Start: java.exe -classpath ./; -jar tsl.jar <xml-filename>
    with for example xml-filename = suite

    Creating xml-files: If You want to create 'xml-files', an easy way is to work with the work.xml (start it with: java.exe tsl.jartifex.JArtifex work ). This is a simple texteditor providing you to start Your 'xml-file' and to view all possibilities with the 'visual Constructor' (tslConstruct.xml)
     

    Commandline arguments

    Start 'java -jar tsl.jar -help' to see this screen
    ======================================================================
    == JArtifex, Author: Thomas Schneider, Version: 5.00 (01.05.2004)
    ======================================================================
    Please give at least one argument: the ini-File without 'ini'-extension
    Syntax: tsl.jartifex.JArtifex [-serialize= [options] [program-parameters]
            with option:
                 -debug     	prints debuginformation on standard-output
                 -trace     	prints callstack with every output
                 -server=   	url, specifying the rmi-server for this client
                 -client=   	url, specifying this rmi-server-adress
                 -xpos=     	main-window x-position
                 -ypos=     	main-window y-position
                 -layout=   	java-layout like: windows, motif, mac, metal, organic
    				or the full classname (be sure, it's found by classpath)
                 -help=     	prints this information
                 -nobeep    	no beeps on error-messages
                 -noerror   	no general errordialogs will be shown
                 -test	send action-events from all controls and quit
                 (-serialize= load JArtifex from serialized file)
                 -q         	quickconnection: don't show db-connection-dialog
                 -xmltags=  prints info about basic controls (e.g.: -xmltags or -xmltags=spread)
            with program-parameters:
                 This are parameters that you can use inside your iniFile.
                 You can embedd them like:  for the first parameter.
    ======================================================================
         

    System variables

    Inside the xml files you can use system variables in the same manner as inside ant scripts. For example, you can put into the content of a Textfield the following:
    <Edit   name = "medTest"
            command = "{$user.dir}"
    </Edit>

    The Application-Generator (from Database to XML)

    The generator uses all informations from a given database. These are Tablenames, Fieldnames, Fieldtypes, Foreignkeys. Each table represents a process in the application. All processes are viewable in a TabbedPane. Each process contains an overview (Spread).All table-fields are editable and saveable through the selected line in the overview-spread. The standard-menu contains the item 'Dataselection'. There you can start a search-dialog for the selected process. The generated application is easily extendable (through its xml-files). But the generation-process is dynamic, too. It uses templates (*.tml) to build the xml-files. It's possible to change these tml-files. The substitution tags of these templates start with '${' and end with '}' (like you know from ant). With the xml-files, the generator produces an empty java-controller class, for each table a persistable java-dataobject and help/documentation files (html). To use the dataobjects, implement a method (with a spread parameter) inside the controller class, and create the dataobjects through the spread-dbtablobject.
    Start the generator with:
    java -cp .;tsl.jar;hsqldb/hsqldb.jar tsl.jartifex.ApplicationGenerator [application-name] [db-driver] [db-url] [db-user] [db-passwd]

    or start the example: application-generator.bat
    This example generates an jartifex-application from the timesheet-database. The application-name is 'TestApp'. Go into this directory and start the TestApp.bat to see the it.

    Applets

    You can embed your tsl-program into an applet (look at suite.html ). There are two ways to do it: Very important: All Dialogs (controls with tag 'Dialog') should appear at the end of the 'swing.group'!

    The following applet-parameters are supported:
     
    Name Value
    program programname (this should be an xml-file) without extension (e.g. "suite"). The xml-file should have the tag <JArtifex.programname>
    show_in_html "yes": the applet-content is the contentpane of the swing-elements, "no": an external swing-frame will be built.
    embedded_file "yes": the configuration is embedded inside the html-file. No external xml-file will be read, "no": an external xml-file will be read. 
    debugmode "yes": switch on the debugoutput, "no": no debugoutput will be printed to the standard-output.

    The Structure of an xml-file

    The xml-file has to follow a structure given by the following groups:
    Tag Comment
    <group.Common> common definitions
    <group.Menu> menu-structure
    <group.Swing> interactive controls
    <group.Autostart> control-actions starting after loading

    On any position it is possible to insert the content of a file. This works with the '<include: filename />' tag.
    For an example, look at mr.xml.
            <Edit   name    = "medhhhh1"
                        title   = "Please input a date before today:"
                        tooltip = "Please input a date before today: "
                        type    = "char(&&&&&&&&&) "
                        focuslost = "bnShow "
                        alignment="right ">
            </Edit>
            <include: progress.inc/ >
            <Button name    = "bnPrint"
                title   = "Print"
                cmdtype = "CLS"
                command = "@extern printSpread" >
            </Button>
    The hole content of the file progress.inc will be inserted at the given position.

    The GUI, Layout-managing

    The GUI-elements have to be placed inside the menu-group or inside the swing-group. The following text gives information about the swing-group. The JArtifex works with the GridBagLayoutManager. But it tries to give the user only the most important properties. All properties have a default-value, so it is possible to write only the pur control-tags like <Edit></Edit> to create in a fast way a GUI-prototype. This control-tags like Edit will be invoked dynamically  by searching for the class Edit.class. This Edit-class specializes the class BasicControl. This BasicControl holds the given GUI-component.

    Communication between Controls

    One of the most important things to let your application work, is to define communications between your controls. For example, if a button was clicked and he started an action and this action returned a result. You want to link this result to another control, to fill it, or to start another action. There are several possibilities to get some content of a control or to put some content (e.g. an action-result) into a control.
    There are two kinds of controls: action-controls and no action-controls


    The Model/View/Controller Concept

    It's possible to give the view your own model-instance by using the 'model'-property. This will try to invoke the method 'setModel' for the given component. The parameter for this method will be of the type that your controller-class will return. If it's not the right hierarchical class (like an interface), you have to use the 'modelclass'-property , too. Your model will only be given to the view on starttime.
    Here is an example:
    <JArtifex.modelviewcontroller>
    <group.common>
    title = "ModelViewController"
    extern = "_ExternControllerTest"
    onclose = "exit"
    @Table = "javax.swing.JTable,null,scrollable,container"
    @MyText = "javax.swing.JTextField,null"
    </group.common>
    <group.swing>
    <Table name="tTest" modelview ="Model" modelobject="@extern getModel" modelclass="javax.swing.table.TableModel" width="3">
    </Table>
    <MyText name = "medMyText" model = "AdressText" modelview="Text" modelobject="@extern getAdress">
    </MyText>
    <Button widthstring = "WWWWWWWWWW" title = "updateModel" position = "right" cmdtype = "CLS" command= "@medMyText updateModel">
    </Button>
    <group.swing>
    </JArtifex.modelviewcontroller>
    There are two examples: One for a real model firing tablemodelchanged-events, the other one for a normal businessobject. Both objects will be given by the _ExternControllerTest class and both views are GeneralizedBasicControls defined inside the common-block. For further information look at using own business objects .

    Element-Positions

    Size and Position of the elements belong to a grid, containing all elements. Is the width of your element 2, so the width of this element equals the width of two other elements (with width=1). You have the possibility to use numbers for the position of your element, but it is also possible to built your elements sequently (from left to right and from up to down). So You don't need to define x-pos and y-pos variables, You can use only the constants 'RIGHT' and 'DOWN' ('DOWN' is like a carriage return).
     
    <Edit   name = "medDate"
            position = "right">
    </Edit>

    or:
    <Edit   name = "medDate"
            xpos = "1"
            ypos = "0">
    </Edit>

    Element-Sizes

    Size and Position of the elements belong to a grid, containing all elements. Is the width of your element 2, the width of this element equals the width of two other elements (with width=1). Every BasicControl tells the JArtifex-Program , witch kind of element it is. There are several methods, saying how the BasicControl will be handled:
     
    isAction has no content, gets no result-content, like: Button, Menu
    isContainer contains other controls, like: Panel, Split
    isGrowing grows not only in horizontal but in vertical direction too. like: Panel, Split 
    isScrollable has a Scrollbar, like: Spread, Tree, FileTree, Text

    On default, every control has the width=1 and height=1. On default, every control grows and fills the hole place in horizontal direction. The margin between the controls is given by the common-property margin (default: 0).
    If you wish to define the width of an Edit, Label, Button, Combo, you can use the property widthstring. There you give a string, that will be calculized by JArtifex to get the width of this string and JArtifex will set the minimumsize, preferredsize, maximumsize to this value.

    Example1: Edit should have the width of 10 characters ('W' is the biggest character)
    <Edit   name = "medDate"
            withstring = "WWWWWWWWWW"
            command = "hallo"
            xfill         = "off" >
    </Edit>
    If you want, that the Edit-field should be as width as the string 'hallo', you don't need the widthstring-property

    Example2: Edit should have the width of 10 characters, but it fills the hole place. So only the relativity to other control-widths is given, not the exactly size.
    <Edit   name = "medDate"
            withstring = "WWWWWWWWWW"
            command = "hallo">
    </Edit>

    The Menu and the Controls

    Basic Swing-Tags

    To see a complete list of all tags and its properties, click here short-reference.html

    It is of course possible to define own swing-tags by creating controls extending the class BasicControl .
    The following controls (=Tags) are basic elements (but you can define your own, see Combo.java ):
     
    Control Command Comment
    Popup
    Menu-Popup, where to put Menuitems into (group.Menu)
    Menu X Menuitems inside a Popup. The behavior equals to the Button (group.Menu).
    Dialog
    enables dialog-creation (look at Dialogcreation )
    Edit
    editfield of type: char(n),int(n),date(n),float(n), char(mask), Default:char(256)
    Text
    textfield (multi-line), content will be read from file
    Html

    shows the content of any url
    Combo X combobox. first element will be preselected
    Checkbox X checkbox
    Button X action-button
    Timer X timerfield (invisible) (see timer.xml)
    Rmibutton X RMI-action-button (look at Dialogcreation , Client/Server(RMI) )
    Spread Y table (can be filled by file or sql-statement)
    Graph Y line/column/bulk-graph (will be filled by file or sql-statement)(see graphsheet.xml)
    Page
    tabbedpane-pages. will contain following elements 
    Split
    Splitwindow.will contain the two following elements
    Tree
    tree-object
    Filetree
    tree-object showing a filetree (e.g. work.xml)
    Picture
    shows a picture read from given file (JPG, GIF)
    Progress
    Progressbar to show status-messages and a bulk
    Password
    Password-field
    Paint

    Panel with drawing functionality using java.awt.Graphics methods.
    These are only the basic-controls. Please look into the 'tsl/controls'-directory to see all controls.

    Basic Tag-Properties

    Start 'java -jar tsl.jar -xmltags' to see this screen
    -------------------------------------------------------------------------------
    Possible main-properties are:
    -------------------------------------------------------------------------------
    name         : Identifier of this element
    title            : Title of this element (Default:<not defined>)
    mnemonic  : Hotkey for swing-component (Default: First character of title)
    modelobject: method that returns a model-object from extern
    model         : bean-name for the getter/setter-methods of the model-object
    modelview  : bean-name for the getter/setter-methods of the view-controls
    modelclass : full classname of the transfer-object (model<->view)
    cmdtype    : TXT,EXE,SQL,CLS,READ,WRITE,APPEND,EXIT,OPEN,CLOSE,RELOAD,PRINT
                     : DOFOR,DELETE      (Default: TXT)
    command  : how to fill control or what to do on user-interaction
    type          : control-dependend (e.g. Edit-> char(100) )
    widthstring: any string, defining the width of the control (like Edit, Button, Label, Combo)
    xfill           : fill control in horizontal direction (default:on)
    xpos         : horizontal grid-position of swing-component
    ypos         : vertical grid position of swing-component
    width        : (Number) grid-width of swing-component  (Default: 1)
    height       : (Number) grid-height of swing-component (Default: 1)
    position    : relativ position to last swing-component: RIGHT,DOWN (Def.: DOWN)
    link          : result-elements, separated by ','
                    : clauses: 'NULL:','NOTNULL:', <expression>':', 'NEWWINDOW'
    dblclick    : the name of a control that has to handle the dblclick
    focuslost  : the name of a control that has to handle the focuslost-event
    focusgained: the name of a control that has to handle the focusgained-event
    shortcut    : a character. Pressing this key, the command of this control will be started.
    help          : an Url (like http://www.hallo.de). Pressing F1 this url will be shown.
    enabled    : on/off (default:on)
    visible       : on/off (default:on)
    background : background-color (blue,green,red... or number,number,number)
    foreground : foreground-color (blue,green,red... or number,number,number)
    tooltip       : any text to explain control
    -------------------------------------------------------------------------------

    Events

    The Program-class works as controller, listening to all keyevents of all controls and to the special events of special controls. These you can see in the following table.
    The following events will be handled( -> starting an action):
     
    Control Action
    All doublemouseclick
    Edit return key
    Text Strg+return
    Combo selection
    Checkbox selection
    Button enter, shortcut, mouseclick
    Spread any key, mouseclick
    Tree  selection
    Mouse-Double-Clicks
    All controls can handle the special mouse-double-click. To you this feature, you have to define the special 'dblclick'-property. The value is the name of the control, that will handle the doubleclick

    Example:
    <Spread   name = "medDate"
                    dblclick = "bnShowEditDialog">
    </Spread>
    If a the user do a doubleclick to this spread, the button, showing a dialog will be started. This 'dblclick' is simular to the 'link' property with the following differences:
    1. The value can be exactly one control
    2. The value has to be exactly the name of the control (no properties like 'OnNull:' are handled)
    3. The 'link'-properties will be started or filled on any events. If a 'dblclick' is defined, the 'link' will not handle doubleclicks
    4. The 'dblclick' will start or fill the dblclick-control only on mouse-double-click-events.

    Editfields

    /**
     * There are three ways to define validation-properties:
     * 1. By a given mask (e.g. ##.##.#### --> the '.' will be used as separators)
     * 2. By a given mask, starting with the REGEXP flag (e.g. �[a-z] --> [a-z] will be used as a regular expression)
     * 3. By a type CHAR(n),INT(n),DATE(n),FLOAT(n), Default is CHAR(100), with n=length or mask.
     * 4. By your own (extern) function (e.g. public String DateUtil.validDate(String)).
     *
     * (1) Mask-Validation:
     * If you use the mask-validation, it is possible to define your own charset by the method
     * defineCharset(char,String). The char-argument can be used inside the mask-definition, the
     * String-argument defines the possible input-characters for this mask-sign.
     * The basic mask character types are:
     * #: Numeric
     * &: Alphanumeric
     * +: Uppercase
     * -: Lowercase
     * *: Everything
     * !: Userdefined character
     * �: Flag at the entry of a mask to define a regular expression
     * All other characters in the mask will be defined as separators. The input cursor will
     * jump over the separator characters!
     *
     * (2)Regular Expressions
     * If your mask starts with '�', the rest of your mask will be used as a regular expression.
     * (for example: $[a-zA-Z0-9])
     * 
     * (3) Class-Validation:
     * If you use the class-validation or your own-validation, it is possible to define autocompletion.
     * For class-validation it is possible to set an error-text with setErrorMessageText(String).
     * The class-validation will start only if the text has at least the length 'minLen'.
     *
     * (4) Extern-Validation:
     * This function will be called by method/constructor-invoking
     * and must have one String argument and return value. The return value has to be 'null'
     * if the user-input is incorrect. In any other way, the return-value will replace the current input.
     * 
    */
    Using  the mask the input will be validated on every key-event.
    Using  the normal types (e.g. CHAR(2) ) the validation will start if the focus has been lost.

    1. Example: If you use
    <Edit   name    = "medTest"
            title 
      = "Testfield"
            type 
       = "date(##.##.####)"
            command = "01.01.2001"
    >
    </Edit>
    or
    <Edit   name    = "medTest"
            title 
      = "Testfield"
            type 
       = "date(##.##.####)"
            command = "__.__.____"
    >
    </Edit>
    If no title-property is given (or is empty), no JLabel-Control will be created for this Editfield!
    The mask inside the date(...) is not a simple mask. Simple masks are masks without seperators and with only one type of signs (like in the first two examples).
    If there is no simple mask, the editfield-behavior is different:

    2. Example: If you use
    <Edit   name    = "medTest"
            title 
      = "Testfield"
            type 
       = "int(##)">
    </Edit>
    the user has to input at least one numerical sign. This input will be validated on every key-event. If the user tries to leave this editfield, this editfield has to contain a valid number (because of the 'int(...)' ). So, if the field is empty, the focus can't be lost because it is no number.

    3. Example: If you use
    <Edit   name    = "medTest"
            title 
      = "Testfield"
            type 
       = "char(##)">
    </Edit>
    the user has to input a valid character string. But every character has to be numeric (validated on keyevent). If the user tries to leave this editfield, this editfield has to contain a valid string (because of the 'char(...)' ). The empty string is a defined string, so it is no problem to leave this editfield without
    containing any sign.

    4. Example: If you use
    <Edit   name    = "medTest"
            title 
      = "Testfield"
            type 
       = "int(2)"   min    = "0"   max    = "24"   errortext    = "Please input a number between 0 and 24" >
    </Edit>
    no validation will be done on keyevents. So it is possible to input everything! But on leaving this editfield, the content will be validated and has to be a number of maximal length 2 (at least of length 1, between 0 and 24).  If nothing is inputted, there is no valid number (see Example 2.).
     

    The Spread

    To see the following information, type : java -jar tsl.jar -xmltags=spread (To see a complete list of all tags and its properties, click here short-reference.html
    -----------------------------------------------------------------------
    Special properties of Spread are:
    -----------------------------------------------------------------------
    editable   : 'on' -> each table-cell is editable
               : e.g. row=2 -> the second row is editable
               : e.g. col=2 -> the second column is editable
    columns    : header-column-names (devided by ','
    colorleft  : sets the background-color of the left-most column
    colorright : sets the background-color of the right-most column
    colortop   : sets the background-color of the top row
    colorbottom: sets the background-color of the bottom row
    coltypes   : sets the column-types (masks like ##.##.####) devided
    colinits   : defines the initial strings  for the coltype-masks
               : by ',' or control-references like '@myCombobox'
    fitcolumn  : columnoptimizing: number of column owning the restwidth
    autoresize : on: on resize, all columns will be resized (default:on)
    rowheight  : rowheight for all rows in pixel
    dbtable    : database-table to use for rowinsertupdate
    dbmapcols  : (e.g. 0,1,3) map the cols to the sort of columns in the dbtable
    dbsinglemode: on: start insertupdate on each row (default:off)
    dbinsertupdate: 'on' rowselection start sql-insertupdate on dbtable
    rowchangedaction: name of Button or MenuItem to start on rowselchange
    calc_row_col: [row1,col1]+[row2,col2]+[row3,col3]
    sumrow     : adds a row with the sums of the columns (default:off)
    calc_row_col: [row1,col1]+[row2,col2]+[row3,col3]
    -----------------------------------------------------------------------
    Cell-specific properties (like calc_0_x is calc row=0 and all columns):
    -----------------------------------------------------------------------
    calc_row_col: [row1,col1]+[row2,col2]+[row3,col3]
    edit_row_col: 'on' or 'off'
    -----------------------------------------------------------------------
    Special contents (e.g. [mySpread(row)]) of Spread are :
    -----------------------------------------------------------------------
    header     : returns the header (all columnsnames) of the table
    selectedrow: returns the selected row of the table
    selectedcol: returns the selected column of the table
    oldrowvalues: returns the backup of the current row
    row=       : returns the content of the given row
    col=       : returns the content of the given (by index or name) column
    sumrow=    : returns the sum of the given row
    sumcol=    : returns the sum of the given column
    -----------------------------------------------------------------------
    Special extern commandtypes of Spread are:
    -----------------------------------------------------------------------
    addrow     : add new row to the end of this spread
    deleterow  : delete the selected row of this spread
    copyrow    : copy the selected row of this spread and append it to the end
    dofor      : start action for every row of this spread
    --------------------------------------------------------------------------------
    Possible bean-properties are:
    --------------------------------------------------------------------------------
    setSelection(Object) 
    --------------------------------------------------------------------------------
    

    The Spread is the most important control of this Tool. For examples, using all features, look at externtest.xml , _ExternControllerTest.java .

    Example:
    Create a swing-table with the column-header "Col1-Name,Co2-Name". The second column is editable and the most left column is gray.
    The first column is of type "##.##.####" (look at the class DocumentValidator: # is a number, & is alphanumeric, . is a seperator, * is everything)
    The second column is of type combobox (@cbbTest is a reference to another control that is a combobox)
    On selection-change-events the buttons actionExecute1 and actionExecute2 will be startet.
    On mouse-double-click-event, the button bnFillSpread will be startet.
    The column-widths will be optimized (because of 'fitcolumn'). The first column (=0) will yield the rest-width!
    For more information about the spread-functionality, start java -jar tsl.jartifex.JArtifex -xmltags=spread
    <Spread name    = "sprTable"
            command = "Col1-Name,Co2-Name"
            editable = "col
    =1"
            colorleft= "lightgray"
            fitcolumn= "0"
            dblclick = "bnFillSpread"
            coltypes = "##.##.####,@cbbTest"
            link    = "actionExecute1, actionExecute2"
    >
    </Spread>

    Giving the spread-content (selected row, column=0) to another control (medText):
    <Button name    = "actionExecute1"
            visible   = "off"
            command = "[sprTable(col=0)]"
            link    = "medText">
    </Button>

    Filling the spread throuth an extern java-method. This method has to return a TableVector (or a Vector of Vectors). The TableVector is able to hold the column-headers (attribute:columns), column-types (attribute: types) and the data (look at _ExternControllerTest.java ):
    <Button name    = "bnFillSpread"
            cmdtype   = "CLS"
            command = "@extern getData"
            link    = "sprTable">
    </Button>
    (@extern is the instance of your extern controllerclass (defined inside the common-block)

    Filling the spread through an SQL-Statement:
    <Button name    = "bnFillSpreadSQL"
            cmdtype   = "SQL"
            command = "select * from mytable where adress=[medText]"
            link    = "medText">
    </Button>

    Timer-Buttons

    The Controltype 'Timer' enables executing commands within given time-intervals (see timer.xml)

    Generic Controls

    Generic controls are controls without a spezialized class like Edit . You can use any GUI-class like the JTable as a xml-Tag. The disadvantage is , that you can't define special properties outside the properties of the BasicControl. The following page shows the use:
     * Constructs a generic BasicControl with no derived specialized control. Inside the classProperties
     * have to be the following items:
     *      1. full classname of the component
     *      2. name of the method to be invoked on calling 'fillIt(fillObject)' or the string 'null'
     *      3. one of the following keywords:   action (-> isAction()=true e.g. on Buttons)
     *                                          container (->isContainer()=true e.g. on Panels)
     *                                          scrollable (->isScrollable()=true e.g. on JTable)
     * Inside the xml-file it looks like:

    <JArtifex.layout>
        <group.common>
            @Table      = "javax.swing.JTable,null,scrollable,container"
        </group.common>
        <group.swing>
            <Table  name="tTest"
                    model="@extern getModel"
                    modelclass="javax.swing.table.TableModel">
            </Table>
        </group.swing>
    </JArtifex.layout>

     

    Creating own controls

    Inside the package 'tsl.controls' all controls (=tag-names) are defined. If you need a special control, you can create a new class inside this package. The following example shows the code for a very easy control: The Label (using the swing-class JLabel)
     
    tsl.control.Label
    package tsl.controls;

    import tsl.*;
    import javax.swing.*;
    import java.awt.*;
    import java.util.*;

    public class Label extends BasicControl
    {
        public static final String KEY_ALIGNMENT        = "alignment";
        public static final String STR_LEFT             = "left";
        public static final String STR_RIGHT            = "left";
        public static final String STR_CENTER           = "left";

        public Label()
        {
        }
            public Container initSpecials(Hashtable htProperties, Container parent)
            {
                    JComponent comp;
            //create the JLabel (the basic-paramters name,x,y,.. are filled by the BasicControl)
                    comp = program.addComponent(parent, new JLabel(), name, x, y, width, height);
            //property: alignment
                    String alignment = (String)htProperties.get(KEY_ALIGNMENT);
                    if (alignment!=null)
                    {   if (alignment.equalsIgnoreCase(STR_RIGHT))
                            ((JLabel)comp).setHorizontalAlignment(JLabel.RIGHT);
                            if (alignment.equalsIgnoreCase(STR_CENTER))
                            ((JLabel)comp).setHorizontalAlignment(JLabel.CENTER);
                            if (alignment.equalsIgnoreCase(STR_LEFT))
                            ((JLabel)comp).setHorizontalAlignment(JLabel.LEFT);
                    }
            //fill the control
                    ((JLabel)comp).setText(command);
            //store it
                    setControl(comp);
                    return comp;
            }
            public void fillIt(Object fillObject)
            {
                    ((JLabel)control).setText((String)fillObject);
            }
            public Object getContent()
            {
                    return getInterpretation(((JLabel)control).getText());
            }
            public static void printInfo()
            {
                    BasicControl.printInfo();
                    System.out.println("----------------------------------------------------------------------");
                    System.out.println("Special properties of Label are:");
                    System.out.println("----------------------------------------------------------------------");
                    System.out.println("alignment  : horizontal textposition (left,right,center) (default:left)");
                    System.out.println("----------------------------------------------------------------------");
            }
    }

    To see the most important features and methods look at BasicControl . Examples for the special behavior of controls are: Button, Spread, Panel, Text, Split.

    Control-Links, Control-Content

    Inside a <command> you can use references to other controls.
    Syntax: '[controlname]' On runtime the content of this control will be filled into the <command>.
    To get properties of controls look at Setting or Getting control-properties on Runtime .

    The content is:
    Control Content
    Edit selection or text or this editfield
    Text selection or text or this textfield
    Spread content of the selected cell
    Combo content of the selected row
    Checkbox string-representation of Boolean (‘true’ or ‘false’)
    Tree content of the selected cell

    For example:
    <Edit   name = "medDate"
            command = "[medActualDate]">
    </Edit>
    or
    <Edit   name = "medActualDate"
            link = "NOTNULL:[medDate]">
    </Edit>

    Setting or Getting control-properties on Runtime

    It is possible to change control-properties on runtime without using own java-code. This works with the help of Bean-Properties. Every public getter or setter method of a control (derived from BasicControl ) can be called indirectly.
    <Button name    = "bnExampleOk"
            title   = "Ok"
            command = "[medDlgDate.getBackground]"
            link    = "medDlgDate.setForeground, bnExampleOk.setForeground"
    >
    </Button>
    In this example, the result will be the background-color of the medDlgDate-control. This result will be transferred to the foreground-color of the medDlgDate-control (so the text will be invisible). The same result will be given to the Button bnExampleOk, so the text of this button will be invisible too.

    The BasicControl implements the following bean-properties:

    Each control (derived from BasicControl) can have own bean-properties. To find them, please start the following command:
    java -jar tsl.jar -xmltags=controlname
    where controlname is a control like Edit , Button etc. (look at Basic Tag-Properties )

    Commands

    The propterties 'cmdtype' and 'command' work together. The 'cmdtype' is a constant of the following list, the 'command' is variable.
    Commandtype (propertyname=cmdtype) is defined by:
    CMDTYP Comment
    EXE executes an operating system specific command.
    CLS executes any java-method (with String or Object-parameters (@))
    TXT interprets a command (default)
    SQL executes a sql-statement
    PRINT prints given or selected element (control)
    DELETE deletes a control (be careful!)
    READ reads from file
    WRITE writes into file
    APPEND appends data to file, spread, tree, combo
    RELOAD deletes all elements and build everything new (given by xml-file)
    OPEN opens fileselectbox
    CLOSE closes the mainwindow or a dialog (given by command=DialogName)
    SHOW Sets the visibility of a control (useful to show dialogs)
    FOCUS Sets the focus to control, given by 'command'
    DOFOR starts loop for all rows of a spread (given by command-property)
    DELETEROW deletes the selected row of a spread (given by command-property) 
    EXIT exits the program and the JVM
    RMI Only for Rmibutton (look at Client/Server(RMI) )
    REQUEST Only for Rmibutton (look at Dialogcreation )
    These are only the basic-cmdtypes. Please start 'java -jar tsl.jar -xmltags=spread ' to see the properties of for example of a spread.

    The commandtype CLS:
    For the command CLS there are four ways to build the command (see BasicControl.html ):
     *          1. <package+classname>
     *              --> the main method of this class will be startet in an own Thread.
     *          2. <package+classname> <methodname> [<methodparameter> [<methodparameter>]...]
     *              --> the method of this class with this parameter will be executed.
     *                  (e.g. 'samples._ControlChanger change @ControlName BLUEFOREGROUND'
     *                  where '@' defines the reference to the control 'ControlName')
     *          3. <program> <main> <inifile> [<commandline parameter> [<commandline parameter>]...]
     *              --> A new Program in its own Thread in its own Frame will be startet
     *                  through its main method with the inifile and commandline parameters.
     *                  (e.g.: 'tsl.jartifex.JArtifex main fedit help.eng')
     *          4. <program> <constructor> <inifile> [<commandline parameter> [<commandline parameter>]...]
     *              --> A new Program in its own Thread but within the parent window will be startet
     *                  through its constructor with inifile and commandline parameters.
     *                  If the parent window is an Applet, the Program will be embedded in the Appletcontext.
     *                  If the parent window is a Frame, the Program will be embedded in an JInternalFrame.
     *                  (e.g.: 'tsl.jartifex.JArtifex Program fedit help.eng')

    CLS-Example for 2.:
    The method 'change(BasicControl control, String color)' of class samples._ControlChanger will be started.
    <Button name    = "bnStart"
            cmdtype = "CLS"
            command = "samples._ControlChanger change @ControlName BLUEFOREGROUND ">
    </Button>

    CLS-Example for 4.:
    <Button name    = "bnStart"
            title   = "Start MyXmlFile"
            cmdtype = "CLS"
            command = "tsl.jartifex.JArtifex Program myxmlfile test"
    >
    </Button>

    Java-Methods

    If you use the commandtype 'CLS ', there has to follow the complete path of a java-class, the methodname and the method-arguments (separated by blanks). The result of the method can be given to another control. The class 'tsl.StringUtil' implements some useful java-methods:
     
    replace(source,search,replace) replace in 'source' 'search' with 'replace' 
    replaceInFile(file,search,replace) replace in 'file' 'search' with 'replace'
    calculate(exp) calculate expression in 'exp' operations: +, -, *, /, ^
    isTrue(exp) return value is "1", if 'exp' is true , if not: null. 'exp' compares Strings, Dates, Doubles operations: ==,!=,<,<=,>,>=
    DoForFile(SourceFile, sub1, sub2File)

    Other java classes, useful for dynamic java-method calling:
    _Applet.java showDocument(Object applet, String url, String target),   play(Object applet, String url)
    samples._ControlChanger.java change(Object obj, String property)
    _SqlUtil.java sql(Object obj, String table, String action)

    Resulthandling

    It is possible to define links to other controls getting the result of an action (event that executes a command).
    To define links to properties look at: Setting or Getting control-properties on Runtime.
    To define links to mouse-double-click-events look at: mouse-double-click-events
    The result-objects have to be listed inside the tag-property 'link' (separated by ','). The resulthandling can be constrained by:

    ResultProperties:
    NULL: result will only be given to the following control, if the result is null
    NOTNULL: result will only be given to the following control, if the result is not null
    <expression>: result will only be given to the following control, if the result equals <expression>
    !<expression>: result will only be given to the following control, if the result not equals <expression>
    NEWWINDOW as result-object: put result-spread into a new JFrame
    (Look at  Syntax and special Keywords).

    Expression-Example:
    If the result of the command (in this example it will be the content of the Edit-Control 'medDlgDate') equals the expression '01.01.2001', the result will be given to the Edit-Control 'medText'.
    <Button name    = "bnExampleOk"
            title   = "Ok"
            cmdtype = "TXT"
            command = "[medDlgDate]"
            link    = "01.01.2001:medText"
    >
    </Button>
    <Button name    = "bnExampleOk"
            title   = "Ok"
            cmdtype = "TXT"
            command = "[medDlgDate]"
            link    = "[medStaticDate]:medText"
    >
    </Button>

    NULL, NOTNULL-Example:
    If the method 'validDate' returns null, the button 'bnExampleCancel' will be executed.
    If the method returns an instantiated object, this object will be given to the Edit-Control 'medRowText'.
    <Button name    = "bnExampleOk"
            title   = "Ok"
            cmdtype = "CLS"
            command = "@extern validDate [medDlgDate]"
            link    = "NOTNULL:medRowText,NULL:bnExampleCancel"
    >
    </Button>

    Dynamic Controls

    It is possible to create controls while the program is running. They also can be deleted. At the moment, you can use this feature only for spreads. If you define a result-element for a button with PAGE, SPLIT,PANEL or 'NEWWINDOW', a new spread (holding the result) will be built inside the PAGE, SPLIT,PANEL or a new window. Look at the two following examples.

    NEWWINOW-Example:
    The method 'getSpread' has to return a TableVector. This TableVector will be embedded in a Spread-Control in a new Frame.
    <Button name    = "bnExampleOk"
            title   = "Ok"
            cmdtype = "CLS"
            command = "@extern getData [medDlgDate]"
            link    = "NEWWINDOW"
    >
    </Button>

    Dynamic-Control-Creation-Example:
    The returnvalue of the getData-method will be given to the Panel-Control 'panelLeft'. But this panel is a container (instanceof Swing-component JPanel, JSplitPane), holding no data but other controls. So a new control of type Spread will be created and embedded into the given panel, showing the resultdata of the command.
    <Button name    = "bnExampleOk"
            title   = "Ok"
            cmdtype = "CLS"
            command = "@extern getData [medDlgDate]"
            link    = "panelLeft"
    >
    </Button>

    Result-handling on Items,Buttons

    Resultfields are optional. The property-name is 'link'. If it is a Menu or Button, it will be executed (only , if it is not a property of a control, look at Setting or Getting control-properties on Runtime) . Is there no resultfield, the selected control gets the result (if it is no Item, Button). It is possible to define more than one resultfield (resultfield1,resultfield2,...)

    Clauses and Loops

    You can implement clauses and loops using java-methods. The loop-counter can be evaluated using the methods calculate(exp) and isTrue(exp). The loop stops, if the return value of the isTrue(exp) method is null. Buttons will be executed even if the return value is null, but if you use the 'NULL:', 'NOTNULL:','<expression>:' keywords (Look at  Syntax and special Keywords ), you can solve this problem.

    The other way is to use the commandtype DOFOR, but especially for spreads. A command will be executed for all rows of this spread:
     
    <Button name = "myName"
      title = "Dofor-Button"
      cmdtype = "DOFOR"
      command = "Spread-Name"

    link = "actionButton">
    </Button>    

     

    Autostart

    It is possible to start defined controls (or menuitems) on loading the program (see dofor.xml or Sql-Example )
     
    <group.Autostart>
            <Start1 name    = "bnLoad">     </Start1>
            <Start2 name    = "bnClsTable"> </Start2>
    </group.Autostart>

    Dialogcreation


    To see the following information, type : java -jar tsl.jar -xmltags=dialog
    ----------------------------------------------------------------------
    Special properties of Dialog are:
    ----------------------------------------------------------------------
    modal      : the behavior of this dialog will be modal (default:off)
    resizeable : off: dialog will not be resizeable (default:on)
    onclose    : close: dialog will be closed, nothing: nothing to do
    defaultbutton : name of the defaultbutton for this dialog
    inputfocus : name of the input-control that has the first focus
    xpos       : absolut x-position of this dialog (default:center)
    ypos       : absolut y-position of this dialog (default:center)
    xsize      : x-size of this dialog (default:640)
    ysize      : y-size of this dialog (default:320)
    ----------------------------------------------------------------------

    To create dialogs, use the BasicControl 'Dialog' as XML-Tag.
    The 'modal', 'xpos', 'ypos', 'xsize', ' ysize ' -properties let you define the behavior of your dialog.
    To open your dialog, use the cmdtype='show', command= dialogname.
    To close your dialog, use the cmdtype='close', command= dialogname.
    To define a defaultButton use the property defaultbutton
    To define a control that has the first focus use the property inputfocus
     
    <Dialog name      = "dlgTest"
            title               = "Test-Dialog"
            defaultbutton = "bnOk"
            inputfocus     = "medFirstEditfield" >
    </Dialog>

    This Button will open the dialog:
    <Button name      = "bnShowTest"
            title               = "Show the Test-Dialog"
            cmdtype       = "show"
            command     = "dlgTest" >
    </Button>

    You can find an example at externtest.xml .

    Other ways to create dialogs:
    The creation of dialogs is possible with the help of RMI. The RMI-control is 'control.Rmibutton'. If an Rmibutton with type 'REQUEST' is activated, the application will look, if the new window has already been started (as RMI-Client with the parent-window as a registered RMI-Server), if not, it will be startet.
    The following is a short example (extended from rmitest.xml):
     
    <Rmibutton name = "myName"
      title = "Request-Button"
      cmdtype = "REQUEST,[ControlName]">
    </Rmibutton>    

    "ControlName" is holding the url to register itself at the rmi-registry.
    For further information look at Client/Server(RMI) .
     

    Client/Server(RMI)

    Every program, containing an Rmibutton will be registered as an RMI-Server. The file rmitsl.bat shows, how to start the environment. So it is possible, to start an action (Rmibutton) on any machine that has started a tsl-Program containing this Rmibutton.

    The following sample shows the three possibilities to use the Rmibutton:
    rmitest.xml
    19:<group.Swing>
    20:        <Edit   name    "medInput"
    21:                title   "Input">
    22:        </Edit>
    23:        <Edit   name    "medOutput"
    24:                title   "Output">
    25:        </Edit>
    26:        <Comobo name    "cbbServer"
    27:                title   "Server"
    28:                cmdtype "READ"
    29:                command "rmi-hosts.log">
    30:        </Combo>
    31:        <Rmibutton      name    "rmiRequest"
    32:                        title   "RMI-Request"
    33:                        cmdtype "REQUEST,[cbbServer]">
    34:        </Rmibutton>
    35:        <Rmibutton      name    "medFillEdit2"
    36:                        title   "RMI: Fill Edit2 with Edit1"
    37:                        cmdtype "TXT,[cbbServer]"
    38:                        command "medInput"
    39:                        result  "medOutput">
    40:        </Rmibutton>
    41:        <Rmibutton      name    "medServerFillEdit2"
    42:                        title   "RMI: Fill Edit2 with Server-Edit1"
    43:                        cmdtype "RMI,[cbbServer]"
    44:                        command "medInput"
    45:                        result  "medOutput">
    46:        </Rmibutton>
    47:</group.Swing>

    "medInput" is the first Editfield
    "medOutput" is the second Editfield
    "cbbServer" is a combobox, reading its content from the file 'rmi-hosts.log'
    "rmiRequest", "medFillEdit2", "medServerFillEdit2" are the three RMI-buttons. The action is to get the content of "medInput" and to give that to the "medOutput"
     
    Type: REQUEST[, Server-Path] Starts new Program (xml-file is a substring of Server-Path) with actual Program as Server
    Type: TXT[, Server-Path] Starts action on given Server, giving the Server its own action-content
    Type: RMI[, Server-Path] Starts action on given Server, using the Servers action content

    Starting the program twice will show the following:
    Server1-Program Server2-Program (Client using Server1 as Server)
    Preconditions:
    The Server1 is registered as //localhost/rmitest/986324225930 (inside the rmi-registry)
    The Server2 ist registered as //localhost/rmitest/986324234830 (inside the rmi-registry)
    Server1 uses itself as Server-Program (look at the combobox)
    Server2 uses Server1 as Server-Program (look at the combobox)
    The first Editfield of Server1 contains the text 'input1'. The first Editfield of Server2 contains 'input2'.

    Pushing Button: 'RMI->fill Edit2 with Server-Edit1'
    Now we push the last button 'RMI->fill Edit2 with Server-Edit1' of Server2. The button takes the content of the first Editfield and puts it into the second Editfield. But the Rmibutton looks for the given Server1 and starts itself on Server1. So the first Editfield of Server1 will be putted into the second Editfield of Server1 and Server2.

    Pushing Button: 'RMI->fill Edit2 with Edit1'
    Now we push the button 'RMI->fill Edit2 with Edit1' of Server2. The button takes the content of the first Editfield and puts it into the second Editfield. But the Rmibutton looks for the given Server1 and starts itself on Server1 but with the content of the first Editfield of Server2. So the first Editfield of Server2 will be putted into the second Editfield of Server1 and Server2.

    Pushing Button: 'RMI-Request'
    Now we push the last button 'RMI-Request' of Server2. The Rmibutton will look for a registered Server that is selected inside the combobox. If this Server doesn't exist, it will be started now. This new Server-Program will use Server2 as Server-Program. This mechanism is useful for creating dialogs.

    Interfaces to other Java-codes or Embedding own Business Objects

    If you want to use your own models and objects there are several possibilities to do this:
    1. you can create a new control (extending BasicControl ) as a view-object, communicating with your own models/objects through own controllers.
    2. you can create a controller-class that works as an interface between the program-class and your business-objects (e.g. externtest.xml + _ExternControllerTest.java) .
    3. you can simply start methods (or constructors) of other classes (see cmdtype 'CLS') (e.g. tabletest.html + _ControlChanger.java ).
    4.  

      to (1): Look at Combo.java
      to (2): Inside the common-group you have to define the key 'extern'. The value has to be the complete path and name (e.g.:extern="mypackage.MyClass") of your controller-class, that should be able to handle different stati of the program and to return data. The program-class will instantiate an object of this class, calling the default-constructor. You are able to use this class by your controls, defined inside the xml-file. This can be done by using the cmdtype 'CLS'. The class (inside the command-property) has to be a reference to the externController followed by the methodname and its parameters (e.g.: command="@extern getMyData"). For further information, look at the javadoc of the framework: Program.getExternInterface() and ModelViewController-concept .
       

    Creating the Help-System

    Every control can define a help-url. This html-url will be shown in an extra java-window, if the user presses the F1-key.

    Example with a relative filepath (absolut would be 'file://c:/tsl/doc/documentation.html')
    If this button has no help-property the system looks inside the parent-properties (recursive) to find a help-content.
    <Button name      = "bnShowTest"
            title               = "Show the Test-Dialog"
            help              = "file:doc/documentation.html">
    </Button>

    Planned New Features

    Hints, Howto's, FAQs, Problems

    -To see a complete list of all tags and its properties, click here short-reference.html -A very simple example is the xml-file fedit.xml . Here you can see, that a program can contain two lines (editfield, button).
    -The sample.xml shows the most possibilities of defining controls and menuitems.
    -The externtest.xml shows all possiblities to work with the spread-control, dialog-control and the communication with extern-classes.
    -The work.xml , sqlutil.xml and the timesheet.xml show useful commands.
    -Type 'java -jar tsl.jar' to get help on commandline-options.
    -Type 'java -jar tsl.jar -xmltags=spread' to get for example special property-informations about the spread-control.
    -If you want to include your own extern classes, be sure, your classes are in the classpath (then it is better to extract the tsl.jar)
    -To find problems or errors use the commandline argument '-debug'. A lot of debug-informations will be printed to the standard-output.
    -Please don't define empty properties (e.g.: command=""), because of an error inside the class StringTokenizer.
     

    Samples

    All elements are used (in a senseless way) in 'sample.xml'.
    To start this sample: 'java.exe Program sample'
    Other examples are:
    Example Comment
    suite a toolbar with an editfield and a lot of buttons (representing all other samples) using the editfield as commandline argument
    graphSheet loads tables (from sql-statement or file) and shows the data in a graphsheet
    sqlUtil a complex utility to work with sql-statements
    sample a sample-file showing the most possibilities of the Program (but in a senseless way)
    Editor a very simple text-editor (the file has to be given by commandline argument)
    Workspace a working space for textfiles
    Viewer shows gif/jpg-pictures given by commandline argument 
    tslDevelop shows  (a little bit) the syntax for building controls in a program, given by commandline argument
    Calculator a calculator, but not in the common way
    Desktop shows the possibility to start several java-programs (TSL-Programs) in one mainwindow
    DoFor is able to start any command (exe,sql,class) for each row of a given table
    Timer starts a given command every 5 seconds
    Rmitest start this with rmitest.bat . Two programs will be started to show client/server -interactivity.
    ExternTest this example shows the use of dialogs and spreads and extern controller-classes.
    TableTest use this example to see the functionality of the Spread.

    Sql-Example, using a Spread-object showing the result of an sql-statement

    This example will be a dialog with a Spread-Object , showing the result of an sql-Statement. The Edit-Fields will show the content of the selected row of this Spread and they will be actualized on selection changing. The Button 'Disable' only starts dynamically a java-method that disables the Button.
    Here follows the short but explained example:
    Tabletest.xml
     1:<JArtifex.tabletest>
     2:<group.COMMON>
     3:        LABEL           ="left"
    4:        DRIVER          ="sun.jdbc.odbc.JdbcOdbcDriver"
    5:        URL             ="jdbc:odbc:timedb"
    6:        DB              ="timedb"
    7:        USER            ="time"
    8:        PASSWD          ="time"
    9:</group.COMMON> 10:<group.Swing> 11:        <Edit   name    "medColumn1" 12:                title   "Column1" 13:                command "[sprTable(col=0)]"> 14:        </Edit> 15:        <Edit   name    "medColumn2" 16:                title   "Column2" 17:                command "[sprTable(col=1)]"> 18:        </Edit> 19:        <Spread name    "sprTable" 20:                title   "Table" 21:                cmdtype "SQL" 22:                command "select from dplan" 23:                width   "2" 24:                result  "bnExecute1, bnExecute2"> 25:        </Spread> 26:        <Hidden name    "bnExecute1" 27:                command "[sprTable(col=0)]" 28:                width   "2" 29:                result  "medColumn1"> 30:        </Hidden> 31:        <Hidden name    "bnExecute2" 32:                command "[sprTable(col=1)]" 33:                result  "medColumn2" 34:                width   "2" 35:                position= "right"> 36:        </Hidden> 37:        <Button name    "bnDisable" 38:                title   "Disable" 39:                cmdtype "CLS" 40:                command "_ControlChanger change @bnDisable DISABLE" 41:                width   "2"> 42:        </Button> 43:</group.Swing> 44:<group.Autostart> 45:        <Start1 name    "bnExecute1"</Start1> 46:        <Start2 name    "bnExecute2"</Start2> 47:</group.Autostart>