swix at user guide

91
Swing-XML Authoring Tool Swing-XML Authoring Tool v. 0.5.5 User Guide by Paolo Marrone http://www.swixat.org Nov 15, 2006

Upload: aj-lopez

Post on 24-Oct-2014

54 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: Swix at User Guide

Swing-XML Authoring ToolSwing-XML Authoring Toolv. 0.5.5

User Guide

by Paolo Marronehttp://www.swixat.org

Nov 15, 2006

Page 2: Swix at User Guide

The Swing XML Authoring Tool User Guide

Table of Contents

Introduction...............................................................................................................................................4Chapter 1: The MVC Paradigm................................................................................................................5

How the MVC pattern is implemented in SwiXAT...........................................................................6The View .............................................................................................................................................8The Controller......................................................................................................................................9

The Command Binding mechanism...............................................................................................9Scripting.........................................................................................................................................11

Application Context based mechanism...................................................................................11Direct importing based mechanism.........................................................................................12Meaning of the Returned Value...............................................................................................13

Automatic declarations..................................................................................................................14Imported Packages....................................................................................................................14Predefined Objects....................................................................................................................14

Events Handling............................................................................................................................15Window's Events......................................................................................................................15Components' Events.................................................................................................................17

Indirect Command Binding: the <Action> tag............................................................................19Special ActionCommands.............................................................................................................21

Reserved words.........................................................................................................................21Static method invocation..........................................................................................................22Multiple command support .....................................................................................................23

Invoking a command from within script code.............................................................................23The Model..........................................................................................................................................23

DataSources...................................................................................................................................24The 'origin' attribute.................................................................................................................24Origin attribute in JButton and JMenuItem............................................................................24Origin attribute in button groups.............................................................................................25The 'render' attribute.................................................................................................................25The DataSource's common attributes......................................................................................26The <ContextDataSource> ......................................................................................................27The <ScriptingDataSource> ...................................................................................................27The <XPathDataSource> ........................................................................................................27The <ObjectDataSource>.........................................................................................................28The <DOMDataSource>..........................................................................................................29

How to use XPath..........................................................................................................................29The Context....................................................................................................................................31

The 'current' context.................................................................................................................32The 'shared' context..................................................................................................................34Context's keys accessors methods............................................................................................34

Updating the model: the UpdateOrigin command.......................................................................35Using the 'update(...)' command..............................................................................................36

Page 2

Page 3: Swix at User Guide

The Swing XML Authoring Tool User Guide

The Model's events handling........................................................................................................37Chapter 2: Special Features....................................................................................................................41

Support for MDI applications............................................................................................................41The <WindowMenu> tag..............................................................................................................41The <MDIDesktopPane> tag........................................................................................................42The <ModalInternalFrame> tag...................................................................................................43

Support for JComboBox and JList  components..............................................................................43The <ComboModel> and <ListModel> tags...............................................................................43The <ComboBoxRenderer> tag....................................................................................................44The ComboBox's “values” attribute.............................................................................................45

Support for JTree components...........................................................................................................45The <TreeModel> and <TreeCellRenderer> tags........................................................................45The <NestedTreeModel> and <TreeNode> tags..........................................................................49

The enhanced Renderer mechanisms................................................................................................50The <XPanel>, <XMenuBar> and <XToolBar> tags.......................................................................51The <DatePanel> and <DateField> tags...........................................................................................52The <TableChooser> tag....................................................................................................................53Support for JTable component...........................................................................................................54The <WizardPanel> tag.....................................................................................................................57The <CardPanel> tag.........................................................................................................................60Support for DockingPanels................................................................................................................62Support for PopPup Menus................................................................................................................64Threaded Action Commands.............................................................................................................65Support for Testing.............................................................................................................................67

Chapter 3: The Application Context XML file.....................................................................................68How to launch a SwiXAT based application....................................................................................69How to write the Application Context..............................................................................................69The Application­specific beans.........................................................................................................69

The Application bean ...................................................................................................................70The Command beans.....................................................................................................................73

The Application­independent beans..................................................................................................74The ScriptManager bean...............................................................................................................74The TagLibrary extensions............................................................................................................75The SetterFactory bean.................................................................................................................76

Chapter 4: Getting Started......................................................................................................................78How to build SwiXAT from Source .................................................................................................78How to create a SwiXAT based Sample Application ......................................................................79The Hello World example..................................................................................................................82

Example 1: The static Hello World example...............................................................................82Example 2: Inserting a Button......................................................................................................83Example 3: Adding a DataSource................................................................................................85Example 4: Passing parameters between two frames..................................................................86Example 5: Validating the user's input.........................................................................................88

Chapter 5: Extending the framework.....................................................................................................90How to add new commands...............................................................................................................90

Page 3

Page 4: Swix at User Guide

The Swing XML Authoring Tool User Guide Introduction

Introduction

This  document  aims   to  explain   the  functional  details  of   the SwiXAT framework  (Swing­XML Authoring Tool – http://www.swixat.org), in order to permit anyone interested to use all the features of the framework.

What is SwiXAT?SwiXAT is the name of the framework built with the aim of providing a powerful User Interface framework based on Swing and XML. It allows new Java applications to be build simply by writing XML parameters and scripted Java code.

Why use SwiXAT if a GUI application can be simply written by using Java­Swing?It takes a lot of work to develop a Swing application, laying out and configuring GUI components, and then integrating them with the application functionality. SwiXAT addresses both of these issues by providing a framework based on a complete implementation of the MVC architectural pattern. 

The benefits obtained by a such framework are the followings:

1. Architectural Correctness   : By adopting a true MVC (Model View Controller) based framework, it is very easy to correctly implement any UI application. It's not difficult to write a Java/Swing application, but what's very difficult is to build a good, well designed Swing application, where the adoption of the MVC paradigm permits to reduce the maintenance costs, thanks to the clean separation between the view and the application logic.

2. Development Speed   : The adoption of a framework reduces the development cost by providing out­of­box, well integrated and easy to use common features, like wizards, plugins, support for MDI  interfaces,  etc.  Moreover,   the use of  XML to define  the user  interface,  as well  as   the adoption of an interpreted scripting language, permits to implement the 'Code&Test' development style, where the compilation time is reduced to zero. 

3. Code Reuse   : The net separation between the view and the control logic permits to write reusable modules   that   can   be   combined   in   several   manners.   The   developer   is  naturally  induced   to modularize   the   application   and  write   reusable   code,  minimizing   the   effort   of   building  new applications or adding new functionality to existing ones.

To accomplish the above goals we don't  need to implement a monolithic application, but rather thought to develop a powerful framework where the user can assemble pre­built building blocks to implement the required application. 

SwiXAT is all the above, and we hope you'll appreciate our effort.

Page 4

Page 5: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

Chapter 1: The MVC Paradigm

What we need is the possibility to define the UI purely in terms of writing external parameters, for instance by modifying XML files. Consequently we need a Java library to define a swing user interface through XML tags.The idea is as follows:We need to start with the definition of the MVC architectural pattern, as depicted in the following figure:

The  View  represents the user interface (frames, panels, etc) containing all the available controls (buttons, labels, text boxes, etc).

The  Model  represents   the  objects  and   the  entities  handled  by   the  application   (i.e.   the   internal representation of the business model).

The Controller acts like a gateway between the View and the Model. This provides a mechanism to notify the Model about modifications made by the user, and to display changes to the model in the corresponding View.

The continuous­black arrows represent method calls, whereas the dotted­red arrows represent event notifications.

The internal pattern mechanism works as follows:We'll start from a situation where a View is already displayed to the user, and s/he starts to interact with it. Follow the numbered arrows in the above figure:

Page 5

View

Model

Controller1

2

3

54

Method callEvent notification

Page 6: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

1. The View notifies the Controller about a user's action (like a button click).2. The Controller calls the corresponding methods on the Model's objects to execute the changes 

the user has requested (the start of a download from a remote server, for instance).3. The Controller shows the corresponding View in response to the user's action (a panel containing 

the progress bar, for instance). When displayed, the View registers itself as a Model's events listener.

4. The  Model   notifies   all   the   registered  Views   about   any   changes  within   it   (for   instance,   the download of a percentage of bytes).

5. In response of the above notification, the View gets from the Model all the informations it needs to show itself (for instance, the current downloaded bytes).

We will  not  discuss  all   the benefits  of   the  MVC pattern  at   this   time,  because  anyone who  is interested   can   read   a   lot   of   documentation   on   Internet.   We   will   instead   concentrate   on   the implementation of the MVC modules within the framework.

How the MVC pattern is implemented in SwiXATBefore to start to explain all the features of SwiXAT, we believe it's very important to give you an overview about how this framework is organized and what are the main modules interested.The following picture illustrates the overall architecture on which SwiXAT is based, in terms of used libraries and needed external parameter files:

Page 6

View

XMLView

XMLView

XMLViews

XMLView

XMLViewScripts

Controller

SwiXML BeanShell

 Model

XMLApplication

Context

JXPath

DataSource Adapters

Spring

BusinessModel

DataModel

Page 7: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

As clearly shown, SwiXAT represents only the glue between the different technologies/frameworks used. The main goal is to permit the developers to write an entire application by writing only XML and scripting code. The necessity for compiled java code is almost totally eliminated, resulting in an improved developing speed, ease of testing, code reusability and readability.  

The authors of SwiXAT have made what any conscientious application designer should always do: to define an overall architecture based on well known design patterns, and then choose the best OS frameworks that permit to implement easily such design patterns. The paradigm is: do not start from scratch, but climb on the shoulders of the Giants.We have simply written the code needed to put it all together, hoping you'll appreciate our choices (being it an Open Source project, you're invited to participate, in order to change/improve the things you don't like). 

The main elements involved in any application built on top of SwiXAT are the following:

● The View is based on the XUL paradigm, where the design of the UI interface is made by writing XML tags instead of Swing Java code. XML permits to write less code respect to the equivalent java statements needed to build the same user interface. SwiXML is the XUL framework chosen for   this   purpose,   mainly   due   to   its   fundamental   characteristics   like   the   robustness   and extensibility.

● The Controller handles requests and creates or prepares the response. Typically controllers need access both to the View and to the business logic (the Model). Controllers handle the request by instantiating a command object, passing it request parameters. Controllers handle the response by delegating to a view and optionally populating a model. Controllers need to be configured with the Spring IoC framework. The  Controller  can delegate the execution of the control logic to script code based on the BeanShell interpreter (as of SwiXAT 0.3.0 we have added the support for the Groovy language). The use of scripting code permits us to write very fastly all the control (NOT the business) logic of our application. For our choice,  all the script code is separated by the XML used to describe the views; in this manner we guarantee a clean separation between the view and the controller, avoiding to build strange mixtures of XML/JavaScript that make the application very hard to read and maintain. This decoupling also guarantees a strong reusability of the defined views (i.e. the same view used in different contexts might need a different logic behind it). Of course the use of script code is not mandatory, because the developer is free to implement the control's logic within standard (compiled) java classes.

● The  Model, represented by your own data model and/or object model, is accessed by specific data sources, that represent the bridge between the Model and the View/Controller parts. Some pre­built data sources already exist (and many others will be implemented in the next releases), but  they're easily extensible,  and anyone can build a new one to access  to any specific data format. In order to permit to navigate the business model obtained by a data source, we use XPath, a very powerful query language used to traverse DOM trees. As an object model can be viewed as a hierarchical tree, we use JXPath ­ a free java implementation of the XPath language ­ to navigate our own specific object model

Page 7

Page 8: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

● All the above components are kept together by the Spring Framework, a complete and powerful implementation of the “Inversion of Control” pattern. The Spring IoC implementation permits to define within an XML file all the components needed by the application (along with all their dependencies). In this manner Spring represents a powerful mechanism to define and access to all the needed parameters (the so called “Application Context”), permitting in this manner to write   within   external   resources   all   the   dependencies   between   the   different   pieces   of   our application   (as   an   example,   the   binding   between   the   UI   components   and   the   associated commands is defined within the Spring XML file)

In order to build an application, the developers need only to write the external files containing the needed XML (to define both the application context and the views) and JavaScript code (to write the control logic), depicted in the above figure with white boxes.

The following chapters will explain all the details of the above architecture.

The View In order to be able to easily define a View without writing Java code, the user interface will be defined by XML tags as in the following example. The following code might be contained in a file named ControlPanel.xml. <Panel name=”Control Panel”>

<button text=”Start” .../><button text=”Stop” .../>...

</Panel>   

In this manner we could write several useful reusable panels that the user could connect together to build the final user interface. Of course the user can build new panels if needed.Several panels could be assembled within a frame (or a any other Container object) just by using an appropriate tag built  to  'include' one panel within another. This tag   has been named <XPanel> (standing for eXternal Panel) and used in this manner:

<Frame ...><SplitPane orientation=”HORIZONTAL”> <Xpanel xml=”ControlPanel.xml”/> <Xpanel xml=”ProgressBar.xml”/><SplitPane/>

</Frame>

In   this  case we have placed  two panels  within a  JSplitPane,  but  either  of   the panels  could be included in another frame, making them prebuilt, reusable UI objects. This leaves the freedom of choice about the desired user interface to the user.

To define a Swing interface using XML code, we have chosen SwiXml, an Open Source framework downloadable   from  http://www.swixml.org/,   hence   you   need   to   read   the   SwiXML   available documentation in order to learn more about it. 

Page 8

Page 9: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

The ControllerWe need a mechanism to execute a command in response to a user's action. To do this, we need to write   a   Java   class   containing   the   code   of   the   action   and   a   mechanism   to   connect   it   to   the corresponding user interface control.We could use the tag parameter ActionCommand to define the corresponding action:

<button name=”Start” ActionCommand=”StartDownload”/>

At this point we need a mechanism to link the ActionCommand string with the component that implements the required action.

The Command Binding mechanismIn order to bind the ActionCommand with the code that will execute the corresponding action, we have   defined   an   interface   named   org.swixat.commands.Binder.   This   interface   exposes   three properties (along with the corresponding getter/setter methods):

● Type: (optional) contains the name of the component that executes the invoked action. If defined, it can point either to a custom java class, or a file containing Java interpreted code. See the paragraph 'Scripting' below.

● Output:   (optional)  contains   the name of  the XML file  describing  the new View to show in response to an user's action. If declared, the InternalFrame described in the XML will be shown after the execution of the action.

● OnError: (optional) contains the name of the XML file describing the view to show in case of the executed actions returns an error.   If declared, the InternalFrame described in the XML will be shown after the execution of the action, in case of error.

The Binder interface is actually implemented by the  org.swixat.commands.CommandBinder class. However you don't  need to call  directly the CommandBinder's methods, because we have implemented an easy mechanism to declare the needed command bindings, simply by using XML tags written within a configuration file (named also 'Application Context'. See the   'Inversion of Control (IoC)' section to learn more about the XML Application Context syntax and content). 

In order to declare a command used to respond to the user's actions, we need to write within the XML application Context:

<bean id="commandName" class="org.swixat.commands.CommandBinder">   <property name="type">      <value>some/path/command.bsh</value>   </property>   <property name="output">      <value>somepath/outputFrame.xml</value>   </property>   <property name="onError">

Page 9

Page 10: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

      <value>somepath/errorFrame.xml</value>   </property></bean>

The basic rule for the interpretation of the value of the tag 'type' is the following:

If the ‘type’ property contains a string terminating with ‘.bsh’, then that string is interpreted as the name of the file containing the scripting code (with the file path relative to the classpath of the application), otherwise the string is interpreted as the class name of the object implementing the GuiCommand  interface (that must also be present in the classpath).

In this manner we let the developer free to choose how to implement the controller's logic of the application. In fact it isn't mandatory to write only script code, because, for some specific tasks, the developer can choose to implement the logic within classic java classes.Both the 'type' and the 'output' properties are optional (although at least one of the above tags must be present) because we could have the following three situations:

<bean id="open" class="org.swixat.commands.CommandBinder">   <property name="type">      <value>bsh/checkSelection.bsh</value>   </property>   <property name="output">      <value>xml/custDetailsFrame.xml</value>   </property>   <property name="onError">      <value>xml/errorNoSelectionFrame.xml</value>   </property></bean>

<bean id="exit" class="org.swixat.commands.CommandBinder">   <property name="type">      <value>org.swixat.commands.ExitCommand</value>   </property></bean>

<bean id="about" class="org.swixat.commands.CommandBinder">   <property name="output">      <value>xml/AboutFrame.xml</value>   </property></bean>

The first command named 'open' is used to open a new frame (custDetailsFrame.xml) after having verified (by invoking the script contained in the checkSelection.bsh file) that the user has made some selection on the current frame. In case of error (no selection), an error panel is displayed (errorNoSelectionFrame.xml).

Page 10

Page 11: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

The command 'exit' is used to close the application, hence only the 'type' tag is declared, within which   the   class  org.swixat.commands.ExitCommand  is   invoked   (as   the   corresponding value doesn't  terminates with '.bsh',  the  ExitCommand  references a java object declared in the framework's classpath).

The last example shows the 'about' command used to open the about box of the application. It uses the tag 'output' to open the frame described by  AboutFrame.xml.

Now it should be clear how to link the ActionCommand of a UI component to the corresponding command associated to it. 

ScriptingOne of the main goals of this framework is to provide easy customization of the application through the writing of external scripts/parameters. Therefore, a powerful mechanism to obtain this goal is represented by scripting code used in response of any user action.

We have chosen the BeanShell (http://www.beanshell.org/) interpreter which allows Java code (not only JavaScript) to be executed from a file. As   of   SwiXAT   0.3.0   we   have   refactored   the   scripting   mechanism   in   order   to   make   it   easily extensible. Thanks to that refactoring, the Groovy (http://groovy.codehaus.org/) language support has   been   added   (see   the  ScriptManager  declaration   in   the   'Application­independent   properties' section of this document to know how to activate the desired interpreter).

We have implemented two distinct mechanisms that can be used in order to invoke a script code in response of a user's action.

Application Context based mechanism

Whenever we need to execute some code, in response of which we want to show either an output view or an error view, and when the above association controller/output­view is known a priori, we can declare that association within the Application Context XML file, as already described in the above section.

To do this, we have to specialize the content of the ‘type’ property of the Binder interface. Where we want   to  execute Java code in  response of an action,   the value of   that   tag must be a  string representing the name of a file containing the code to execute. 

If we need to execute  the code contained into the file ‘path/start.bsh’ in response of  the action ‘Start’, and then show the 'path/startView.xml' view, we would write in the Application Context XML:

<bean id="Start" class="org.swixat.commands.CommandBinder">   <property name="type">      <value>path/start.bsh</value>   </property>   <property name=”output”>      <value>path/startView.xml</value>   </property>

Page 11

Page 12: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

</bean>

and then we could reference the above command in any UI actionCommand:

<Button text=”Start” actionCommand=”Start”/>

Note: the script file declared within the <type> property must contain NOT only functions (i.e. not only   script   code   contained   within   a   function's   body   'funcName()  {...}').     In   fact,   the framework will execute only the code written outside any function's body. That code, however, can invoke whatever function declared within the same script file, if needed.

Direct importing based mechanism

As of SwiXAT 0.3.5 we have added the possibility to directly import a script file within any XML view in this manner:

<Frame ...><Script id=”script” src=”/some/path/script.bsh”/>...<button id=”b1” text=”Start” actionCommand=”start()”/>...

</Frame>

note that the button's ActionCommand parameter contains the string “start()”, that must be the name of a function declared in the script previously imported (the ActionCommand parameter, in this case, must contain a function call terminating either with “)” ­ or “);” ­ in order to permit the framework to discriminate between the two script invocation methods). 

The script.bsh file will contain something like this (written in BeanShell syntax):

start() {// Your own code here...

}

Of   course   a   single   script   file   can   contain   any   number   of   functions.   In   this   manner   we   have eliminated the existing constraint represented by the necessity to write a single function within each script file.

In   this   case,   if   the   script   needs   to   open,   as   response,   a   new   view,   it   must   return   a org.swixat.framework.OutputView  object,  by instantiating it with the name of the file containing the view's XML, as in this example:

import org.swixat.framework.OutputView;

funcName() {

Page 12

Page 13: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

...return new OutputView(“/some/path/to/nextView.xml”);

}

Note:  the script file imported with the <script> tag must contain  only  functions (i.e. only script code   contained  within   a   function's   body   'funcName()  {...}').  This   is   because  we   cannot control the moment at which the code outside any function will be executed, obtaining uncertain and undesired behavior.

You can also pass whatever parameter to the invoked function, like in the following example:

<Frame ...><Script id=”script” src=”/some/path/buttons.bsh”/>...<button id=”b1” text=”1” actionCommand=”buttonHandler(1)”/><button id=”b2” text=”2” actionCommand=”buttonHandler(2)”/><button id=”b3” text=”3” actionCommand=”buttonHandler(3)”/>...

</Frame>

if the buttons.bsh file contains the following code:

buttonHandler(int x) {System.out.println(“You have pressed the key '”+x+”'”);

}

then, whenever a button will be pressed, the program will print the corresponding number on the standard output console.

Meaning of the Returned Value

Regardless of the used invocation method, a script code can return a value to the caller application. The value returned is a java.lang.Object, so you can put into it whatever value/object. The returned value is used in a different manner, depending on the context within which the script is excuted:

Within a script invoked by the Controller, the returned object can be used to indicate the result of the elaboration: it contains an instance of the Integer class containing either the value 0 in case of success, or 1 in case of error. In this last case, if the script was invoked by a command declared within a CommandBinder, the associated 'onError' view is shown.As   for   SwiXAT   0.3.5   we   have   extended   this   behavior   by   permitting   to   return,   optionally,   a org.swixat.framework.OutputView class. If returned, this class must contain the name of the XML file describing the view to show in response of the invoked script code. Example:

...return new OutputView(“/some/path/nextView.xml”);

Page 13

Page 14: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

In this manner the developer can dynamically choose which view must be shown in response of an ActionCommand.

Indeed the OutputView class exposes other two different constructors:1. OutputView(String view, String key, Object value)  – the 'key' and 'value' 

parameters, if not set to null, represent a value that we need to pass to the new view by inserting it within the current context, indexed by the 'key' string.

2. OutputView(String view, Map context)  –   In   this   case   the   'context'   parameter contains not only a single key­value pair, but an entire context, represented by an instance of the java.util.Map class. All the keys defined within the Map will be inserted in the current context of the called view.

By using one of the above contructors, the developer can pass whatever parameter to the new view that will  be shown in response of  the command. The new view will  be able to access  to  those parameters   simply by  reading   the corresponding keys  of   the current  context,  either  by  using  a <ContextDataSource context=”current”...>  tag from within the XML view, or by using the 'currentContext' variable from within script code (see the 'Automatic declarations' section   below).   For   commands   declared   in   the   XML   Application   Context,   the   above   two constructors can be called also by setting the view's name to null; in this case we want simply to invoke the new view (the name of which is declared in the XML application context) by setting its initial context with some key­value pairs. 

Within a  script   invoked by a ScriptingDataSource (see  the  'Model'   section below),   instead,   the returned value is used as root object returned by the data source. In this manner we can access to whatever property of that object by using an XPath expression in order to bind whatever returned value to any UI control.

Automatic declarationsThe framework provides the user with some pre­declared objects/packages useful to access to some internal feature from within a script code:

Imported Packages

In   order   to   declare   that   some   packages   have   to   be   imported   by   default,   you   can   add   the corresponding   'import'   statement   within   the  ScriptManager  declaration,   as   described   in   the 'Application­independent properties' section of this document.

In   this  manner  you  don't   need   to  declare   every   time   the  complete  package  name,   in  order   to instantiate the most frequently used classes.

Predefined Objects

The framework declares also the following objects:● currentContext   :   points   to   an   org.swixat.model.Context   object   containing   all   the   internal 

variables declared in the application in the form key­value pairs. You can access to any declared value by calling currentContext.getData(“key”) (to learn more about this object, read 

Page 14

Page 15: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

the 'Current Context' paragraph). It contains the following predefined methods:1. “getWidget”: permits to access to the map containing all the UI components declared in 

the   current   frame,   indexed   by   their   ID.   Example.: currentContext.getWidget(“someID”)

2. “getFrame”: returns an instance of the org.swixat.framework.AbstractFrame class, that is the frame that contains the current view. This property is useful in order to be able to call some useful method of the AbstractFrame class, as for  instance the executeCommand method.  Example:   if  we  need   to  close   the current  view from within   the   script   code invoked   in   response   to   a   command,   we   can   use   the   following   syntax: currentContext.getFrame().executeCommand(“cancel”) 

3. “getShared”: when a new frame is opened, if in the parent frame's context the key 'shared' is present (i.e. it has been set with the setShared(someValue) method), then its value is copied  within   the  newly  created   frame's   context  with   the   same key.  Useful   to   share contexts between childs of the same parent frame.

4. “getParent”: within a frame invoked by another frame, this method returns the caller's idMap. Example: currentContext.getParent().get(“someParentID”)

● application   : points to the Application object, as declared in the 'application' bean in the XML IoC properties file, so that you can easily access to the application­specific properties. (See the 'Application­specific properties' section of this document).  

● context   :   points   to   the   instance  of  ContextBinder,  which  is   the  container  of   all   the   existing contexts declared within our own application. (See the paragraph 'Context' below). 

Events HandlingOther  than the user's actions,  a GUI normally needs to handle specific events raised by the UI components themselves. In order to accomplish this goal, we have implemented a mechanism very similar to that one used to handle the user actions.

Window's Events

In order to handle all the window's events, we have extended the SwiXML tag library with the following new tags:

Tag name Attributes Notes

<WindowEvents> onOpenedonClosingonClosed (*)onActivatedonDeactivatedonIconifiedonDeiconified

(*) The onClosed event can be annulled by the user (see description below)

<WindowFocusEvents> onGainedFocusonLostFocus

Page 15

Page 16: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

Tag name Attributes Notes

<WindowStateEvents> onStateChanged

They are inserted, normally, within a Frame (or InternalFrame), in the following manner:

<Frame title=”Some title”...><WindowEvents id=”windowEvents” 

onOpened=”actionOnOpened”onClosing=”actionOnClose” .../>

<WindowFocusEvents id=”focusEvents”onGainedFocus=”actionGainedFocus” .../>

...</Frame>

The   value   of   the   above   properties   contains   the   name   of   the   action   to   execute   when   the corresponding event is raised, exactly as already explained for the ActionCommand property of any UI component.The meaning and purpose of the above events is clear, I think, but a consideration must be done for the WindowEvents' onClosing attribute.While all the above events must be considered just as simple 'notifications' of the corresponding event (i.e. they cannot be annulled), the onClosing event is the only one that can be annulled, giving the user the possibility to avoid the window closing, when requested. The rule is that if the value returned by the invoked action is equal to zero, then the action is confirmed, and the frame is closed (and   then   the   onClosed   event   is   raised   and   the   corresponding   action   executed,   if   declared), otherwise the close action is annulled.

Look at the following example, where we have the following frame:

<Frame ...><WindowEvents id=”events” onClosing=”askForClose”>...

</Frame>

and   the  askForClose  action   points,   within   the   XML   application   context,   to   the askForClose.bsh script file, within which the following code is written:

return javax.swing.JOptionPane.showConfirmDialog(null,   "Close the Window?",  // Message   "Close Confirmation", // Title   JOptionPane.YES_NO_OPTION,   JoptionPane.QUESTION_MESSAGE);

then,  when the user closes  the above window, a panel asking for  the closing confirmation will appear:

Page 16

Page 17: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

as the value returned by the script will  contain 0 only if  the user presses  the  'Yes'  button,   the application frame will be closed only if the user confirms the action.

Components' Events

Also for  each UI component  we can   intercept  and handle  some events,  other   than  the already declared ActionCommand, as illustrated in the following table:

Tag name Attributes Notes

<MouseEvents> onClickedonDblClickedonEnteredonExitedonPressedonReleased

<MouseMotionEvents> onDraggedonMoved

<MouseWheelEvents> onWheelMoved

<KeyEvents> onPressedonReleasedonTyped

<ItemEvents> onStateChanged Applies only to Swing components that inherit the AbstractButton class.

<FocusEvents> onFocusGainedonFocusLost

<InputMethodEvents> onCaretPositionChangedonInputMethodTextChanged

<ComponentEvents> onHiddenonMovedonResizedonShown

Page 17

Page 18: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

Tag name Attributes Notes

<ChangeEvents> onChange Applies to AbstractButton, JTabbedPane, Jspinner, Jslider, Viewport, JProgressBar, ... and whatever else Swing component that exposes 'addChangeListener'

<TableEvents> onTableChanged Applies to JTable components

<TreeSelectionEvents> onValueChanged Applies to JTree components

<ContainerEvents> onAddedonRemoved

<PropertyChangeEvents> onChangepropertyName (*)

(*) The propertyName attribute must be set with the name of the component's property to monitor(ex: propertyName=”text”)

<VetoableChangeEvents> onChange

<DocumentEvents> onChangeUpdateonChangeInsertUpdateonRemoveUpdateonModified (*)

Applies only to Swing components that inherit the JTextComponent class.

(*) If declared along with other specific event attributes, it's called after all others. Example: if onChangeUpdate and onModified are used together, the onModified action is invoked after onChangeUpdate.

<CaretEvents> onCaretUpdate Applies only to Swing components that inherit the JTextComponent class.

<HyperlinkEvents> onHyperlinkUpdate Applies only to Swing components that inherit the JTextComponent class.

<ListSelectionEvents> onValueChanged Applies only to JList components

All the above tags must be inserted as child of the UI component for which the corresponding event must be handled, as in the following example:

Page 18

Page 19: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

<TextField id=”name” ...>   <MouseEvents id=”mouse” onDblClicked=”dblClickAction”/>   <FocusEvents id=”focus” onFocusGained=”focusGainedAction”/></TextField>

The   script   invoked   by   the   corresponding   event   will   be   able   to   access   to   the   instance   of   the associated   event   (java.awt.event.FocusEvent  or  java.awt.event.MouseEvent  in the above example) by invoking the method “getArgument()” of the current context, as in this example:

event = currentContext.getArgument();...

As the description of the meaning of all the above events is out of the scope of this document, we recommend you to read the corresponding documentation available both on Internet and on several technical books.

Indirect Command Binding: the <Action> tagSometimes it's useful to associate both the same attributes and the same behavior to different UI components. Think, for example, to the 'Save' command accessible both from a menu item in the File menu and from a button in the toolbar. Of course they must share the same text (eventually translated according to the locale setting), as well as the same state (the 'Save' command must be disabled if there isn't any document opened).

But if we declare the 'Save' command in the following manner:

<MenuItem id="saveItm" text="txtSave" icon="imgSave" mnemonic=”mnSave” accelerator=”accSave” ActionCommand="save"/>

...<Button id="saveBtn" text=”txtSave”

mnemonic=”mnSave” accelerator=”accSave” ActionCommand="save"/>

we have duplicated a lot of code, because as you can say, the  'text',   the  'mnemonic'  and the 'accelerator' attributes are declared in both the places with the same values.

Moreover, we have some problem when we try to enable/disable the command, because we should call the setEnabled method on each Button/MenuItem connected to that ActionCommand. 

The <Action> tag come in our aid by providing a simple mechanism to share the same command between different UI controls. We can rewrite the previous code in the following manner:

<Action id=”saveAct” text="txtSave" mnemonic=”mnSave” accelerator=”accSave” command=”save”/>

...<MenuItem id="saveItm" icon="imgSave" ActionCommand="saveAct"/>...<Button id="saveBtn" ActionCommand="saveAct"/>

Page 19

Page 20: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

As   you   can   see,   all   the   shared   attributes   now   are   declared   only   in   the  Action  tag.   The ActionCommand attribute of each UI component points to the ID of the Action element, and its 'command' attribute indicates which command must be invoked for this Action.Not only we have written the shared attributes only once, but now we can disable the Save command (and consequently all the associated UI controls) simply by writing a single row of script code:

currentContext.getData(“idMap”).get(“saveAct”).setEnabled(false);

The advantages of using the Action tag aren't finished here, because this mechanism permits also to easily reuse the same panel within different contexts.

Imagine we have the necessity to save a file in different formats (say binary or XML) depending on the frame (i.e. the context) from within the 'Save' command is invoked; moreover, imagine that we have built  a reusable panel  that contains  the Save button,  that will  be displayed within the two different frames (imagine a frame where the panel is displayed alone, while in another one the same panel is displayed together with other panels, for instance within a side of a SplitPane).

You know we can use the XPanel   tag to  import   the same panel  within different  frames,  but  a problem arises when we try to determine the content of the Save button's ActionCommand attribute declared within the imported panel.

Imagine we have declared the following commands in the application context:

<bean id="saveAsXML" class="org.swixat.commands.CommandBinder">  <property name="type"><value>saveAsXML.bsh</value></property></bean><bean id="saveAsBinary" class="org.swixat.commands.CommandBinder">  <property name="type"><value>saveAsBinary.bsh</value></property></bean>

we cannot   link  the Save button's  ActionCommand to any of  the above commands,  because the button will be used in different contexts.You'll  have guessed that by using the Action tag we can resolve easily the dilemma, simply by writing, in the Frame_A.xml:

<Action id=”saveAct” text=”txtSaveAsXML” mnemonic=”mnSave”  accelerator=”accSave” command=”saveAsXML”/>...<XPanel xml=”xml/myPanel.xml”/>

and in the Frame_B.xml:

<Action id=”saveAct” text=”txtSaveAsBinary” mnemonic=”mnSave” accelerator=”accSave” command=”saveAsBinary”/>

...<XPanel xml=”xml/myPanel.xml”/>

whereas, in the myPanel.xml, we can simply write:

Page 20

Page 21: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

...<Button id=”saveBtn” actionCommand=”saveAct” />

Note that, thanks to this mechanism, we've been able also to differentiate the text displayed in the Save button ('txtSaveAsXML' in the Frame_A and 'txtSaveAsBinary' in the Frame_B, both declared in the locale property file). 

Special ActionCommands

Reserved words

In order to specify some specific behavior in response of an ActionCommand, we have declared the following reserved words:

Cancel:   when   a   component's   ActionCommand   contains   the   string   'Cancel',   the   corresponding command  will   close   the   current   frame.  The  onClosing   and  onClosed  events  will  be   raised,   if declared.The following button:<Button text=”Cancel”/>when pressed, will close the frame where it appears, without the necessity to write any external script code. In this case we don't need to declare the ActionCommand attribute because by default the button's text represents also the name of the associated ActionCommand.

RefreshView: this ActionCommand will refresh the content of the current frame's UI components, by re­reading all the declared DataSources. We can use this command in different manners:

● refreshView ­ refreshes all components● refreshView() ­ refreshes all components● refreshView($id) ­ refreshes the component having the given id● refreshView("id") ­ refreshes the component having the given id● refreshView($id1, $id2, $id3, ...) ­ refreshes all the components in argument● refreshView($id1, "id2", "id3", ...) ­ refreshes all the components in argument 

RefreshViewPattern: similar to refreshView, refreshes the components having the id that matches one or more patterns: 

● refreshViewPattern("pattern");● refreshViewPattern("pattern1", "pattern2", "pattern3", ...);

The “pattern” strings must contain a valid regexp expression. 

example: refreshViewPattern("^.*?ButtonPanel$");refreshes all the components with id like 'PersonButtonPanel', or 'CompanyButtonPanel' 

RefreshData: this command clears the content of all the cacheable DataSources within the current frame. See the chapter 'Data Sources' in order to learn more about cacheable data sources.

Page 21

Page 22: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

Static method invocation

As for the version 0.4.5, we have introduced the possibility to invoke whatever static public method of any class declared in the classpath of the application.The syntax is the following:

ActionCommand=”SomeClass.someMethod($someSource)”

SomeClass  is   the used class, and the framework searches for  this class by using the  'basedir' property declared in context.xml as the package name, after having substituted each '/' with '.' 

If basedir = “my/package/name/”, the class fully qualified name is constructed like this:my.package.name.ClassName

If the class is not found within the package pointed by 'basedir', the class is searched without any package.

The 'someMethod' is searched and invoked for that class. Of course the invoked method must be declared as static.

In the Java class you can have declared more arguments than in the XML code, as in this example:

public class MyClass {public static void myMethod (

Application app, AbstractFrame parentFrame, String dataFromMyDataSource){

...}

}

while the XML view contains:<Button id=”btn” actionCommand=”MyClass.myMethod($myDataSource)”/>

as you can see, the first two arguments are declared only in the java class, while the XML code contains only one argument. The first parameters can belong only to some specific types, so that they can be substituted by the corresponding objects' instances in the framework:● org.swixat.framework.Application● org.swixat.framework.Frame● org.swixat.model.Context

when the action is invoked, respectively the current Application, Frame or Context is passed to the method, according to  the matching data  type.  We also search the missing arguments  in _share, idmap and _parent context, in order to call correctly the Java method. 

All   the  remaining  parameters  declared   in   the XML view are considered  as   the  name of   some 

Page 22

Page 23: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

DataSource declared in the current Frame, so that the corresponding value will be passed to the invoked method (to learn more about DataSources, read the following chapter 'The Model').

As for  the version 0.5.0,  we can use  $e  as one of  the parameters  in  the XML call,  where  $e represents a pointer to the raised event intercepted by the ActionCommand. Of course the method must have declared a corresponding parameter belonging to a compatible type.

If the method returns void, then new Integer(0) is returned, otherwise is the same thing that with any   other   invoked   script   function   (i.e.   the   method   can   return,   for   example,   an   instance   of OutputView, if needed).

Multiple command support 

You can have more than one action in action command, each action must be separate by ';'. 

example:

<Button ... actionCommand="update($textfield/text, $MyObject/name); refreshView" />

Invoking a command from within script codeSometimes it could be useful to invoke a command directly from within script code, for example when we want to execute some action before to invoke the command.

To do that, we can simply write:

...currentContext.getData(“_frame”).executeCommand(“command”);

Of course the command string can represent a command declared in the application context file, a script function imported in the current frame, or one of the reserved commands (either 'cancel' or 'refreshView').The reserved key '_frame' in the current context returns a pointer to the current AbstractFrame class, hence you can call whatever else public method on it.

The ModelThis is represented by the object model of the calling application, hence we do not need to build any new class to implement it. We do however need a mechanism to permit a View to get all the data it needs to fill its internal UI controls (see the arrow #5 in the MVC schema).

To do this, we have defined a mechanism based on DataSources.

Page 23

Page 24: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

DataSourcesBy looking at the SwiXAT's MVC implementation presented at the beginning of this document, you'll   have   noticed   that   the   object   model   of   our   application   is   accessed   by   a   layer   named 'DataSource'.It  represents the bridge between the Model and the View/Controller modules.  All   the problems inherent   the   access   to   specific   sources   of   data   are   delegated   to   some   specific   DataSource implementation.

SwiXAT provides the user with some pre­built DataSource, but new ones can be added simply by implementing the org.swixat.databinding.DataSource interface.The use of the above interface permits the application to access in the same manner to whatever source of data, regardless its nature and/or location. This feature frees us from being worried about the kind of data we need to access to.   

The 'origin' attribute

Any DataSource implementation must have a property named 'id', that indicates the DataSource's name used by the Swing UI components in order to be linked to the corresponding data source, as explained in the following example:

<ContextDataSource id=”DSName” .../>

The Swing component that needs to be filled by the above data source must declare the property 'origin', setting its value to the id of the corresponding data source:

<label id=”name” origin=”$DSName” default=”some/XPath” .../>

In this way a View is able to get the required Model's data by simply connecting the UI control to the corresponding DataSource using the parameter tag 'origin'.When a View is  displayed,   the framework will   invoke all   the getData methods on  the defined DataSource objects.The  'origin'  attribute can contain also a XPath expression,   in order  to navigate and access  to a particular property of the object tree returned by the DataSource, like in the following example:

<Label origin=”$Customer/address/city”/>

Read the “How to use Xpath” paragraph in order to learn more about Xpath expressions.

If  the  'default'  attribute  is found,  the value returned by the corresponding  XPath  is used as  the component's origin in case the actual origin's value returns null. Ignored if the origin's value is not null. 

Origin attribute in JButton and JMenuItem

As   for   the  version  0.5.0,   the   'origin'   attribute   can  be  applied  also   to   JButton  and   JMenuItem 

Page 24

Page 25: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

components, but in this case the behavior is slightly different. For these two components, in fact, the value   returned  by   the  DataSource pointed  by   the  origin  attribute   is  used   to   enable/disable   the corresponding button or menu item: if the value returned is either a non­null value or a non­empty result set, the component is enabled. Otherwise it is disabled. The component is also disabled if the value returned by the origin data source is Boolean.FALSE.

Origin attribute in button groups

If the button has the buttonGroup attribute, then the button is added to the specified buttonGroup (creation of the buttonGroup is automatic if needed). The value returned by the origin attribute changes the button's state: 

• Boolean.FALSE or null = unchecked • Boolean.TRUE or not null = checked 

The 'render' attribute

As for the version 0.5.0 we have added also the 'render' attribute, that permits to set the content of a UI component by applying whatever valid XPath function.Let's explain with an example: suppose an origin's XPath expression used for a JLIST or some such reads as follows:

<List origin="$company/department[@name=$dept]/employee"> 

where  $company  and  $dept  are   variables   that   reference   previously   established   xpath   data sources.Imagine we would like the widget to display, on each line of the list, the full name of each employee e.g. John Doe, obtained from the @firstname and @lastname attributes of employee. 

Our solution has been to add a new render attribute to the GUI component that contains an optional XPath expression that renders the desired result. So, in this instance: 

<List origin=”...”render = “concat(./@first, ' ', ./@last)”>

As you can see, the '.' (dot) is used to reference the object pointed by the 'origin' attribute.For those that may not know, XPath 1.0 contains a number of handy string manipulation routines, and many other besides that can serve to format content.concat() can be thought of as a sprintf or println equivalent, with much greater expressive power relative to data retrieval, as nested xpath expressions can be employed as done in the example.The   scheme   is   very   general,   and   applies   to   widgets   that   either   handle   lists   (set   attribute iterate="true", as explained below) or single strings. 

Moreover,  whenever   a   render   attribute   is   encountered,   the  node   set   (a  List  when   iterate=true) obtained by evaluating the origin xpath expression is saved in the component's "originNodes" client 

Page 25

Page 26: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

property, so you can access to the 'origin' data from within script code by writing the following code:

originData = Component.getClientProperty(“originNodes”);

where Component is a pointer to the GUI component obtained by its ID (see the 'current context' paragraph).

The DataSource's common attributes

All the DataSources components have the following common attributes:

The 'path' attributeThis attribute contains the XPath used to get the needed value. It uses as root the object pointed by the data source. In order to learn more about how to use this attribute, read the section 'How to use XPath' below.

The 'iterate' attributeThis boolean attribute specifies if the object returned by the application of the xpath expression contains a 'scalar' value (false ­ the default), or a 'vectorial' value (true). This attribute makes sense if we think that an XPath operates on a DOM tree. In some circumstances the xpath expression could return multiple nodes, so in these cases it could be useful to set to true the 'iterate' attribute, in order to get all the instances found in the document.For example, for the following XML data source (but the same concept applies also for other types of data sources):

<developpers>  <person><name>paolo</name></person>  <person><name>benjamin</name></person></developpers>

the XPath “/developpers/person/name” returns:● the List [paolo, benjamin] if iterate is true● the String “paolo” otherwise

The 'cacheable' attributeEach DataSource can be declared cacheable, by setting to true the property “cacheable” (false by default). After the first invocation, a cacheable data source stores its data within an internal buffer, avoiding so to extract the data at each call of the DataSource.getData method. This is a very useful feature when the data access/extraction is very expensive in terms of elaboration time or resources occupied, and the source of data doesn't change very often.Of course this property doesn't make sense for every existing DataSources, so in some cases its value doesn't affect the behavior of the corresponding DataSource.A cacheable  DataSource  can  be  cleared  by  calling   the   'refreshData'   command   (either  within  a component's actionCommand attribute, or within script code). After a refreshData command, the 

Page 26

Page 27: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

next call to the DataSource's getData will re­read from the original source.

The <ContextDataSource> 

<ContextDataSource id="DSname" cacheable=”true|false”context="contextName"source="sourceObjName"path="some/XPath/selectedProperty"iterate="true|false"

/> 

The ContextDataSource is used to get the data from an application's context, and owns the following properties:

● context   : a string containing the name of the context from which the data is taken. There is one context already declared ­ “current” ­ that contains all the UI Swing components declared in the XML file of the current frame (see the 'current context' section below). 

● source   : a string containing the key of the object stored within the declared context. ● path   :  a string containing the XPath used to get  the needed value.  It  uses as root   the object 

pointed by the declared 'source' within the 'context'.

The <ScriptingDataSource> 

<ScriptingDataSource id="DSname" cacheable=”true|false”script="somePath/scriptFile.bsh"path="some/XPath/selectedProperty"iterate="true|false"

/> 

The ScriptingDataSource is used to get the data by using interpreted BeanShell java code, and owns the following properties:

● script   : a string containing the name and path of the file containing the scripting code. Within the script code, the returned object must be put in the predefined 'retValue' variable.

● path   :  a string containing the XPath used to get  the needed value.  It  uses as root   the object returned by the invoked script code.

● iterate   : a boolean value indicating if the value returned by the data source is a scalar value (false) or contains an array of values (true).

The <XPathDataSource> 

<XPathDataSource id="DSname" path="$DataSourceID/some/XPath"

Page 27

Page 28: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

/> 

The XPathDataSource is used to get the data from another DataSource, and owns the following property:

● path   :  a  string containing  the XPath used  to get   the needed value.   It  MUST begin with  the reference to the DataSource ID that will return the root object on which the remaining XPath expression will be applied.

This DataSource is useful in situations where we need to traverse many times the same object tree, in order to extract different objects/properties, starting from the same root object pointed by another DataSource. This permits us to reuse the same source of data avoiding to repeat many times the same xpath expression, like illustrated in the following example:

<!­ The root CUSTOMER object ­­><ScriptingDataSource id="EMPLOYEE" script="queryData.bsh"

path=”department[@name=$dept]/employee”/>

<!­­ References to the CUSTOMER object's properties ­­><XPathDataSource id=”FIRSTNAME” path=”$EMPLOYEE/firstName”/><XPathDataSource id=”LASTNAME”  path=”$EMPLOYEE/lastName”/><XPathDataSource id=”ADDRESS”   path=”$EMPLOYEE/address”/>... <Label origin=”$FIRSTNAME”/><Label origin=”$LASTNAME”/><Label origin=”$ADDRESS”/>

In this manner we decouple the GUI component from the corresponding data source, so we're able to reuse the same GUI (for example by using the XPanel tag) with different data sources.

The <ObjectDataSource>

<ObjectDataSource id="DSname" cacheable=”true|false” source="spring_Bean_ID"path="some/XPath/selectedProperty"

/> 

This DataSource uses as source of data an instance of the object declared in the Spring XML application context, pointed by ID contained in the 'source' attribute. Its attributes are:● source   : a string containing the ID of the object declared within the Spring application context. ● path   : a string containing the XPath used to get the needed value. It uses as root the bean pointed 

by the declared 'source' object.

Page 28

Page 29: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

The <DOMDataSource>

<DOMDataSource id="DSname" cacheable=”true|false” source="spring_DOM_ID"path="some/XPath/selectedProperty"iterate="true|false"

/> 

This DataSource accesses to the DOM obtained by the parsing of a resource containing a well formed XML file. The XML resource name must be declared in the Spring application context and is pointed by the 'source' parameter.

● source   : a string containing the ID of the DOM object, declared within the Spring application context. It  must point to a bean belonging to one of the following classes:

• String (containing a valid URI)• java.net.URL• java.io.InputStream

● path   :  a  string containing  the XPath used  to get   the needed value.  It  uses as  root   the DOM instance pointed by the declared 'source' object.

● iterate   : a boolean value indicating if all the instances found must be returned (false by default) 

This DataSource is very useful to get, for example, XML data from an HTTP server, on which the XML could be formatted dynamically by, for instance, JSP, PHP, ...any other server technology or language.

How to use XPathWithin each DataSource component, the 'path' tag contains a string that points to the property of the object extracted by the corresponding data source.It   must   contain   a   path   according   to   the   W3C   standard   XPath   syntax1  (see http://www.w3.org/TR/xpath).XPath is a very powerful mechanism that permits to traverse hierarchical structures. It was thought to navigate XML files (i.e. DOM structures), but an object tree is comparable to a DOM structure and can be traversed very easily using JXPath (http://jakarta.apache.org/commons/jxpath/), a library built to permit to apply XPath to whatever  Java object tree.

Let we have the following two java objects in our own object model:

public class Employee {    public String getName(){       ...    }     public Address getHomeAddress(){       ...    }

1 A good starting point to learn more about XPath is the W3Schools tutorial at http://www.w3schools.com/xpath 

Page 29

Page 30: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

}

public class Address {    public String getStreetNumber(){       ...    }}

We can access to the StreetNumber of the current Employee simply by using the following XPath:homeAddress/streetNumberOf course in the above example the root object is an instance of the class Employee.

Having as root object, instead, a container class containing a list of employees:public class Employees {    public ArrayList getEmployees(){       ...    }}

We could select a particular employee having the name 'Fred' with the following XPath:employees[name=”Fred”]/streetNumber

As the complete syntax of the XPath expressions is out of the scope of this paper, we recommend you to read the available JXPath documentation on the corresponding web site.

What we want to illustrate here is how to use XPath within the SwiXAT framework. Continuing with the above example, if we have in the current context a list of employees, we could extract the street number of the employee named 'Fred' by using the following data source:

<ContextDataSource id="DSStreetNumber" context="current"source="employees"path="employees[name='Fred']/StreetNumber"/>

To display the extracted street number within a label, we can write, in the same XML file:

<Label id=”streetNum” origin=”$DSStreetNumber” />

It's important that the data source referenced by the 'origin' property is declared within the same frame/panel containing the swing component that uses it.

The 'origin' parameter can contain also an XPath, so we can easily reuse the same data source by pointing to different objects belonging to the same object tree, as in the following example:

<ContextDataSource id="DS1" context="current"source="employees"path="employees[name='Fred']”/>

Page 30

Page 31: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

...<Label id=”name” origin=”$DS1/name”/><Label id=”streetNum” origin=”$DS1/homeAddress/streetNumber”/>

In this case we have used a DataSource in order to extract the entire instance of the Empoyee named 'Fred'; after that, the two labels access to two different properties of the extracted object, by using two different XPaths (in the form '$DataSourceName/some/XPath').

Remember: Wherever in the XML view a value of an attribute starts with “$”, then the string is interpreted and evaluated as an XPath expression.

Note: The origin string must always begin with the '$' character, regardless of the presence of a path after the DataSource's ID.

We can also reuse a previously declared data source as key within whatever else XPath:

<ContextDataSource id="NAME" context="current"source="parent"path="name"/>

<ContextDataSource id="EMPLOYEES" context="myContext"source="employees"/>

...<Label id=”streetNum” 

origin="$EMPLOYEES/employees[name=$NAME]/StreetNumber"/>

In the above example we have declared the data source NAME, that extracts the wanted name from a TextField contained in the previous frame (the “parent”), and then we have used that data source by referencing it within the Label's  'origin' property, in order to extract the corresponding street number of the Employee having the selected name.

The real value and usefulness of the above mechanism will be clearest after having read the next paragraph about what are and how to use the Contexts.

The ContextTo permit the passing of parameters between the Model and the View (and between two or more Views), a context can be created and handled.

Each context is represented by a data structure that stores all the parameters in the form key­value pairs, permitting get/set operations based on that name.

In order to be able to differentiate parameters with the same name, but declared in different Views, we have implemented a mechanism to store different contexts, each one identified by a context name. Consequently we have implemented a 'context by name' accessing mechanism, based on the ContextBinder component.

Page 31

Page 32: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

The writing/reading of whatever context's  value can be done from within scripting code in   the following manner:

myObject = context.getContext("contextName").getData("objID");

where:

● The implicit variable 'context' points to the container of all the declared contexts (represented in the framework by the org.swixat.model.ContextBinder class)

● The string “contextName” is the name of the context to which we want to access. Use the string 'current'  to access to the context containing all the UI components of the calling frame. This parameter  is  omitted if  we want  to access  to  the  'default'  context (which one created by the framework itself).

● The string “objID' is the key identifying the object within the context. For the 'current' context, use the 'id' of the needed Swing component (as declared in the frame's XML file)

If the context name is null, then the 'default' context is returned. The 'default' context is created by the framework when the application is started, so you can use it to temporary store/retrieve your own data.

In order to create a new context, you can write within script code:

newContext = context.setContext(“contextName”, new GenericContext()); 

and then, to put a key­value pair within it:

newContext.setData(“newKey”, value);

or:

context.getContext(“contextName”).setData(“newKey”, value);

NOTE:  because  the global  contexts,   if  not accurately cleaned from the old unused values, can create memory leaks, you're invited to avoid to use this global mechanism of memory storage. In any case, remember to deallocate the resources when not more used, by setting to 'null' the corresponding key:

● to remove a context's key, use: context.removeData(“key”)

● to remove an entire context, instead, use: context.setContext(“contextName”, null)

Use instead the current context, as described in the next section.

The 'current' context

As said, the 'current' context contains all the declared variables of our application (in the form key­

Page 32

Page 33: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

value pairs). It can be accessed either by the ContextDataSource tag within the XML view (using “current”   as   context   name),   or   from   within   any   script   code   by   using   the   predefined   variable currentContext.

There is a different current context for each frame opened within our application. This means that, when a frame is closed, the corresponding context is destroyed, and its content is passed to the invoked frame within the key “parent”. Hence in any given moment, each frame can access both to its own context and the caller frame's context.

In fact the current context contains the following predefined keys:● “idMap”:   a   java.util.Map   containing   all   the   UI   components   declared   in   the   current   frame, 

indexed by their ID. Example.: currentContext.getData(“idMap”).get(“someID”)● “parent”:   within   a   frame   invoked   by   another   frame,   this   key   points   to   the   caller's   idMap. 

Example: currentContext.getData(“parent”).get(“someParentID”)

The following scheme illustrates how the context is managed by the framework when two frames need to share some UI control's content:

The numbers indicate the steps involved:

1. The user fills the text field in the Frame A and then pushes the button 'OK' (in the configuration file, the ActionCommand linked to that button opens a new window named 'Frame B').

2. In response of the button's ActionCommand, before to open the Frame B, the framework stores all the UI components in the “idMap” of the current context, in the form of key­value pairs (this is a default action always executed by the framework). Note: even if in the context table we have indicated the content of the text field (the string 'XYZ'), indeed in the idMap the framework stores a reference to the TextField component itself.

3. The framework, before  to open  the new frame,  creates a  new context   (that  will  become the current context of the new opened frame), and inserts into it a reference to the Frame A's idMap, with the key “parent” (note: it's a reference, NOT a copy). 

Page 33

CurrentContext A

XYZName:

OK

Key Value

name “XYZ”

XYZName:

Frame A Frame B

1

2

idMap

CurrentContext B

Key Value

name “XYZ”

parent3

4

Page 34: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

4. The framework, in the initialization code of the Frame B, fills the UI components with the values got from the declared data sources, according the tags written in the frame's XML description file.

The code used in the previous example should be:

In the FrameA.xml:

<TextField id=”name”/>

...

<Button id=”ok” text=”OK” ActionCommand=”openFrameB”/>

In the FrameB.xml:

<ContextDataSource id=”DSName” context=”current” source=”parent” path=”name/text”/>

...

<Label id=”custName” origin=”$DSName”/>

So, when this second panel will be displayed, the getText method will be invoked on the TextField component of the Frame A (that one having 'name' as id), and the label 'custName' will be filled with the returned text.

The 'shared' context

In   some   cases,   it   could   be   useful   to   share   some   values   between   more   frames,   all   of   them descendants of a unique parent frame. We have resolved this requirement by adding a reserved context's key named '_shared'.

When a new frame is opened, if in the parent frame's context the key '_shared' is present, then its value is copied within the newly created frame's context with the same key.

Context's keys accessors methods

As of SwiXAT 0.5.5, in order to simplify the access to interesting context values, we have defined the following methods: 

• ctx.getParent():Context returns the context of the parent frame 

• ctx.getShared():Context returns the shared context 

• ctx.containsData("key"):boolean checks if the key has been defined in the context 

• ctx.getFrame():AbstractFrame returns the frame associated with this context 

• ctx.getWidget(id):Object method to access directly to the Widget registered with 'id' in XML context file 

The following JavaScript code: if (currentContext.getData("idMap").get("id").getSelectedIndex() == ­1) 

Page 34

Page 35: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

   {...

can be written as: if (currentContext.getWidget("id").getSelectedIndex() == ­1)

   {...

Changes introduced in SwiXAT 0.5.5Note: currentContext.getData(“someKey”) returns now Context.UNINITIALIZED if “someKey” doesn't exist in the context. This permits to differentiate between a null value put by the user, and no existing key. 

Consequently, the following JavaScript code: if (currentContext.getData(“key”) != null) {...

doesn't work anymore, so it must be rewritten as: if (currentContext.containsData(“key”)) {...

Updating the model: the UpdateOrigin commandThis new command  is used  to update  the origin,  or whatever other  thing pointed by an XPath expression, when the corresponding event is thrown.It must be inserted within an xxxEvents tag in the XML View. We have prepared some examples in order to explain how does this mechanism work.

Example 1: the TextField's origin is used as target.

<TextField id="TF" origin="$DataSource/someProperty"> <DocumentEvents onChangedUpdate="UpdateOrigin"

onInsertUpdate="UpdateOrigin" onRemoveUpdate="UpdateOrigin">

<UpdateOrigin source="$TF/text"/> </DocumentEvents></TextField>

As you can see, the UpdateOrigin command is executed in response to some document's events. When the command is executed, the <UpdateOrigin> tag is searched, and its 'source' attribute is parsed   in  order   to   extract   the  data  used   to  update   the  property  pointed  by   the  origin's  XPath expression. In the above example the DataSource.someProperty will be updated with the value from the text property of the TextField component named 'TF').

Example 2: we use a specifique target because the List's origin is used as list model.

<List id="list" origin="$xpath/to/listModel"> <MouseEvents onClicked="UpdateOrigin"> <UpdateOrigin source="$list/selectedItem"

Page 35

Page 36: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

target="$AppObject/some/attribute"/> </MouseEvents></List>

Same as  the previous example,  but  in  this  case the <UpdateOrigin> tag contains also a  'target' attribute. This is because the List's origin attribute cannot be used, as it points to a ListModel, not to an Object's property.

Example 3: here “checkForAttributeValidity” is the actionCommand executed in order to verify some condition: if 0 is returned, then the UpdateOrigin is performed, else nothing is done.

<TextField id="TF" origin="$AppObject/xpath/to/attribute"> <DocumentEvents onChangedUpdate="UpdateOrigin"

onInsertUpdate="UpdateOrigin"onRemoveUpdate="UpdateOrigin">

<UpdateOrigin condition="checkForAttributeValidity" source="$TF/text"/>

</DocumentEvents></TextField>

If a type conversion is needed between source and target values, you can write and put a specific converter by calling: org.apache.commons.beanutils.ConvertUtils.register(Converter converter, Class clazz);

The UpdateOrigin tag accepts also an actionCommand attribute. If present, then the declared actionCommand is executed after the update action is performed.

Using the 'update(...)' command

UpdateOrigin can be replaced simply by the “update(...)” command:

● update searches UpdateOrigin component in caller if caller is the Container that must perform the update

● update(xpathSource) the destination is the origin attribute on the parent component● update(xpathSource, xpathTarget) both source and target are indicated● update(xpathSource, xpathTarget, postActionCommand) same as above, along with the 

command to execute after the updating is done● update(preConditionCommand, xpathSource, xpathTarget, postActionCommand) the 

preConditionCommand is executed before the updating is done. Must return 0 if the update must be performed, 1 otherwise. 

Example: a selection in the ComboBox changes the value in the TextField, and vice­versa.

<ComboBox id="combo" origin="$articles"

Page 36

Page 37: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

actionCommand="update($combo/selectedValue/price, $field/text)"

/><TextField id="field"> <DocumentEvents

onModified="update($field/text,$combo/selectedValue/price)" /></TextField>

In the above example we can see the importance to keep the real object in Swing components, and not the String representation.In the above example we didn't check the price before updating the object, if we want to check the price, we can use a specific UpdateOrigin XML element, as illustrated in the following example:

<ComboBox id="combo" origin="$articles" actionCommand="update($combo/selectedValue/price, $field/text)"/><TextField id="field"> <DocumentEvents

onModified="update(Util.checkStringIsNumber($field/text), $field/text, $combo/selectedValue/price, '')"/>

</TextField>

If the condition in the update returns 0, then the update is done.

The Model's events handlingSomeone will have noticed that we still didn't speak about the handling of the model's events, as contemplated by the MVC pattern, and as described by the arrow #4 in the MVC schema shown at the beginning of this document.

As of SwiXAT 0.3.0 we have added a mechanism to handle any event raised by any business object of our model.

The model's event handling is based on a custom class that must be written by the developer. This class represents a 'bridge' between the business object that raises the event and the corresponding framework's class that handles that event. Thanks to this mechanism, the business objects used by our application are not aware of SwiXAT, as they don't need to be coupled with the framework in any way.

The 'bridge' class must implement the interface of the business object's events listener. Moreover, it must extend the org.swixat.events.AbstractModelEvents class. 

The  mechanism  is   adherent   to   the  Observer  design  pattern,   and   is  described   in   the   following schema:

Page 37

Page 38: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

The classes in the above schema belong to the StockPicker example that you can find within the samples directory of the SwiXAT distribution package.

StockListener is an existing interface in the application's object model, and describes the interface to implement to write a model's event listener.The AbstractModelEvents class is declared in the framework, and must be extended by the custom event handler class, that in this example is represented by the StockListenerImpl.The following listing shows its source code:

public class StockListenerImpl extends AbstractModelEvents implements StockListener {    private static String PRICE_CHANGED = "onPriceChanged";        /** Specific StockListener's event.     *  Inherited from the StockListener interface     */    public void onChange(PriceChangedEvent pce) {        ModelEvent event = new ModelEvent(PRICE_CHANGED, pce.getSource(), pce);        fireOnEvent(event);    }

    /** Methods invoked by the framework in order to register this wrapper as     * model's event listener.     */    public void registerAsListener() {        ((StockPicker)getSource()).addStockListener(this);    }

    /** Methods invoked by the framework in order to unregister this wrapper as     * model's event listener.     */    public void unregisterAsListener() {        ((StockPicker)getSource()).removeStockListener(this);    }

}

Page 38

Page 39: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

As you can see, we have implemented only three methods:

● The 'registerAsListener' and 'unregisterAsListener' methods, that are invoked by the framework in order to permit the wrapper to be registered/unregistered as the model's event listener. As the mechanism used to register a model's listener is dependent on the model's implementation, we need to write here custom code, according to the object model we're using. In the example we call   the  business  object's   addStockListener  method,  passing  as  parameter   a   reference   to   the wrapper itself (this is possible because the wrapper implements the StockListener interface, as expected by  that  method).  The model  object   to which  the wrapper needs  to be registered  is contained within the 'source' property of this class, and points to the object referenced by the XPath written in the  'origin' parameter of the corresponding tag where this listener has been declared (see view's XML code below).

● The 'onChange'  method is the specific event handler invoked by the business object when the requested event is raised. It is declared within the StockListener interface and its signature can change depending on your own business model. Within this event handler we need to instantiate a ModelEvent object (the event object expected by the wrapper's listener) passing as constructor's parameters the name of the captured event, along with a reference to the object that has generated the event (in our example we get it by calling the event.getSource() method, but also this can change,  and depends on  the specific  behavior of your  business  model).  After   that,  we must invoke the fireOnEvent method, that is inherited by the AbstractModelEvents class. This method will permit the SwiXAT framework to notify the listener of this wrapper (i.e. the current View), in order to permit the execution of the corresponding action.

That's all. As you can see, the code you need to write is really simple and is composed only by few rows of java code. Of course this class must be compiled and inserted within the classpath of your application.

In order to be instantiated, this class must be associated to a new tag, and to do it, we need to extend the tag library by writing in the XML application context, within the “newTags” bean (read the Chapter 3 ­ The Application Context XML file – to learn more about it), the following code: 

<!­­ TagLibrary extensions ­­><bean id="newTags" class="org.swixat.framework.TagLibraryExt">   <property name="newTags">      <map>         <entry key="StockPickerEventHandler">

     <value>org.swixat.samples.stockPicker.model.StockListenerImpl</value>         </entry>      </map>   </property></bean>

So we can instantiate and use the listener within a view's frame (or internal frame) in this manner:

<Frame ...>    <!­­ The source business object ­­>    <ContextDataSource id="getStock" context="current" source="stockPicker"/>

Page 39

Page 40: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 1: The MVC Paradigm

        <!­­ Model's Event Handler ­­>         <StockPickerEventHandler origin="$getStock" onPriceChanged="refreshView"/>    ...

Now we have all the pieces of the puzzle in the right place, so let's show how the entire mechanism does work:

1. The tag <StockPickerEventHandler> is parsed by the framework when the corresponding view is invoked

2. The corresponding class (StockListenerImpl) is registered as a listener of the business object declared by the 'origin' attribute (an instance of the StockPicker class, in the above example returned by the ContextDataSource named 'getStock'). We know that the registration is made by invoking the   method  registerAsListener,  where the programmer will  have written the corresponding code 

3. When the business object will raise the 'priceChanged' event, the 'onChange' event handler will   be   invoked,   within   which   the   'fireOnEvent'   method   will   be   invoked,   causing   the execution   of   the   command   declared   in   the   'onPriceChanged'   attribute   of   the <StockPickerEventHandler> tag ('refreshView' in the above example).

Within  the command  invoked by  the corresponding event handler,   it's  possible  to  reference  the original model's event object simply by accessing to the  '_arg'  key of the current context (like already seen in the UI component's event handling). This is very useful in all the situations where the raised model's event contains some custom property to which we need to access.

As you can see, it's very simple to use this powerful mechanism. All you need to do is to write the simple class that implements your own business object's listener, along with few rows of XML code.

As already said, the business model doesn't need to know anything about the SwiXAT framework, because the wrapper creates the needed uncoupling between the model and the framework.This is useful in order to permit to reuse whatever existing business object without modifications.

That wrapper is the only class the developer needs to write, because all the remaining parameters have to be written simply within the corresponding XML parameter files.

Page 40

Page 41: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

Chapter 2: Special Features

Being SwiXAT based on SwiXml, all the tags defined in that framework can be used within the XML that describes a view. To see a list of all the accepted tags along with their attributes, go to http://www.swixml.org/tagdocs/index.html.

SwiXAT, however, can be extended with new tags, in order to add whatever new feature to a view. Other than some specific tags, like those that permit to declare a data source, that will be explained in detail in the next chapters, let's explain here what are the tags we have declared to add some specific UI control to a view.

Support for MDI applicationsSwiXAT provides a strong support for MDI  ­ Multi Document Interface ­ applications, particularly with the availability of the <InternalFrame> tag, used to instantiate a JinternalFrame.

In order to declare a MDI application, you need to insert a <DesktopPane> tag within the Frame XML   view,   and   declare   the   ID   of   that   pane   within   the   XML   application   context   (see   the 'Application bean' paragraph in the Chapter 3). After that,  you can use all the tags illustrated in this paragraph, in order to use all  the features SwiXAT provides you.  

The <WindowMenu> tagA useful feature, for MDI applications, is to have a menu containing the list of the open internal frames, along with some tool to adjust automatically the size and position of those frames.The   tag  <WindowMenu>  permits   to   add   such a  menu  within  whatever  menu  bar,   like   in   the following example:

  <menubar>...<WindowMenu id="menuWindow" text="Window" />...

  </menubar> The above view, when displayed, will generate a 'Window' menu like this:

Page 41

Page 42: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

As you can see, it contains the list of the opened internal frames, where the user can either choose the frame to bring to front, or align the internal frames in two predefined manners (cascade or tile).Whenever an internal frame is opened or closed, the above list is updated to reflect the frames existing in the main window.All the above features are available out­of­box, without writing any line of code!As the class instantiated by the 'WindowMenu' tag extends the Swing's Menu class, it accepts all the attributes permitted for the <Menu> tag, like 'mnemonic', 'accelerator', etc.

The <MDIDesktopPane> tagAnother useful feature for MDI applications is the possibility to have a scrollable desktop pane, so that, when an internal frame is moved outside the visible window's area, a scrollbar is displayed.That desktop pane is obtained by using the tag <MDIDesktopPane> instead of <DesktopPane>, like in the following example:

<Frame ...>    ...    <ScrollPane constraints="BorderLayout.CENTER">        <MDIDesktopPane id="desktop" opaque="false"/>     </ScrollPane> </Frame> 

Note that the MDIDesktopPane, in order to work properly, must be inserted within a ScrollPane component.

This is the visual behavior of a MDIDesktopPane when an internal frame is moved beyond the external border of the main window...

Page 42

Page 43: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

...as you can see, a horizontal scrollbar appeared.Of course a vertical scrollbar would be appeared if we had moved the internal frame beyond the lower edge of the window.

The <ModalInternalFrame> tagBy default, all the internal frames declared with the tag <InternalFrame> are instantiated as no­modal frames. No­modal frames permit  the user to click anywhere in the application's window, outside the no­modal frame, in order to choose/activate whatever else available feature.Although   the   above   behavior   is   the   preferred   in   many   situations   within   a   MDI   application, sometimes it's useful to display an internal frame without giving the user the possibility to activate other frames/functionalities of the application until that frame is not closed.This   kind   of   frame   is   called   'modal',   and   can   be   instantiated   in   SwiXAT   by   using   the   tag <ModelInternalFrame>, like in the following example:

<ModalInternalFrame id="aboutFrame" size="350,180" title="About Box" layout="BorderLayout" Maximizable="false" Closable="true">    

...</ModalInternalFrame>

The 'About Box' is a classical example of a modal frame, and as shown by the above example, the tag ModelInternalFrame can be used exactly as you'd use any InternalFrame tag.The unique difference is that in this manner you create a 'modal' internal frame.

Support for JComboBox and JList  components

The <ComboModel> and <ListModel> tagsWe have already seen, in various examples, that the 'origin' attribute of a GUI component points to 

Page 43

Page 44: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

the DataSource that extracts and returns the data used to fill the content of the GUI component.This   is   true  also   for   JList  and  JComboBox  components,  because  we can   fill   them by using  a DataSource that returns an array of values.Sometimes, instead, we need to interpret the 'origin' attribute as 'the value to use as current value for the component'.    In   order   to   accomplish   this   requirement,   as   for   the   version   0.5.0,   the   support   for   the JComboBoxModel and JListModel has been added.Let's show how to use them with an example (we'll use a JComboBox, but the same syntax can be used for a JList):

<ComboBox origin=”$DS1/some/path/selectedValue”>   <ComboBoxModel origin=”$DS2/some/path/listOfValues”/></ComboBox>

As you can see, we have two 'origin' attributes:That one at the level of the ComboBoxModel tag points to the list of values used to fill the content of the ComboBox, while the ComboBox's origin attribute points to the current selected value in the list. This is very useful when, for example, we extract the list of possible choices from a column of a table in a data base, and the current value is read, instead, from the query made on a different table.Of   course   the   two   'origin'   attributes   can  point   indifferently   either   to   the   same  or   to   different DataSources.

The <ComboBoxRenderer> tagThe ComboBoxRenderer tag permits to encapsulate real Renderers.To learn more about renderers, see the java documentation about javax.swing.ListCellRenderer interface. The real renderer must be a child of this tag in the XML description.This permits to use whatever renderer implemented for a normal swing application in a very simple manner, like in this example:

<ComboBox origin=”$Data”>  <ComboBoxRenderer>    <MyDefaultRenderer/>    <MyPersonRenderer type="Person"

    childsPropertyName="address/city"/>    <MyAddressRenderer type="Address" childsPropertyName="city"/>    <MyStringRenderer type="String"/>  </ComboBoxRenderer></ComboBox>

As you can see, you can use different renderers for the same GUI component.In the above example:

1. MyDefaultRenderer is used when no other renderer is found.2. MyPersonRenderer is used for data belonging to the class Person, and the value displayed 

will be the value returned by Person.getAddress().getCity()3. MyAddressRenderer is the same thing, only for instances of the Address class.

Page 44

Page 45: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

4. MyStringRenderer is the same thing for String objects.

The real renderer used will be that one having the 'type' attribute corresponding to the class of the data pointed by the 'origin' attribute. If there isn't any matching renderer, that one without the 'type' attribute will be used. If no empty renderer is found, the  javax.swing.BasicComboBoxRenderer class will be used.Each xxxRenderer tag listed in the XML view must be declared in the XML application context, within the 'newTags' section (see 'The TagLibrary extensions' paragraph), and must point to a class implementing the  javax.swing.ListCellRenderer interface.

The ComboBox's “values” attributeIf values="..." is found on ComboBox tag, it's used as the model. The values are comma separated. You can use an XPath expression for each value.

Example: <ComboBox values='"String","Int","Float",$DS/type'/>

We have also added the support for empty first element: we have added the boolean “firstNull” attribute to permit to have an empty row at the first position:

<ComboBox firstNull="true" ...>

Support for JTree componentsFor JTree components, we have implemented several mechanisms useful to fill  the internal tree, starting from the custom object model of the application.

Normally, if the 'origin' attribute declared within the <Tree> tag points to a DataSource that returns a TreeModel instance, that model will be simply used as the tree's model.

Beside  this   simple  basic  mechanism,  we have  implemented   two different   techniques   to   set   the content of a JTree, as illustrated in the following paragraphs.

The <TreeModel> and <TreeCellRenderer> tagsIn order to permit to use a JTree, and fill its internal model with a tree that is loaded starting from some hierarchical structure mirroring our own business model, we have inserted the <TreeModel> tag.Its syntax is the following:

  <Tree id="names" origin="$xpath/to/tree/root">     <TreeModel childsPropertyName="rootPropName">        <TreeModelMapping type="some.path.to.subTreeClass" 

      childsPropertyName="subTreePropName"/>     </TreeModel>

     <TreeCellRenderer textPropertyName="textPropName" 

Page 45

Page 46: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

 toolTipTextPropertyName="toolTipPropName">        <TreeCellRendererMapping type="some.path.to.subTreeClass" 

 textPropertyName="subTreeTextPropName"  toolTipTextPropertyName="subTreeToolTipPropName"/>

     </TreeCellRenderer>  </Tree> 

As you can see, the TreeModel and TreeCellRenderer tags must be inserted within the <Tree> tag of which they describe both the model and the appearance. The 'childsPropertyName' attributes must contain the name of the getter properties that permit to 'traverse' the object tree for data belonging to the   class   described   in   the   'type'   atribute,   whereas   the   textPropertyName   and toolTipTextPropertyName contain the methods that return respectively the description and the tool tip text of each kind of 'type' node.

As example, let's have the following java classes:

public class Animals {    private static final Animal rootAnimal = createAnimals();

    private static final Animal createAnimals() {        Animal root = new Animal("Animals");        root.setChilds(new ArrayList());        // Elements linked by the 'childs' property        Animal mammals = new Animal("mammals");        root.getChilds().add(mammals);        mammals.setChilds(new ArrayList());        mammals.getChilds().add(new Animal("rabbit"));        mammals.getChilds().add(new Animal("dog"));                ...

   // Elements linked by the 'subCategories' property        NoneAnimal mystic = new NoneAnimal("mystic");        root.getChilds().add(mystic);        mystic.setSubCategories(new ArrayList());        mystic.getSubCategories().add(new NoneAnimal("hydra"));        mystic.getSubCategories().add(new NoneAnimal("pegasus"));         return root;    }

    public Animal getRootAnimal() {        return rootAnimal;    }}

public class Animal {            private Collection childs;    ...    public Collection getChilds() {                return this.childs;    }

Page 46

Page 47: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

    public String getName() {                return this.name;    }}

public class NoneAnimal {    private Collection subCategories;    ...        public Collection getSubCategories()  {        return this.subCategories;    }        public String getDescription()  {        return this.description;    }}

The above three classes represent our own object tree:1. The Animals class builds the entire Animals' tree, and its  getRootAnimal method returns 

the Animal's instance representing the root of the tree.2. The Animal class represents a kind of nodes of the tree, and the getChilds method points to 

its childs nodes, constituted themselves by instances of the Animal class.3. Finally, the NoneAnimal class represents another kind of nodes belonging to the same tree, and 

the  getSubCategories  method   returns   its   childs,   constituted   by   instances   of   the NoneAnimal class.

In order to fill a JTree with the above object tree, we need first of all to write a script that creates and returns the instance of the Animals class (bsh/getAnimals.bsh):

return new Animals();

Now we need to instantiate a JTree having as model the above created object tree:

  <ScriptingDataSource id="ANIMALS" script="bsh/getAnimals.bsh"/>           <ScrollPane constraints="BorderLayout.CENTER">         <Tree id="names" origin="$ANIMALS/rootAnimal">      <TreeModel childsPropertyName="childs">        <TreeModelMapping 

  type="org.swixat.samples.baseApp.model.tree.NoneAnimal"   childsPropertyName="subCategories"/>

      </TreeModel>                  <TreeCellRenderer textPropertyName="name" 

  toolTipTextPropertyName="name">        <TreeCellRendererMapping 

  type="org.swixat.samples.baseApp.model.tree.NoneAnimal"   textPropertyName="description" 

Page 47

Page 48: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

  toolTipTextPropertyName="description"/>      </TreeCellRenderer>    </Tree>  </ScrollPane>

In this example the XPath expression written in the JTree's origin attribute points to the rootAnimal property of the Animals class returned by the ScriptingDataSource.

The  TreeModel,   in   order   to   fill   the   entire   tree,   will   traverse   the   object  model   by   calling   the 'getChilds'  property for each node of kind Animal, and the  'getSubCategories'  property for each node of kind NoneAmimal, as declared by the childsPropertyName attributes.The 'getName' and 'getDescription' methods, instead, are used to get the text and tool tip text for the two kinds of node objects.

The resulting tree is the following:

 We can also fill a multi­root tree by using the same <TreeModel> tag.The unique difference is represented by the root of the tree, that in this case must be a Collection containing all the roots of our tree.To do it, we'll change the XML view in this manner:

  <ScriptingDataSource id="ANIMALS" script="bsh/getAnimals.bsh"/>           <ScrollPane constraints="BorderLayout.CENTER">            <Tree id="names" origin="$ANIMALS/rootAnimal"           rootVisible="false">        <TreeModel childsPropertyName="childs"/>

   ...     </Tree>

   ...  </ScrollPane>

Note that the unique difference is represented by the 'rootVisible' JTree's property, set to false 

Page 48

Page 49: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

in order to make the JTree a multi­root tree.

The result of the above changes are displayed in the following figure:

With this simple mechanism we're able to fill  a JTree with any kind of hierarchical object tree, regardless of the internal structure of our object model.

The TreeCellRenderer tag accepts also the closedIcon, leafIcon and  openIcon attributes, that must contain the icons' paths used for the different kind/state of each tree's node. No resource key is supported at the moment.

The <NestedTreeModel> and <TreeNode> tagsWe have implemented a new TreeModel, named NestedTreeModel, to permit to display more easily a business model's tree of objects in situations where some nodes represent simply the category's name (not derived by real object's instances) within which some child nodes must be grouped.

If we have an object 'Person' like this:

If we want to display one person as Root TreeNode, and somethink like this for tree:

George Brown­+             +­ Parents ­+             |           +­ Mother

Page 49

Page 50: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

             |           +­ Father             +­ Children             +­ Friends ­+                         +­ Sam Black                         +­ Ralph White

where the 'Parents', 'Children' and 'Friends' nodes don't derive directly from some object's callable method.

We can write within the XML view:

<Tree id="tree" name="tree">   <NestedTreeModel id="treeModel">     <TreeNode id="rootTreeNode" origin="$Person">       <TreeNode name="Parents">          <TreeNode treeOrigin="../.." childsPropertyName="parents"/>       </TreeNode>       <TreeNode name="Children">          <TreeNode treeOrigin="../.." childsPropertyName="childs"/>       </TreeNode>       <TreeNode name="Friends">          <TreeNode treeOrigin="../.." childsPropertyName="friends"/>       </TreeNode>     </TreeNode>   </NestedTreeModel></Tree>

We get the following interesting features:• We can put any number of TreeNodes in a TreeNode.• treeOrigin take orgine from another TreeNode, only .. is permitted or ../../.., etc• childsPropertyName contains an XPath pointing to a property belonging to the node's origin 

pointed by treeOrigin• We can put the origin attribute in any TreeNode, if needed• It's very easy to find the TreeNode associated with any user object. On NestedTreeModel, 

you have getNode(userObject):TreeNode method (if the same userObject is used more than once, the last is returned). This permits, within script code, to select easily Nodes in a Tree when we have a pointer to one of the used user objects

As label of each node, the value returned by the DataSource pointed by the 'origin' attribute is used, if   declared.   Otherwise   treeOrigin.childsPropertyName   is   used;   finally,     the   'name'   attribute   in treeNode is used, if none of the above applies.

The enhanced Renderer mechanismsAs of SwiXAT 0.5.5 (thanks to the great work made by Benjamin Poussin), a new enhanced items rendering mechanism has been implemented. By using it, now it's possible to choose a different renderer based on the class each single item belongs to. This mechanism works for JList, JComboBox, JTree and JTable components. 

Page 50

Page 51: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

The corresponding tags are:● <ListRenderer> and <DefaultListCellRenderer>● <ComboBoxRenderer> and <DefaultComboBoxRenderer>● <TreeRenderer> and <DefaultTreeRenderer>● <TableRenderer> and <DefaultTableCellRenderer>

For example, we can have, for a JTree object:

<Tree id="tree" name="tree"> <NestedTreeModel id="treeModel"> <TreeNode ..../> </NestedTreeModel> <TreeRenderer> <DefaultTreeRenderer type="some.package.Person"

childsPropertyName="firstname" toolTipPropertyName="firstname"/>

<DefaultTreeRenderer type="some.package.Company" childsPropertyName="name"/>

... </TreeRenderer></Tree>

in this case we have different renderers for different Classes (Person and Company in the example).

We can also write something like this if all the objects in the tree expose the same property ('name' in the example)

<Tree id="tree" name="tree" renderer="name"> <NestedTreeModel id="treeModel"> <TreeNode ..../> </NestedTreeModel></Tree>

The <XPanel>, <XMenuBar> and <XToolBar> tagsWhenever we need to reuse some panel, menu bar or tool bar, we can use these three tags, that permit to import the corresponding GUI definition fragment from an external file.

Their syntax is the following:

<XToolBar xml=”path/to/aToolBar.xml”/><XMenuBar xml=”path/to/aMenuBar.xml/><XPanel xml=”path/to/aPanel.xml”/>

Page 51

Page 52: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

As you can see, all the above tags accept an attribute named 'xml', that must point to the name of the XML file containing the corresponding GUI definition fragment.Of course the root element within each external file must be of a type compatible with the type expected by the corresponding import statement, as in the following examples:

aToolBar.xml:<toolbar orientation="HORIZONTAL" ...>   ...</toolbar>

aMenuBar.xml:<menubar>   <menu ...>   ...</menubar>

aPanel.xml:<panel layout=”GridBagLayout” ...>   ...</panel>

The <DatePanel> and <DateField> tagsThe possibility to choose a date from a user friendly calendar­like panel, instead of inserting directly the date by hand, is very useful for many applications that need to ask the user for a date.SwiXAT permits to do it thanks to two tags, named respectively DatePanel and DateField.They are used in the following manner:

<DatePanel id=”someID” origin=”$xpath/to/aDate” date=”mm/dd/yyyy” />

the 'origin' and the 'date' attributes are both optional and mutually exclusive, because both they can be used to set the initial displayed date (set to today by default), respectively in a dynamic or static manner.The resulting component shown in the view is the following:

The DateField tag is similar, because it accepts the same attributes of the above component. The unique difference is that it displays a single date field, similar to a combo box, and the calendar 

Page 52

Page 53: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

panel is displayed only when the arrow near the field is pressed.The   above   two   components   are   derived   by   the   Nachocalendar   project (http://sf.net/projects/nachocalendar),  hence  you can   read   the  project  documentation   in  order   to learn more about these components.

The <TableChooser> tagThis component extends a JTable, where one of the columns is reserved to show a check box.The TableChooser is useful whenever we want to show a list of items composed by different fields (displayed within different columns of the table), and want to permit the user to choose some rows of the table by clicking on the corresponding check box.

The TableChooser component can be instantiated in the following manner:

     <TableChooser id="TChooser"columnsName="ColName1|ColName2|..." 

       checkBoxCol="n"origin="$DataSourceID“

/>

It exposes the following properties:

● columnsName   : The list of columns' names separated by the character '|'. If omitted, the columns will be named Column 1, Column 2,  etc.

● checkBoxCol   : An integer indicating which column will be reserved to contain the check boxes● origin   : Points to the ID of the data source that will return the data contained in the table. The 

returned value must be a 2D array of Objects. The number of the table's columns will be equal to the number of columns of the array + 1 (that one containing the check boxes)

For example, if we have a DataSource named “CUSTOMERS” that returns the following 2D array of Strings:

Ralph White White Street, 44 London

Sam Black Black Street, 55 New York

Tom Yellow Yellow Street, 66 Paris

Paul Green Green Street, 77 Rome

and our XML view contains the following code:

   <ScrollPane>       <TableChooser id="TChooser"

columnsName="Name|Call|Address"        checkBoxCol="2" origin="$CUSTOMERS"/>   </ScrollPane>

Page 53

Page 54: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

the following TableChooser will be shown:

As you can see, the second column, that contains the check boxes, has been added by the TableChooser itself, as our original table was composed by a 2 columns array.In order to get the list of selected rows, we can write the following script code:

chooser = currentContext.getData(“idMap”).get(“TChooser”);Boolean[] selections = chooser.getCheckData();...

obtaining so an array of Booleans where each element is true only if the corresponding table's checkbox is checked.

Support for JTable componentAs for SwiXAT 0.5.5 we have added the possibility to easily fill a Table by declaring the source of data with the 'origin' attribute and a TableModel tag.

Example 1:<table origin="$DS/datas" renderer="name"/>

● origin is used as data for DefaultTableModel, must be a 2D array, or a Collection<Collection> 

● renderer is used to render data. The value is used as property name to access to the model 

Example 2:<table origin="$DS/selected"> <tableModel origin="$DS/list" columns="name, firstname, address/city" columnNames="Name, Firstname, City" columnEditables="false, false, true"/></table>

● origin in table permits to select rows in table● origin in tableModel is a List of Objects● column is an XPath list, one XPath for each column● columnNames is used as the table header, if missed the column xpaths are used

Page 54

Page 55: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

● columnEditable permits to indicate which columns are editable 

Example 3:<table> <tableModel origin="$DS/number" column="$DS/person$[row]/name,

$DS/person$[row]/firstname,$DS/person$[row]/address/city" columnName="Name, Firstname, City"/></table>

● in this case origin is just used to know how many rows the table must have● each column gets all its own data from the indicated XPath. When the table asks for data, 

each XPath is evaluated by setting the $row variable to the current row, and $o to the current origin object 

Example 4:<table> <tableModel> <MyTableModel> </tableModel></table>

● in this case MyTableModel is an existing table model (the data access is cabled in code) 

Example 5:<table> <tableModel origin="$Persons"> <column title="Name" property="name" editable="false"

type="String" actionEdit="update($e/value, $e/object/name)"/> <column title="Firstname" property="firstname"/> <column title="City" property="address/City" editable="true"

type="String"/> <column title="Developer" property="jobs/developer"

editable="true" type="boolean"/> <column title="Project" property="project"

renderer="concat(name, ' ', startDate)"/> </tableModel></table>

● title is used as column name● property is used to take the value for a cell, property is an XPath that starts from current 

origin's row● editable is used to make the cell editable● type permits to use easily the default editor registered on the table● renderer permits to define the string representation for the cell; renderer is an XPath that 

Page 55

Page 56: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

starts from the current cell value. We can have renderer defined directly on tableModel, in this case it is used if there is no specific renderer on column.

● when a change is made on the column Name, the corresponding value in object person is directly modified (actionEdit=...)

● For actionEdit in $e variable in the command we have:● $e/object: object for the current row● $e/value: new value entered by the user● $e/row: the row that changed.● $e/column: the column that changed 

Another example of actionEdit:<scrollPane constraints="tableConfig"> <table id="tableConfig"> <tableModel

origin="entrySet(my.package.SomeObject.getProperties())"> <column title="Property" property="key"/> <column title="Value" property="value" editable="true" actionEdit="my.package.SomeObject.setProperty(

$e/object/key, $e/value)"/> </tableModel> </table></scrollPane>

Example 6:You can use the attribute layDown="true" in the Table tag to reverse columns and rows:

<table layDown="true"> <tableModel origin="..."> <column title="first" ...> <column title="second" ...> <column title="third" ...> ...

The result is: 

first ... ... ...

second ... ... ...

third ... ... ...

Page 56

Page 57: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

The <WizardPanel> tagSwiXAT provides a powerful and easy to use mechanism to define wizards, i.e. sequential panels that drive the user to complete some kind of functionalities by asking him the needed informations in a user friendly manner. An auto installer setup program is a classical example of a wizard.

Normally a wizard must respect some simple rules:

● The path to reach the final goal (as, for instance, the correct installation of an application) must follow a predefined sequence of panels

● The user cannot 'jump' forward to any panel beyond the next in the sequence● The user can go back to the previous panels in order to review his own choices● The user can abort the operation in any moment, regardless of the number of covered panels ● A panel can contain informations that depend on the previous choices made in any previous 

panel

We have implemented the 'wizard' mechanism in SwiXAT by respecting all the above rules, but as we'll show you, some of them can be easily changed.

Let's show how a wizard can be built.As the title of this section indicates, we must use the <WizardPanel> tag, put within whatever frame (either IndependentFrame or InternalFrame), as in the following example:

<internalFrame id="wizardFrame" title="Simple Wizard" size="450,350" layout="BorderLayout" Maximizable="false" Closable="true">      ...   <panel  constraints="BorderLayout.NORTH" layout="BorderLayout">      <panel constraints="BorderLayout.NORTH"/>         <WizardPanel id="wizpnl" xml="xml/wizPanel.xml"          onChange="newTab()"/>        </panel>        <panel  constraints="BorderLayout.CENTER">         <button id="prev" text="Prev"              actionCommand="prev" enabled="false"/>         <button id="next" text="Next"              actionCommand="next"/>         <button id="finish" text="Finish"             actionCommand="finished()" enabled="false"/>         <button text="Cancel"              actionCommand="cancel"/>      </panel>   </panel>   ...</internalFrame>

The above frame contains the WizardPanel along with the buttons normally used in any wizard: 'prev', 'next', 'finish' and 'cancel'. Their meaning is clear, I think.

Page 57

Page 58: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

Note that both the 'prev' and 'finish' buttons are initially disabled, as it doesn't make sense to go to a panel before  the first  one,  and also the user cannot finish the wizard (at   least  in  this example) without having traversed all the wizard's panels.

As you can see, there isn't any predefined layout, because you're free to define whatever look&feel for your wizard simply by using the usual SwiXML syntax.

The WizardPanel tag contains two attributes:● xml – indicates the name of the resource containing the XML describing the layout of the wizard 

(i.e. all the panels that compose it)● onChange – points to the command to execute whenever the user changes the panel (in both the 

two directions). As always, it can be either a command defined in the application context file, or the name of a function defined within some script file imported in the view with the <Script> tag

Let's show what the file pointed by the 'xml' attribute contains:

<panel name="wizpnl">     <tabbedpane id="tabPane">         <panel name="Panel 1">  

  ... put here the content of the first panel...       </panel>      <panel name="Panel 2">  

  ... put here the content of the second panel...       </panel>   </tabbedPane></panel> 

It's composed by a panel containing a JtabbedPane component. Each panel within the TabbedPane represents a panel of our wizard, and we must simply put within them all the UI components we need   to   compose   our   wizard.   The   'name'   attribute   of   each   panel   will   be   the   label   of   the corresponding tab within the TabbedPane.

Here is a simple wizard that you can see by launching the baseApp sample application distributed with SwiXAT:

Page 58

Page 59: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

Once again, you're free to define your own layout for each panel in your wizard. Simply put the needed XML tags within the panels contained in the TabbedPane.

What happens when the user click either on the 'next' button or on the tab of the next panel?As said, the command defined in the 'onChange' attribute is executed.

Here is a simple skeleton that you can use as starting point to define the control logic of your wizard:

int newTab() {    // Gets the pointers to the wizard's buttons    prev = currentContext.getData("idMap").get("prev");    next = currentContext.getData("idMap").get("next");    finish = currentContext.getData("idMap").get("finish");    tabPane = currentContext.getData("idMap").get("tabPane");    // Gets the direction of the tab change (+1, ­1)    step = currentContext.getData("_step").intValue();    // Gets the tab selected by the user    tab = tabPane.getSelectedIndex();    if (tab > 0) {        /* Checks if the user can go to the selected panel */         if (..some condition..) {           return ­1; // Error. The selected tab is not activated        }        prev.setEnabled(true);    } else {        prev.setEnabled(false);    }    // Enables/disables the next and finish buttons

Page 59

Page 60: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

    if (tab == tabPane.getTabCount()­1) {        next.setEnabled(false);        finish.setEnabled(true);    } else {        next.setEnabled(true);        finish.setEnabled(false);    }    return tab; // All OK, returns the tab # to activate} 

As you can see, we have the complete control over any aspect of the wizard's behavior:

● We can read which tab has been selected by the user, along with the direction of the tab change (see the variable 'step' in the above listing, that gets its value from the key '_step' in the current context: it will contain +1 if the user is going forward in the wizard, otherwise ­1).

● The script must return an integer containing the index of the tab to activate. It normally is set to the value returned by TabbedPane.getSelectedIndex(), but by returning a different value we can select whatever else tab, forcing in this manner some particular path in the wizard when some specific condition is verified.

● We can also check if the user can activate the chosen panel, having the possibility to block the action,   in   case   of   error,   by   returning   the   value   ­1   (in   this   case   the   selected   tab   remains unchanged).

● We can also access to whatever component of our panels, having the possibility to enable/disable whatever UI control depending on any condition.

Look at the source code of the wizard implemented in the baseApp example in ordere to learn all the possibilities of this useful buil­in feature.

The <CardPanel> tagThis panel is just a JPanel with a CardLayout manager. This widget is useful if used along with the CardPanelModel. To change the displayed panel, just change state in CardPanelModel.

By default, when the current panel changes, refreshView is called. But you can change this beaviour by declaring the refreshCommand attribute with the following contents:

● refreshView(id)● refreshViewPattern(pattern)● any other command (script, static java, xpath:, ...)

you can also deactivate the view refreshing by using refreshCommand="" (empty string)..

You can invoke any action when the current panel changes with<CardPanel onChange="...code...">

Page 60

Page 61: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

This component, if used along with CardPanelModel, can be useful to easily implement wizard panels.

example:

<frame id="myWizard" visible="true" Size="400,100" title="myWizard">

<ContextDataSource id="wizardModel" context="current" source="wizardModel"/>

<cardPanel origin="$wizardModel" refreshCommand="refreshViewPattern('navBut.*')">

<panel constraints="begin">...</panel> <panel constraints="step1">...</panel> <panel constraints="step2">...</panel> <panel constraints="end">...</panel> <panel constraints="AnotherPossibleTerminalState">...</panel> </cardPanel> <button id="navButPrec" text="Prec"

origin="not($wizardModel/begin)" actionCommand="prev"/> <button id="navButNext" text="Next"

origin="not($wizardModel/end)" actionCommand="next"/>

<button id="navButFinish" text="Finish" origin="$wizardModel/end"

actionCommand="... my command ..."/> <button text="Cancel" actionCommand="cancel"/></frame>

You can use your own actionCommand if you don't have overloaded prec, next, and finish methods in your own model.In this case your actionCommand must change the property “state” of the model in order to change the visible page.

If you don't need to skip steps and don't have different choices (more than one final step), you don't need to use any specific CardPanelModel.

example:

<frame id="myWizard" visible="true" Size="400,100" title="MyWiard">

<cardPanel id="wizardPanel"> <panel constraints="begin">...</panel> <panel constraints="step1">...</panel> <panel constraints="step2">...</panel>

Page 61

Page 62: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

<panel constraints="end">...</panel> </cardPanel> <button text="Prec" origin="not($wizardPanel/begin)"

actionCommand="prev"/> <button text="Next" origin="not($wizardPanell/end)"

actionCommand="next"/> <button text="Finish" origin="$wizardPanel/end"

actionCommand="...your method..."/> <button text="Cancel" actionCommand="cancel"/></frame>

If you use CardPanelModel, you can create your own child implementation to use as model, and add some specific method to set the properties in this model in order to collect informations during the wizard usage in conjunction with UpdateOrigin (or update). 

Support for DockingPanelsWe   have   added   the   support   for   docking   panels   by   integrating   the   FlexDock (https://flexdock.dev.java.net/) framework.The docking panels (known also as floating windows) permit to move the frames within a multi­panel GUI simply by dragging the title bar of each frame.They can be moved around and manipulated by the user (in terms of size, position, and stacking). This type of configurable UI where views can be snapped into place is typically referred to as a docking UI.Complex UIs such as Eclipse and Netbeans have a docking UI.

You can define a docking UI with the following syntax:

<DockingPort? shadowBorder="true" floatingEnabled="true"> <GradientDockablePane id="ID1" title="Root docking panel"

dock="root" layout="BorderLayout"> <!-- First panel's UI components here --> </GradientDockablePane> <GradientDockablePane id="ID2" title="Second docking panel"

dock="ID1" region="SOUTH" ratio="20"> <!-- Second panel's UI components here --> </GradientDockablePane> <GradientDockablePane id="explorer" title="Explorer"

dock="ID1" region="WEST" ratio="30" layout="BorderLayout">

<!-- Third panel's UI components here --> </GradientDockablePane></DockingPort>

The container of all the docking panels is represented by a <DockingPort> tag.

Page 62

Page 63: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

Each dockable panel must be declared with a <GradientDockablePane> tag.Each dockable panel must be identified by an id, because we can refer to it when inserting other panels, by means of the attributes dock="parentID" and region="NORTH|SOUTH|WEST|EAST". The ratio attribute, if present, contains the panel's size in percentage.

If region is omitted, the new panel is stacked within the parent panel.A dockable panel with dock="root" must be ALWAYS inserted, and corresponds to the root panel, i.e. the panel that is 'child' of the DockingPort?, and is the parent of all the other docking panels.

Instead of GradientDockablePane (that displays panels with a gradient title bar and a pin to hide the panel), we can use also DockableView, having the same attributes, but displayed without the pin, with a flat­color title bar.

See the example in /samples/docking directory of the SwiXAT package. 

Example:The following XML code:

...<DockingPort shadowBorder="true" floatingEnabled="true"> <GradientDockablePane id="editor" title="Document1.txt"

dock="root" layout="BorderLayout"> <ScrollPane constraints="BorderLayout.CENTER"> <TextArea text="This is the text of the Document 1..." /> </ScrollPane> </GradientDockablePane> <GradientDockablePane id="output" title="Output" dock="editor"

region="SOUTH" ratio="20"/> <GradientDockablePane id="explorer" title="Explorer"

dock="editor" region="WEST" ratio="30" layout="BorderLayout">

<ScrollPane constraints="BorderLayout.CENTER"> <Tree/> </ScrollPane> </GradientDockablePane> <GradientDockablePane id="editor2" title="Document2.txt"

dock="editor" layout="BorderLayout"> <ScrollPane constraints="BorderLayout.CENTER"> <TextArea text="This is the text of the Document 2..." /> </ScrollPane> </GradientDockablePane> <GradientDockablePane id="properties" title="Properties"

dock="explorer" region="SOUTH" ratio="30"/></DockingPort>...

Page 63

Page 64: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

Generates the following frame:

In the above frame you can:● Change the position of any panel by clicking on the corresponding title bar and dragging it 

to the new position.● Change the size of any panel by moving the corresponding separator (like in any SplitPanel).● Hide a panel by clicking on the 'pin' situated on the right of any title bar. 

Support for PopPup MenusA popup menu can be displayed within a whatever UI component, by using the following syntax:

<TextArea id="text"> <popupmenu> <menuitem text="copy" ActionCommand="copyCmd"/> <menuitem text="cut" ActionCommand="cutCmd"/> <menuitem text="paste" ActionCommand="pasteCmd"/> <menuitem text="Select All" ActionCommand="selectAll"/> </popupmenu></TextArea>

Page 64

Page 65: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

The popup menu is automatically displayed when the mouse right button is pressed within the displayed area of the parent UI component (a TextArea in the above example).You can use mnemonics and accelerators, as in any other menu.

Threaded Action Commands

We added a new Action to do some task in a new thread, and also a mechanism to permit to have the UI showing the progress of the action.

Let's show this mechanism with an example: 

Imagine we have declared the action code within a static java method, so we can invoke it with the following XML code: 

<button constraints="buttonSave" text="Save"origin="$EntityModified"actionCommand='thread:InputRegion.save("FisheryRegion", $FisheryRegion)'/>

The static method is the following:

public class InputRegion {static public Object save(AbstractFrame frame, String type, FisheryRegion fisheryRegion) { log.debug("save called"); try{ ... frame.setInfoText("Checking cell"); ... frame.setProgressMin(0); frame.setProgressMax(latNumber * lonNumber); int progresscpt = 0; ... for(...){ for(...){ ... frame.setProgressValue(++progresscpt); } } frame.setInfoText("Removing unnecessary cells"); frame.setProgressMin(0); frame.setProgressMax(cells.size()); progresscpt = 0; for(Cell cell:cells){

Page 65

Page 66: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

... frame.setProgressValue(++progresscpt); }

frame.setInfoText("Commiting the changes"); ... frame.refreshView("inputFisheryRegion");

frame.setInfoText("Finished"); } catch(Exception eee){ log.error("Can't load save region", eee); return new OutputView("Error.xml", "error",

eee.getMessage()); } return null;}

As you can see, some new property have had added to the AbstractFrame class in order to set the values related to the task's progress.

This is the Panel where we put the status bar used in the frame where we have some action done in a separated thread:

<panel border="LoweredBevelBorder" layout="XMLGridLayout(fr/ifremer/isisfish/ui/StatusBar.xgl)">

<ActionMonitor preThreadCommand="xpath:setVisible($stopCommand, 'true')" postThreadCommand="xpath:setVisible($stopCommand, 'false')" progressStartTime="5" messageTime="7" messageDisplayer="$labelStatus" progressDisplayer="$progressStatus"/>

<progressbar id="progressStatus" constraints="progressStatus"/>

<label id="labelStatus" constraints="labelStatus"/>

<button id="stopCommand" actionCommand="stopCommand" visible="false" text="Stop" ToolTipText="Stop the process" Margin="0,0,0,0" border="EmptyBorder" constraints="stopCommand"/>

<MemoryStatus constraints="memoryStatus"/>

</panel>

ActionMonitor is the essential component that permits to describe how to show the task's progress to the user.

Page 66

Page 67: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 2: Special Features

This component links the Frame's parameters seen above (setInfoText, setProgressValue, ...) to the corresponding UI component. It accepts the following parameters:

● progressStartTime is the time in seconds to start a progress undefined task length if the user doesn't use it in his own action (value ­1 = never start automaticaly) 

● messageTime is the time in seconds the text is displayed (­1 = never removed) ● messageDisplayer and progressDisplayer are the XPath expressions that points to the 

JComponent used to display the progress (often JLabel and JProgressBar) 

you can have more than one ActionMonitor for the same frame; in this case, all the labels will display the same text and will show the same progress value.

Note:   if   you   want   to   use   a   graphical   element   in   your   action,   you   must   use SwingUtilities.invokeLater() or SwingUtilities.invokeAndWait(),   like in any well  designed swing application.   All   the   frame.refreshView*   commands   already   use   SwingUtilities.invokeLater()   if necessary. So you can invoke them simply in your code without problems. 

Support for TestingIn order to simplify the testing of the application, in terms of correctness of the XML files, we have added the org.swixat.tools.CheckTool utility class.

This tool can be used in JUnit test to see if all the defined actionCommands exist, to verifiy if the XML syntax is right, etc. 

Here is an example about how to use this feature:

public class myAppTest extends TestCase {...public void testXML() {

SwiXAT.initFactory("some/path/to/context.xml"); CheckTool.checkView("View1.xml");CheckTool.checkView("View2.xml");

}}

Where View1.xml and View2.xml represent the name of the XML files containing the view definitions that we want to check (they must contain a <Frame> as root component).In case of error, an exception is thrown. 

Page 67

Page 68: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

Chapter 3: The Application Context XML file

One of the most important requirements of the SwiXAT framework is the possibility to implement whatever Swing based UI without (almost) changing any rows of java code (of course we assume that the needed classes exist and have been declared in the application's classpath).A great and new paradigm that we have found very useful for our purpose is a technique called 'Inversion of Control'. It is so called because it creates the entire object model by instantiating and connecting all   the requested classes simply by starting from an external definition, so the main application can access it without be worried about the instantiation of the needed classes.In other words, within the main procedure of our application it doesn't exist any SwiXAT classes' initialization code, but simply we call some components of an external framework that does this for us, simply by reading the initial configuration from a XML file.

A   very   great   implementation   of   a   IoC   framework   is   represented   by   the   Spring   Framework (http://www.springframework.org),  that  we have chosen due to  its  robustness and its very small footprint.A Spring XML property file looks like the following:

   ...   <bean id="myClass" class="my.package.myClass">      <!­­ A simple String property ­­>      <property name="prop_name">         <value>property value</value>      </property>

...      <!­­ A bean used as value of a property ­­>      <property name="pointer_name">         <bean class="my.package.myPointedClass">            <property name="some_name">...         </bean>      </property>   </bean>

The tag <bean...> contains the declaration of a java class to instantiate, whereas the <property...> tag permits to declare a value of whatever parameter of the instantiated class. As you can see, the representation is recursive, because we can declare a new <bean> as value of a <property...>.

When the Spring framework is asked for a bean declared in the XML file (by using as identifier the string contained in the 'id' attribute of the <bean...> tag), it instantiates the requested class and sets all the declared properties by invoking the corresponding setters.

By changing the above Spring XML property file, the user can instantiate different applications without changing any line of java code, because, once the desired classes have been declared in the 

Page 68

Page 69: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

XML parameter file, they will be instantiated by the IoC framework.

As the complete description of the features of the Spring framework is out of the scope of this paper, we recommend you to download and read the Spring's documentation at http://www.springframework.org/documentation.html.In the following chapters we'll assume that the reader has a basic (even if not complete) knowledge about the syntax of the Spring's XML parameter file. 

 

How to launch a SwiXAT based applicationEach application based on the SwiXAT framework is launched by the following command:

java org.swixat.SwiXAT <configuration_file.xml>

The   configuration   file   is   written   by   using   the   SpringFramework   syntax,   and   contains   all   the parameters useful to describe how to instantiate our own application.

As  of  SwiXAT 0.4.0,  we  have   added   the  possibility   to   invoke   the   framework  by  passing   the configuration file as a 'resource' instead of as a file name. This means that the file name is searched within the application's classpath, permitting so to insert and distribute the application context file within the same jar containing all the files needed by the application. This feature is very useful to distribute an application by using the WebStart technology.

In order to use this feature, you need to write the following code within your own application:

SwiXAT.launch(“some/path/context.xml”);

It's also possible to pass an initial context to the application:

SwiXAT.launch(“some/path/context.xml”, initialContext);

where initialContext is a Map containing the key­value pairs that compose the initial context.

You can also use the org.swixat.SwiXATLauncher class to invoke your SwiXAT application, simply by passing the resource's name as the command line argument.

Let's show now how an XML Application Context must be written:

How to write the Application ContextAny application context xml file is composed by two main logic sections:

1. the 'Application­specific' context, containing all the beans that must be configured with specific values for each application

2. the 'Application­independent' context, where we'll find all the beans useful to SwiXAT that normally don't need to be changed

The Application­specific beansWithin this section we need to declare the Application object, that will contain all the properties useful to instantiate our application.

Page 69

Page 70: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

The Application bean This bean contains some parameters used by our application:

<bean id="application" class="org.swixat.framework.Application">   <property name="title"><value>Appl. Title</value></property>   <property name="baseDir">

 <value>some/base/path/</value></property>   <property name="initialFrame">      <value>path/to/initialFrame.xml</value></property>   <property name="onStart"><value>someAction</value></property>   <property name="scriptManager">      <ref bean="scriptManager"/></property>   <property name="desktopPane"><value>desktop</value></property>   <property name="fileExtensions">      <map>         <entry key="filterName">            <list>

<ref bean="filterID1"/><ref bean="filterID2"/>

  </list>         </entry>         <entry key="anotherFilterName">  ...         </entry>      </map>   </property></bean>

The id of the above bean must be always equal to the string 'application', because SwiXAT searches   for   that   name   within   the   configuration   file   in   order   to   know   how   to   instantiate   the application.

This bean owns the following properties:

● title   : (optional) contains the title of the application. It can be used wherever we need to display the application's title (for instance within the main frame's title bar) 

● baseDir   :   (optional)   this  property  contains   the   common  directory  prefix  of   all   the   resources declared within our application. If this property contains, for instance, the value 'org/myPath/', then   a   resource   pointed   by   'xml/myView.xml'   will   be   searched   into   the   absolute   path 'org/myPath/xml/myView.xml'. In presence of this property, it's possible however to declare an absolute path simply by inserting a '/' as first character: '/my/absolute/path/resource.xml'. Even if not mandatory, it's  important to declare this property in order to make the application easily relocatable.

● initialFrame   : this is the name of the XML file that describes the initial frame of our application.

● onStart   : (optional) this property indicates what is the action to invoke when the application starts (i.e. before the initial frame is displayed). Useful to execute whatever initialization code. 

● scriptManager   : the ScriptManager object's id that points to the chosen scripting language. See the 'Application independent properties' section below. 

Page 70

Page 71: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

● desktopPane   : (optional) In case of an MDI application, this is the id of the desktopPane object, as declared within the initial frame of the application. If not declared, the application is considered an SDI application.

● fileExtensions   : (optional) Here you can define all the file filters used when a JfileChooser is instantiated, in order to show only the files having a specific extension. This property must point to a Map containing key­value pairs, where the key contains the file filter's name, whereas the value  is  a  List  of  classes   implementing   the  javax.swing.filechooser.FileFilter  class.  We have implemented a generic extension of that class within the org.swixat.util.GenericFileFilter class. 

In order to explain well how to use this feature, we need to make a little example.

If we're writing an application that can open html files, we need to make the following declarations within the application context file:

<bean id="application" class="org.swixat.framework.Application">   ...   <property name="fileExtensions">      <map>         <entry key="htmlFiles">            <list>

<ref bean="htmlFilter"/>            <list>

    </entry> </map>

   </property></bean>

...

<!­­ File extensions ­­><bean id="htmlFilter" class="org.swixat.util.GenericFileFilter">   <property name="description">

 <value>HTML files (*.htm|*.html)</value>   </property>   <property name="extensions">      <list>

    <value>htm</value>    <value>html</value> </list>

   </property></bean>

In the above example, we have declared an entry named 'htmlFiles'. That entry points to a unique FileFilter instance having the name 'htmlFilter' as bean id.

The 'htmlFilter' bean declares an instance of the GenericFileFilter class, that exposes two properties:● description   : contains a string that indicates the kind of files that will be filtered by this class● extensions   : is a List of strings containing all the file extensions filtered by this class

Page 71

Page 72: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

In the above example we'll show only the files having '.htm' or '.html' as extension. Ok, but how can we use the above filter? 

From within script code, by using the following syntax:

...chooser = application.getFileChooser(“htmlFiles”);...

we'll get an instance of the JFileChooser class that, when used, will show only the files having the specified extensions, as illustrated in the following figure:

Of   course  we   can   add  whatever   filter   to   each  single  map's   entry,   hence   if  we  need   to   open, alternatively, also the files with the .jsp extension, we can write, within the application bean:

   <property name="fileExtensions">      <map>         <entry key="webFiles">            <list>

<ref bean="htmlFilter"/><ref bean="jspFilter"/>

            <list>    </entry> </map>

   </property>

adding also the following new filter:

<bean id="jspFilter" class="org.swixat.util.GenericFileFilter">

Page 72

Page 73: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

   <property name="description"> <value>JSP files (*.jsp)</value>

   </property>   <property name="extensions">      <list>

    <value>jsp</value> </list>

   </property></bean>

We'll obtain the following result:

The Command beansIn this section of the application context we need also to declare all the commands used by our application:

<!­­ Commands ­­><bean id="commandName" class="org.swixat.commands.CommandBinder">   <property name="type">      <value>some/path/command.bsh</value>   </property>   <property name="output">      <value>some/path/outputFrame.xml</value>   </property>   <property name="onError">      <value>some/path/errorFrame.xml</value>   </property></bean>

Page 73

Page 74: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

...

It instantiates a CommandBinder object, so you can recognize all the tags corresponding to all the properties of that class (see the chapter 'The Command Binding mechanism'):

● type   : (optional) contains the name of the component that executes the invoked action. If defined, it can point either to a custom java class, or a file containing Java interpreted code. 

● output   :   (optional)  contains  the name of  the XML file  describing  the new View  to show in response to an user's action. If declared, the InternalFrame described in the XML will be shown after the execution of the action.

● onError   : (optional) contains the name of the XML file describing the view to show in case the executed action returns an error.   If declared, the InternalFrame described in the XML will be shown after the execution of the action, in case of error.

As all the commands are declared outside the frames' XML files, they can be used anywhere into any frame of the application. In   fact   the  commands  declared   in   this   section  can  be  used  by  any  UI  component,   as  well   as referenced by any <WindowEvent> and <EventHandler> tag.In this manner the code reuse is facilitated, making the application maintenance simpler.

Last, but not least, if you have declared some <EventHandler> within some XML view definition file, you need to declare the corresponding wrapper you have built, as in the following example:

<!­­ Event wrapper ­­><bean id="wrapperID" class="some.package.YourOwnWrapper"          singleton="false"/>

The id of this bean must be equal to the content of the 'wrapper' property of the corresponding <EventHandler> tag. The referenced class must inherit the AbstractModelEventWrapper class, as descibed in the 'How to write an event wrapper' section.Remember to set  always  the parameter  'singleton' to false, in order to create a different wrapper instance for each declared <EventHandler> tag.

The Application­independent beansIn this section we'll put all the declarations that are independent from any specific application, so the properties declared here can be copied (almost) without modifications to the configuration file of any SwiXAT based application. 

The ScriptManager beanFirst of all, in this section we find the ScriptManager declaration, useful to choose the scripting language:

<bean id="scriptManager" class="org.swixat.script.ScriptManager">

Page 74

Page 75: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

   <property name="scriptEngine">      <!­­value>org.swixat.script.GroovyScripting</value­­>      <value>org.swixat.script.BeanShellScripting</value>   </property>   <property name="evals">      <!­­ Initial script code to evaluate ­­>      <list>         <value>// Add here your own JS statements</value>         <value>import org.swixat.*;</value>      </list>   </property></bean>

The id of this bean must be the same indicated within the 'application.ScriptManager' property (see the previous section).It exposes two properties:● ScriptEngine   : it indicates the class name of the 'wrapper' for the chosen scripting language. All 

the  invoked script  code will  be  interpreted by  using  that  wrapper.  The  indicated class  must implement the org.swixat.script.Scripting interface. At this moment there exist two wrappers:

● org.swixat.script.BeanShellScripting:   the   BeanShell     (http://www.beanshell.org) wrapper

● org.swixat.script.GroovyScripting: the Groovy language2 (http://groovy.codehaus.org/) wrapper

● Evals   : Contains the code to be executed automatically at the beginning of any script invocation, and   it's   normally   used   to   define   all   the   needed   import   statements.   (Note:   as   the   code   is interpreted at   run  time,  statements   like  'import some.package.*;'  will   slow down the execution, because for any referenced class, the interpreter must scan all the import statements in order to search for the package containing that class. Use instead fully qualified class names, like 'import some.package.myClass;').

The TagLibrary extensionsAmong the application independent properties we find also the tag library extensions, used to add new tags to the frame's XML files.Here is the declaration of the actual Taglib extensions:

<bean id="newTags" class="org.swixat.framework.TagLibraryExt">   <property name="newTags">      <map>         <!­­ A new Tag ­­>         <entry key="newTagName">            <value>some.package.TagLibImplementation</value>         </entry>         <!­­ Another Tag... ­­>         <entry key="anotherTag">            <value>...</value>

2 The Groovy language support cannot be considered fully tested and working, hence you could experience some strange and unexpected behavior. Use instead the BeanShell interpreter.

Page 75

Page 76: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

         </entry>      </map>   </property></bean>

As   you   can   see,   we   instantiate   the   class  org.swixat.framework.TagLibraryExt  that represents the container of all the Taglib extensions.It exposes a property named 'newTags', that is a Map within which all the new tags will be added as a  key­value pair:   the  key  is   the name of   the new  tag   (“newTagName”  in   the above example), whereas the value is represented by the name of the class that implements the behavior of that tag (some.package.TagLibImplementation class in the example).

Now, in your application you can instantiate the new tag by writing, in any XML view:

<newTagName attribName=”value”.../>

The attributes accepted by  the  tag must  be declared  in  the  implementation class  as parameters accessed   by   the   corresponding   getter   and   setter   methods,   in   the   form   getAttribName()   and setAttribName() respectively.

Important: due to some constraints imposed by SwiXML, the implementation class MUST inherit (either directly or indirectly) the javax.swing.JComponent class.

The SetterFactory beanThi bean contains all the classes used to implement the binding between the Swing components and the corresponding wrapper classes used to initialize them:

<!­­ Swing components SetterFactories ­­><bean id="SetterFactory" class="org.swixat.databinding.SetterFactory">   <property name="propertySetters">      <map>         <entry key="your.own.SwingComponent">            <value>some.package.YourOwnPropertySetter</value>         </entry>

    ...      </map>  </property></bean>

The container class in this case is represented by org.swixat.databinding.SetterFactory that exposes a Map named 'propertySetters'. Into that map we will insert, as key, the class name of the Swing component, and as value the corresponding property setter's class name.

The property setter class must implement the org.swixat.databinding.PropertySetter interface.You need to implement the following two methods:

boolean  isCompatible(JComponent  component):  method  called  by   the   framework   in  order   to verify the compatibility of the component with this property setter. It must return true only if the 

Page 76

Page 77: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 3: The Application Context XML file

component passed as parameter can be handled by the implemented property setter.

void setProperty(JComponent component, Object data): method called by the framework to set the content of the component passed as parameter. The content is pointed by the 'data' parameter, and   contains   the   value   returned   by   the   xpath   written   in   the   'origin'   attribute   within   the corresponding tag of the XML view. 

As previously said, this section doesn't need to be changed by the normal framework's user, so only who wants to extend the framework needs to change the above properties.  

Page 77

Page 78: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

Chapter 4: Getting Started

How to build SwiXAT from Source SwiXAT uses Maven for build. 

● Download Maven (if Maven is already installed on your machine skip this step): Download Maven from http://maven.apache.org/start/download.html. Try the Latest Stable Release. 

● Tell Maven how to get the SwiXAT Dependencies:SwiXAT has it's own Maven Repository. You have to add this repository to maven's remote repository propertiy. 

Create a file called build.properties in your user home directory and insert this line: maven.repo.remote=http://www.ibiblio.org/maven/,http://swixat.sourceforge.net/maven/

This tells maven to use the official Maven Repository and the SwiXAT Repository. You will find more informations about repositories at http://maven.apache.org/using/repositories.html. 

● Checkout the SwiXAT sources:

Follow the instructions on the sourceforge CVS page at http://sourceforge.net/cvs/?group_id=99002. You will need the 'swixat' module. 

● Build SwiXAT:

Change to the 'swixat' directory and type maven jar:install 

You should get the following output:

$ maven jar:install 

| \/ | _Apache ___ | |\/| / _` \ V / ­_) ' \ ~ intelligent projects ~ |_| |_\,_|\_/\_|_||_| v. 1.0.2 

build:start: 

java:prepare­filesystem:    mkdir Created dir: /home/jbader/projects/swixat/swixat/target/classes 

java:compile:    echo Compiling to /home/jbader/projects/swixat/swixat/target/classes    javac Compiling 75 source files to /home/jbader/projects/swixat/swixat/target/classes 

java:jar­resources: Page 78

Page 79: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

test:prepare­filesystem:    mkdir Created dir: /home/jbader/projects/swixat/swixat/target/test­classes    mkdir Created dir: /home/jbader/projects/swixat/swixat/target/test­reports 

test:test­resources: 

test:compile:    echo No test source files to compile. 

test:test:    echo No tests to run. 

jar:jar:    jar Building jar: /home/jbader/projects/swixat/swixat/target/swixat­0.4.1.jar    copy Copying 11 files to /home/jbader/projects/swixat/swixat/target Copying: from '/home/jbader/projects/swixat/swixat/target/swixat­0.4.1.jar' to: '/home/jbader/.maven/repository/swixat/jars/swixat­0.4.1.jar' Copying: from '/home/jbader/projects/swixat/swixat/project.xml' to: '/home/jbader/.maven/repository/swixat/poms/swixat­0.4.1.pom' BUILD SUCCESSFUL Total time: 7 seconds Finished at: Thu Aug 11 09:10:41 CEST 2005 

If you're running maven for the first time on your system, it will download all the external libraries needed to correctly build SwiXAT, hence you need an active connection to Internet.

You will find Maven Plugins for several IDEs at http://mevenide.codehaus.org/ 

● Run the examples:Change to the 'target' directory and type ./BaseApp.sh (BaseApp.bat for Windows systems) or whatever else sample shell script.

How to create a SwiXAT based Sample Application SwiXAT comes with an useful maven plugin that permits to create the initial directory structure along with the initial properties files needed to write a new application based on SwiXAT.Of course you're free to create by hand the directory structure you like, but by using this plugin you'll   save many  time and will  obtain a complete  environment  within which you can start   the development of your own application based on SwiXAT.

● Download Maven (if Maven is already installed on your machine skip this step): Download Maven from http://maven.apache.org/start/download.html. Try the Latest Stable Release. 

● Tell Maven how to get the SwiXAT Dependencies:SwiXAT has it's own Maven Repository. You have to add this repository to maven's remote repository propertiy. 

Create a file called build.properties in your user home directory and insert this line: maven.repo.remote=http://www.ibiblio.org/maven/,http://swixat.sourceforge.net/maven/

Page 79

Page 80: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

This tells maven to use the official Maven Repository and the SwiXAT Repository. You will find more informations about repositories at http://maven.apache.org/using/repositories.html. 

● Download and Install the SwiXAT's maven plugin:You can either download and unzip the Launch the following command (you need to have an active connection to Internet):

$ maven plugin:download ­DgroupId=swixat ­DartifactId=swixat­genapp­plugin ­Dversion=X.Y.Z 

The version's number (X.Y.Z) to use in the above command can be chosen among the available ones in the swixat maven repository (http://swixat.sourceforge.net/maven/swixat/plugins). 

● Create the application's root directory:

$ mkdir myApp$ cd myApp

 

● Create the sample project with the command 'maven swixat:genapp'. The plugin will ask for some informations about your new application, as in the following example:

$ maven swixat:genapp __  __|  \/  |__ _Apache__ ___| |\/| / _` \ V / ­_) ' \  ~ intelligent projects ~|_|  |_\__,_|\_/\___|_||_|  v. 1.0.2

Please specify an id for your application:  [app]

Please specify a name for your application:  [Example Application]

Please specify the package for your application:  [org.swixat.app]

Please specify the folder for your application (must be the same as package, onl y with / instead of . ):  [org/swixat/app]

 

If the default value proposed within the brackets is right, you can simply press enter, otherwise you can type your preferred choice and then press enter.

At the end of the above process, the complete source code of the skeleton of your application will be created within the directory 'src' having the following structure:

Page 80

Page 81: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

As you can see, the project.xml file makes your application Maven­compatible, so you can build/run/deploy it by using the Maven commands.

● Now you're ready to compile and run the application...:

$ maven jar run 

...and the magic is done...

You have a basic application ready, with all the needed files in the right place.Open your preferred text editor, edit the files in the src/resources directory in order to implement your own functionalities, and recompile and run with the above maven command.

Your own maven­driven SwiXAT application is ready!

Page 81

Page 82: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

The Hello World exampleIn order to permit everyone to learn how to use SwiXAT, we have prepared the following tutorial, that will explain all the steps needed to build a complete Swing application based on SwiAXT.

Example 1: The static Hello World exampleHow to start, if not by using the classic 'Hello World' example?First   of   all,  we  need   to   create   the  directory   structure   in   order   to   contain   all   the   files   of   our application.You   can   either   use   the   maven­plugin   provided   with   SwiXAT,   or   create   manually   the   needed directories. As the use of the plugin has been explained in the previous section, here we'll explain how to create manually the environment to create a new application (even if our advice is to use maven).

Create   the   root   directory   of   our   application   (say   'c:\SwiXAT\samples\hello\'   in   a   Windows environment, or '~/SwiXAT/samples/hello/' on a Unix/Linux platform).

Cd to that directory and create two sub­directories named respectively 'bsh' and 'xml'.

Within the xml directory create a file named helloWorldFrame1.xml containing the following code:

<?xml version="1.0" encoding="UTF­8"?><Frame id="hello" visible="true" size="250,80" title="My first application" layout="BorderLayout" Maximizable="false" Closable="true" Resizable="false">   <panel constraints="BorderLayout.NORTH">       <label text="Hello World!"/>          </panel></Frame>

Now, create the application context XML file, named context1.xml:

<?xml version="1.0" encoding="UTF­8"?><!DOCTYPE beans PUBLIC "­//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring­beans.dtd">

<beans>  <bean id="application" class="org.swixat.framework.Application">     <property name="title"><value>Hello World</value></property>     <property name="baseDir">

   <value>samples/hello/</value></property>     <property name="initialFrame">        <value>xml/helloWorldFrame1.xml</value>     </property>     <property name="scriptManager">

   <ref bean="scriptManager"/></property>  </bean>

Page 82

Page 83: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

...

We have listed here only the application's  specific parameters.  For   the complete  listing see the context1.xml file contained in the samples directory of the SwiXAT examples distribution.

Note   the  baseDir   property  of   the   application  bean,   that   contains   the   value   'samples/hello/'.   It represents the prefix used to compose all the absolute paths of the declared resources (this means that we need to put in the classpath the SwiXAT directory, i.e the root dir within which our baseDir resides).

Now we can launch our first application simply by typing in a console:cd c:\SwiXATjava org.swixat.SwiXAT samples/hello/xml/context1.xml

Of course you must put all the needed jars in your classpath by setting the environment variable CLASSPATH3,   and   the   java.exe   command   must   be   reachable   in   the   system   path.   The   above commands are for a Windows environment, but the Unix/Linux users will be able to change them accordingly their platform.

The following  windows will appear on the screen:

Congratulations! You have build your own first application based on SwiXAT.

Example 2: Inserting a ButtonNow we 'll build a slightly complex example by adding a button in order to show the hello world message when the button is pressed.

First of all, we need to create a new view containing the button, as illustrated in the following code:

<Frame id="hello" visible="true" size="250,80" title="My first application" layout="BorderLayout" Maximizable="false" Closable="true" Resizable="false">   <panel constraints="BorderLayout.NORTH">        <button id="b1" text="Greetings" ActionCommand="hello"/>    </panel></Frame>

3 The CLASSPATH must be set to: “.;swixat.jar;bsh.jar;commons­jxpath.jar;commons­logging.jar;jdom.jar;spring­core.jar;swixml.jar”. Substitute ';' with ':' for Unix/Linux environments.

Page 83

Page 84: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

The above code will be saved to a file named helloWorldFrame2.xml.Note the ActionCommand associated to the button, that contains the value “hello”. This is the name of the command to invoke when the button is pressed, and it's declared within the  the application context XML file, as in the following listing:

<beans>  <bean id="application" class="org.swixat.framework.Application">     <property name="title"><value>Hello World</value></property>     <property name="baseDir">

   <value>samples/hello/</value></property>     <property name="initialFrame">        <value>xml/helloWorldFrame2.xml</value>     </property>     <property name="scriptManager">

   <ref bean="scriptManager"/></property>  </bean>      <!­­ Commands ­­>  <bean id="hello" class="org.swixat.commands.CommandBinder">     <property name="output">

<value>xml/helloWorldFrame1.xml</value></property>

  </bean>...

The above code (stored within context2.xml) is similar to that contained in context1.xml, except for the initialFrame property, that this time points to the helloWorldFrame2.xml file, and the adding of the 'hello' command bean. This bean indicates, in the property 'output', which is the frame to open ('xml/helloWorldFrame1.xml') when the command is invoked. 

Now launch this second example with the commands:

$ cd c:\SwiXAT$ java org.swixat.SwiXAT samples/hello/xml/context2.xml

A window containing the button  'Greetings' will appear (xml/helloWorldFrame2.xml), and when pressed, our 'Hello World' message will be shown in a separate frame (xml/helloWorldFrame1.xml):

 

Page 84

Page 85: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

Example 3: Adding a DataSourceNow we'll try to build a dynamic frame, where the strings 'Hello' and 'World!' will be retrieved by an external source, by using a ScriptingDataSource.

Create within the bsh subdir a file named getWords.bsh and write into it the following JavaScript code:

import java.util.HashMap;

map = new HashMap();map.put("first", "Hello");map.put("second", "World!");return map;

As you can see, we first create a new HashMap, and then store into it two strings, “Hello” and “World!”, indexed respectively by the keys “first” and “second”. The HashMap is the value returned by this script code. Of course this is just an example, because in a real application the data could be retrieved either from a business object, or from a data base, or... whatever else source.

Now, in order to bind the above data to our view, we need to modify the Hello World frame in this manner (the code is stored within helloWorldFrame3.xml):

<Frame id="hello" visible="true" size="250,80" title="Hello Frame"  layout="BorderLayout" Maximizable="false" Closable="true" Resizable="false">       <ScriptingDataSource id="WORDS" script="bsh/getWords.bsh"/>

   <panel constraints="BorderLayout.NORTH">        <label id="label1" origin="$WORDS/first"/>             <label id="label2" origin="$WORDS/second"/>          </panel></Frame>

The first difference is represented by the presence of the ScriptingDataSource tag, that points to the bsh/getWords.bsh file, containing the script code to execute.The two labels now don't contain statically the text to show, but instead they point, through the XPath expression written in the 'origin' property, to the values returned by the ScriptingDataSource.The Jakarta Commons JXPath library handles the keys stored within a Map exactly as if they were properties of the Map itself, hence we can refer to each stored value simply by writing, in the 'origin' property:“$DataSourceName/keyName”.

The context3.xml file used to launch this example contains:

<beans>  <bean id="application" class="org.swixat.framework.Application">

Page 85

Page 86: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

     <property name="title"><value>Hello World</value></property>     <property name="baseDir">

   <value>samples/hello/</value></property>     <property name="initialFrame">        <value>xml/helloWorldFrame2.xml</value>     </property>     <property name="scriptManager">

   <ref bean="scriptManager"/></property>  </bean>      <!­­ Commands ­­>  <bean id="hello" class="org.swixat.commands.CommandBinder">     <property name="output">

<value>xml/helloWorldFrame3.xml</value></property>

  </bean>...

The unique difference respect to context2.xml is represented by the output view declared in the 'hello' command, that points to the newly created xml/helloWorldFrame3.xml.

By launching this example we'll obtain the same result of the example 2, but this time we know that the two labels show a dynamic content obtained from a DataSource tag.To verify the above assertion, try to change the scripting code in order to return different values.

Example 4: Passing parameters between two framesIn   this   example   we'll   show   you   how   to   pass   a   value   between   two   frames   by   using   a ContextDataSource.

Let's start  from the previous example, by merging the two frames, in order to obtain a window containing both the 'Greetings' button, and the two labels containing the dynamic text, as in the following listing contained within xml/helloWorldFrame4.xml:

<Frame id="hello" visible="true" size="250,80" title="My first application" layout="BorderLayout" Maximizable="false" Closable="true" Resizable="false">       <ScriptingDataSource id="WORDS" script="bsh/getWords.bsh"/>      <panel constraints="BorderLayout.NORTH">        <textField id="text1" Columns="6" origin="$WORDS/first"/>       <label id="label2" origin="$WORDS/second"/>             <button id="b1" text="Greetings" ActionCommand="hello"/>    </panel></Frame>

This time the first label has been substituted by a JtextField in order to permit the user to change its 

Page 86

Page 87: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

value; however note that it continues to get its content from the same ScriptingDataSource used in the previous example, as the label2 does, too.

Now we'll create the frame shown by the command associated to the button, in order to show in a separated window the text composed by the concatenation of the 'text1' and 'label2' content.

Create a new file named xml/helloWorldFrame4a.xml containing the following XML code:

<Frame id="hello" visible="true" size="250,80" title="Hello Frame"  layout="BorderLayout" Maximizable="false" Closable="true" Resizable="false">       <ContextDataSource id="WORDS" context="current"

 source="parent"/>      <panel constraints="BorderLayout.NORTH">        <label id="label1" origin="$WORDS/text1/text"/>             <label id="label2" origin="$WORDS/label2/text"/>          </panel></Frame>

This new frame contains a ContextDataSource, used to retrieve the content of the UI components of the previous frame (i.e. the caller). It points to the 'parent' key within the 'current' context, and as you already know (see the 'current context' paragraph), the 'parent' key points to the Map containing all   the IDs of the previous frame's UI controls. In this manner we have a useful mechanism to retrieve the content of whatever control of the caller frame.

The 'origin' properties of the two labels contain the XPath needed to retrieve the content of the text property respectively of the 'text1' and the 'label2' controls.

In order to launch this example, we need to create the corresponding context4.xml file:

<beans>  <bean id="application" class="org.swixat.framework.Application">     <property name="title"><value>Hello World</value></property>     <property name="baseDir">

   <value>samples/hello/</value></property>     <property name="initialFrame">        <value>xml/helloWorldFrame4.xml</value>     </property>     <property name="scriptManager">

   <ref bean="scriptManager"/></property>  </bean>      <!­­ Commands ­­>  <bean id="hello" class="org.swixat.commands.CommandBinder">     <property name="output">

<value>xml/helloWorldFrame4a.xml</value>

Page 87

Page 88: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

</property>  </bean>...

The only changes are represented by the initialFrame and the output view associated to the 'hello' command.

When launched, the application will show the following window:

Now try to change the content of the TextField (by writing, for example 'Hello dear'), and push the 'Greetings'  button.  A second  frame will  appear,  containing   the  concatenation of   the above  two strings, as the following figure shows:

Example 5: Validating the user's inputNow we'll add a validation script in order to check the validity of the value inserted by the user.To do it, first of all we need to write the script that will validate the input. If we want, for example, to   control   the   length  of   the   string   inserted   in   the   'text1'   field,  we  must  write   in   a   file   called bsh/checkInput.bsh the following code:

text = currentContext.getData("idMap").get("text1").getText();if (text.length() > 10)   return 1;else   return 0;

As you can see in  the above code, we first read the content of the JTextField named 'text1'  by retrieving from the current context  the frame's idMap, and then accessing to the UI component identified by the ID 'text1'.After that, we verify the length of the extracted string, returning the value 1 in case it is greater than 10 characters.

Now   we   need   to   define   the   frame   that   will   display   the   error   message.   We'll   call   that   frame 

Page 88

Page 89: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 4: Getting Started

xml/errorFrame.xml:

<Frame id="errorFrame" visible="true" size="180,100" title="Error"  layout="BorderLayout" Maximizable="false" Closable="true" Resizable="false">       <panel name="pnl" constraints="BorderLayout.CENTER">      <label id="msg" text="'Hello' field too long!"/>      <button text="Close" ActionCommand="Cancel"/>   </panel></Frame>

After that, we must change the 'hello' command definition within the context4.xml, in the following manner (after having renamed the context file as context5.xml):

  ...  <!­­ Commands ­­>  <bean id="hello" class="org.swixat.commands.CommandBinder">     <property name="type">

   <value>bsh/checkInput.bsh</value></property>     <property name="output">

   <value>xml/helloWorldFrame4a.xml</value></property>     <property name="onError">

   <value>xml/errorFrame.xml</value></property>  </bean>  ...

We have simply added two new properties:1. the 'type' property points to the 'bsh/checkInput.bsh' file containing the code written to validate 

the input text2. the 'onError' property points to the errorFrame.xml file containing the output view to show in 

case of error (i.e. in case the script code returns '1')

All the remaining context file is the same as for the example 4.When this example is launched, and a text too long is entered into the text field, an error message is shown, as depicted in the following figure:

Page 89

Page 90: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 5: Extending the framework

Chapter 5: Extending the framework

How to add new commands

If we want to add a new command to invoke in response of some user's action, and we want to add permanently that new command to the framework in order to be able to reuse it within whatever application, we can do it by implementing a new Action interface.

For example, if we want to add the command named “myCommand”, we can build the following new class:

public class MyCommandAction implements Action { public boolean accept(Object caller, AbstractFrame frame,

String command, Object arg) { return "myCommand".equalsIgnoreCase(command); }

public Object doCommand(Object caller, AbstractFrame frame, String command, Object arg) {

// Insert your own execution code here... ...

return new Integer(0); }

public boolean check(Object caller, AbstractFrame frame,String command, Object arg) {

/* Returns true if the command can be executed */ return true; }

}

As you can see, we need to fill three methods:

● accept(): called by the framework, returns true if this Action implementation can handle the command passed as parameter.

● check(): called by the framework in order to check if the command can be executed. ● doCommand():  contains  the code  to execute  in  response  to  the command  invocation.  It 

returns either an Integer (containing the value 0 if all ok, otherwise 1) or an instance of OutputView in order to show a new View in response to the command execution. Null is used when no action found for the command. The only case where we can return null, is for special  commands,  for example an Action that does nothing, but logs all   the commands invoked in SwiXat.

Page 90

Page 91: Swix at User Guide

The Swing XML Authoring Tool User Guide Chapter 5: Extending the framework

All the above methods receive the following parameters:

● caller: the object that called the command initially● frame: frame where come from the command● command: the command to execute● arg: a possible special event argument (in case of a Swing event, points to the causing event 

– e.g. a mouse event)

Once we have built the above new class, we can add it to the ActionManager in order to make it visible to the entire framework. We can write, for example within the OnStart script:

ActionManager.register(new MyCommandAction());

At  this  point  we  can   invoke our  new command   in   any  actionCommand,   like   in   the   following example:

<Button text=”Clik Here” actionCommand=”myCommand”/>

As “newCommand” is intercepted by the MyCommandAction class, we don't need to declare the command in the application context XML file.

We have already defined the following Actions (you can also extend one of them, if needed):

● CancelAction: closes the current frame ● GenericActionAction: if the command corresponds to the id of an existing <Action> tag, the 

corresponding command is executed● HandleClassMethodAction: support for static java methods invocation● HandleCommandAction: executes a normal command● HandleScriptFunctionAction: executes a function declared in a script● NextAction: Go to the next panel of the NavigableComponent associated with frame● OutputViewAction: open new view● PrevAction: Go to the next panel of the NavigableComponent associated with frame● RefreshDataAction: refresh data● RefreshViewAction: refresh current frame, or specific component in frame● RefreshViewPatternAction: refresh component that id match pattern● ThreadAction: executes the action in a separate thread● UpdateAction: update some property● XPathAction: evaluate an XPath

Page 91