JavaFX Forms Framework Part 2

3 08 2009

Full Name Form with Validation

Full Name Form with Validation

Introduction

This is the second installment of a series of blog entries relating to a proof of concept for a JavaFX Forms Framework. Before I specify the requirements and a simple design of the FXForms Framework, I want to follow-up on comments about tough issues relating to enterprise application development and JavaFX. If you recall in Part 1 we discussed about MVC form based technologies. I listed many technologies that may only provide a means to separate content from presentation, but they don’t necessarily deal with real plumbing problems such as Threading, Binding, Validation and Transactions.  I believe these issues are one of the most important areas that must be understood in the JavaFX world, thus positioning itself as a premiere enterprise development platform (not just rich client a hint to Oracle).  As Richard Obaldeston mentions in the comments regarding enterprise level support for JavaFX controls similar to Swinglabs / SwingX. I cannot speak of the future concerning Swing & Swinglabs, but I believe the JavaFX teams are well aware of them, (very much so) due to the fact that the same project owners of the SwingX-WS are leads on the JavaFX teams (I don’t mean to put them on the spot).  Many of these difficult issues are mostly solved in the Browser based Web Application Development world and can also be done in the JavaFX world (Check out Exadel). Of course I can’t answer all the hurdles faced in just one blog entry especially because every enterprise application has varied types of architectures such as (Corba, RMI, EJB, Soap, RESTful, JSON, Jini, JMS, DAO, JDO, JDBC, JNI, etc). It would literally take a book or two. But, I will try to address some of them later in this blog as we discuss JavaFX and Java interoperability. One should always re-evaluate one’s architecture to adhere to best practices or industry standards and conventions. However, some standards seem to stall or are slow to be accepted (JSR-296 or JSR-295) with many reasons of course. It is often the nature of the beast when it comes to new technology solutions and refactoring that subsequently boils down to when and how you want to pick your battles. As readers of this blog for the first time who might be new to JavaFX or Java Swing I strongly encouraged you to explore and learn about the pitfalls of thread safety, asynchronous behaviors, best practices, and UI concepts like (UI blocking, disabling, progress bar, etc.) . So, let’s get started with requirements and the analysis phase of our FXForms Framework.

Requirements

My main goal of these series of blog entries are to share with others my experience with creating an application called iSF86 which hopefully will end up in the Java App Store and make tons of cash so I can quit my day job like Ethan (wishful thinking). iSF86 is an application which contains many form elements to capture a person’s information to apply for a job doing classified work for the United States Government. When dealing with so many forms I thought of building a mini Forms Framework where domain objects can be mapped to forms. The application will save a person’s SF86 information locally as an XML file. This is purely a client-side application which doesn’t involve any server-side communications. Each form would be bound to domain objects in a bi-directional way. A domain object that is bound to an existing form can be swapped out with a different domain object, thus making the old bean ready to be garbage collected and unbound to the form. Important Note: One requirement is that the domain objects will be JavaBeans (see disclaimer below).

Disclaimer: For brevity, the requirements are for JavaBeans (change support) and not POJOs (there is a difference)! Yes, I know I said POJOs in Part 1, because I wanted to tackle the problem using byte code engineering for boiler plate code for property change support on POJOs, but it would be beyond the scope of the blog series’ goal. So, this tutorial is really geared for people migrating Swing/SWT applications to JavaFX applications.

FX Forms Framework Requirements:

  1. It shall bind JavaFX Forms to JavaBeans as domain objects
  2. It shall enable JavaBeans to be swapped in a JavaFX Form
  3. It shall provide validation on property values
  4. It shall provide Action bindings to controls

To keep the framework simple shown below is a list of features that the framework does not provide.  Interesting features will later be discussed in Part 4 Enhancements.

What the FX Forms Framework does NOT provide:

  • Application Framework Features (like JSR-296)
    • Application Lifecycle
    • Resource injection
    • Task Monitoring
    • Saved Preferences
    • Thread Pool
  • Forms Building
  • RCP Features
    • Window Docking
    • Menu bar
    • Etc.

Design

Before going into the design I want to mention other technologies which provide beans to forms binding or RIA MVC capable. The mentioned technologies are primarily Java based. Some of my classes will use similar names because I’ve taken a lot of ideas from these frameworks in the past.  Here are just a few that come to mind:

As a reminder regarding rapid application development that there are two main areas on building applications quickly ‘Forms building’ and ‘Forms binding’. We will only focus on ‘Forms binding’. Ok, already! Let’s get to the designing.

User of the API

At times when it comes to API development I’m a fan of user driven design and the user of the API is who I’m targeting. So, I pretend the FXForms Framework is ready to be used. Below is the developer obtaining a JavaBean and setting it into some Form.

// normally loaded from external source
var personBean1:PersonBean = new PersonBean(); // change support enabled
personBean1.setFirstName("SpongeBob");
.
.
.

// generate a form and bind to bean. Req #1
var personForm:NameForm = NameForm{
jBean:personBean1
};

// subsequent time another domain object is loaded Req #2
var personBean2:PersonBean = … // loaded from external source.
personForm.jBean = personBean2; // old person bean is no longer attached

// set property to an invalid value. Req #3
personBean2.setFirstName(“#$”);
// validator will fire to output error message

// create navigation panel area Req #4
var mainButtonForm:PresentationModel = MainButtonForm {
jBean:personBean2
};
var nextButton:Button = mainButtonForm.getControl(‘nextButton’);
// simulate a mouse press to test action binding

Let’s step through the code to see what is happening and what the FXForms Framework will provide.

Line 1: Creating domain object or loading from external source. Notice the new on the PersonBean (Java Object).

Line 8: Instantiating a Form to use the current JavaBean loaded. All the properties will be bound to form elements bi-directionally. Changes in the GUI will affect properties and changes to the bean properties will change the GUI fields. (Requirement #1)

Line 14: Swapping a domain object with the existing form. Old bean is disconnected from the form and replaced with new bean. Presentation Model Pattern (Requirement #2)

Line 17: Validation of a property when set with invalid data. The user can type into the textbox to fire the validator code. ValueModel updated (Requirement #3)

Line 20-25: A button panel form has buttons mapped to actions. Command Pattern. Yes, this is strange but I will explain later. (Requirement #4)

You will notice the comment on line 25 where you could test a control such as obtaining a button independent of the application being launched (testing individual forms).  This brings up a good point when using MVC Frameworks.  In  the Swing world I highly recommend using FEST Swing a tool to test Swing applications with ease. Also, the team is working on FEST for JavaFX with a joint effort with the JFXtras team.

JavaFX and Java Interoperability

While the user of the API appears simple, it is the behind-the-scenes work that some may consider unorthodox when using a combination of Triggers, Bindings, Reflection, Threading, etc. Until the JavaFX teams expose (with JavaFX blessed code) better interoperability against Java and JavaFX, I will resort to techniques that are known and official. When using triggers on properties this enables us to follow the basic proxy pattern: where a property is changed you will have an opportunity to intercept the change and update value models, which also updates GUI widgets mapped to them. One concern is that object-based memory leaks could occur with inverse bind (Maybe we need a unbind keyword). Another problem is properly populating a form on or off the JavaFX’s main process thread (EDT on the desktop environment) without blocking the GUI thread or causing some race condition.  What follows are the necessary classes to implement the FXForms framework.

Class Design

// Java
DomainModel <abstract Java class>
pcs:PropertyChangeSupport

// Java
PersonBean extends DomainModel <JavaBean>
firstName:String
middleName:String
lastName:String
suffixName:String

// JavaFX
FieldSetter <mixin class> Adapter
valueModel:ValueModel
boundValue:String

// JavaFX
MyTextBox extends TextBox, FieldSetter
updateField(obj:Object):Void

// JavaFX
ValueModel <adapter class>
propertyName:String
guiControls:FieldSetter[]
boundValue:Object
jBean:Object

// JavaFX
PresentationModel extends PropertyChangeListener <mixin class>
propertyValues: Map <String, ValueModel>
propertyValidatorMap: Map <String, List<Validator>
jBean: DomainModel // java class javabean inherit
getModel(propertyName:String):ValueModel
getControl(propertyName:String):Control
propertyChange(changeEvent: PropertyChangeEvent):Void

//JavaFX
Form
guiControls:[] // Scene.lookup(id) is currently a bug in jfx 1.2
presentationModel:PresentationModel

// JavaFX
NameForm extends CustomNode, Form, PresentationModel <JavaFX node>

// JavaFX
Validator
validate():ValidationResult

// JavaFX
ValidationResult
messages:[]
getMessages():Message

// JavaFX
Message

key:String
propertyName:String
errorType:[“warn”,”err”]
text:String

You will notice the NameForm inherits the PresentationModel mixin class which provides the controller functionality mixed in with the view. I’ve done this to make the example short Sometimes I’m not a big fan of inheritance especially in this case and decided to refactor in order to separate the “Presentation Model” from the “View Form” for form reuse.  There are situations such as reusing the same GUI form for “Adding” and “Editing“, but the validation of the form data is different. Developers may also create a concrete presentation model that inherits from the mixin class to be independent of the view so that it decouples the Form and the Presentation Model. An EditPresentationModel and an AddPresentationModel should be created to have two different validations using the same GUI form.  Again for a slim down version I’ve omitted the ability to consume an XML file detailing the form metadata and mappings such as actions, mandatory fields, validators, and custom bindings; the named property is the same name as the ‘id’ attribute on the JavaFX GUI form element (TextBox). I will discuss in Part 4 Enhancements. Relating to validation at some point I would like to provide a way to display warnings and error icons beside fields whenever a Validation Result is updated. The validation results will contain the error messages to be displayed. One last thing to mention is GUI component factories aren’t in the design. You will also notice when creating a TextBox I needed additional behavior, so I simply created a MyTextBox instead of something like var field1 = WidgetFactory.create(valueModel, “TextBox”) to wrap, return and put it into form.

Conclusion

This is surely not a thorough or complete design, but an attempt to demonstrate how to make a simple forms framework from scratch. Hopefully, I’ve captured the requirements and articulated the object relationships within the textual design (No UML sorry). Next, we will look into how to implement the FXForms Framework in Part 3. Please be advised that this design is subject to change as any development shop would.

Personal Note: Sometimes I wonder if Sun had focused on finishing the often highly controversial JSR 295 Beans Binding and Java Properties before JavaFX would it render this blog entry totally useless.

Any comments are welcome. Thanks!

-Carl

References

JavaFX w/JMS 307-311 JavaFX RIA book Server Call Back- James Clarke updates code for JavaFX – Developing RIA book regarding Code Recipe for JMS pages 307-3011 http://tinyurl.com/lzej5x

Best practices: http://www.greggbolinger.com/blog/2008/11/11/1226423940000.html

Fuse http://weblogs.java.net/blog/joconner/archive/2007/11/index.html

Exadel, http://mkblog.exadel.com/ria/javafx-and-spring-crud/

Swing worker / swing/ http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html

Beans Binding: https://beansbinding.dev.java.net/

RESTful : http://jnb.ociweb.com/jnb/jnbAug2009.html

jfxtras JFXWorker http://jfxtras.googlecode.com/svn/site/javadoc/release-0.5/org.jfxtras.async/org.jfxtras.async.JFXWorker.html

Java Properties: http://tech.puredanger.com/java7#property

Fxbuilder: http://www.jroller.com/aalmiray/entry/griffon_gfxbuilder_fxbuilder_side_by

Disable Swing Container:http://weblogs.java.net/blog/alexfromsun/archive/2007/06/_enablingdisabl_1.html

Java Properties without Getters and Setters: http://www.artima.com/forums/flat.jsp?forum=270&thread=247837

Beans Binding (JSR 295) & Properties on JDK7: http://www.javalobby.org/java/forums/t101998.html

JSR 295: http://jcp.org/en/jsr/detail?id=295

RCP Spring rich- http://spring-rich-c.sourceforge.net/1.0.0/index.html

SAF:https://appframework.dev.java.net/intro/index.html

Oracle buys Sun : http://www.oracle.com/us/corporate/press/018363

About these ads

Actions

Information

4 responses

3 08 2009
JavaFX Forms Framework Part 1 « Carl’s FX Blog

[...] 1 – What is a Forms Framework? Also a quick demo of a simple form application. Part 2 – Requirements and design Part 3 – Implementation details Part 4 – Enhancements Part 5 – Concluding [...]

9 08 2009
Java desktop links of the week, August 10 | Jonathan Giles

[...] Dea has put up the second part of his series discussing a JavaFX forms framework. This part covers the requirements and design of such a [...]

10 08 2009
Steve S.

Carl,

This is an excellent article. A technology as new and as cool as JavaFx needs articles like this one to get the word out. It will help people to get started and see how powerful and useful it is, and also in real-world terms. I look forward to the next installment(s) of this! Keep up the good work!

Steve

20 08 2009
JavaFX Forms Framework Part 3 « Carl’s FX Blog

[...] for a JavaFX Forms Framework. If you missed the beginning of the series you may go to Part 1 and Part 2. We will take a look at code snippets relating to how the FXForms Framework was implemented. If you [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

Join 75 other followers

%d bloggers like this: