Max Katz heads Developer Relations for Appery.io, a cloud-based mobile app platform. He loves trying out new and cool REST APIs in mobile apps. Max is the author of two books “Practical RichFaces” (Apress 2008, 2011), and is a frequent speaker at developer conferences. You can find out what Max is up to on his blog: mkblog.exadel.com and Twitter: @maxkatz. Max is a DZone MVB and is not an employee of DZone and has posted 78 posts at DZone. You can read more from them at their website. View Full User Profile

JavaFX and Seam with Flamingo: Part Two

06.29.2009
| 11433 views |
  • submit to reddit

This is a second part of the JavaFX and Seam with Flamingo article series. Building on the background information from the first part of the article, this second part provides a step-by-step tutorial for building a JavaFX applications that talks to a Seam backend.

What We Are Going to Build

Here is a screen shot of the application we are going to build. The application allows adding and deleting users.

 

What You Need

You will need the following software to get through the example. You may have some of the tools already:

  1. JavaFX SDK

  2. Eclipse 3.4.2

    1. Exadel JavaFX Studio plug-in for Eclipse

  3. JBoss Application Server 4.3.2 (to deploy Seam application)

  4. Ready-to-deploy Seam application

  5. Exadel Flamingo

Note: If you would just rather read the tutorial without doing the steps, I have provided a finished application at the end that you can download and deploy to JBoss AS. See the “Finished Application” section.

JavaFX SDK

  1. Download the JavaFX SDK for your operating system

  2. Install JavaFX SDK

Eclipse 3.4

If you don't have Eclipse 3.4.2, please download it from here. While plain Eclipse is sufficient, it would be a good idea to download the Eclipse IDE for Java EE Developers package. All you need to do is unzip the downloaded file.

Exadel JavaFX Studio plug-in for Eclipse

The Exadel JavaFX Studio plug-in for Eclipse provides features to help build and deploy JavaFX applications. The plug-in is free. Go to the JavaFX Studio page and click the Download link on the left-side menu.

You are not required to use this plug-in. It's quite possible to build this application just using the JavaFX SDK and command line tools; however, the plug-in will greatly simplify this process.

Plug-in Installation
  1. Download the plugin, unzip the downloaded file

  2. Start the Eclipse IDE

  3. On the Help menu select Software Updates

  4. In the Software Updates and Add-ons dialog click on the Available Software tab

  5. Click on the Add Site button, choose Local, navigate to the folder with the unzipped plug-in, select that directory (where the unzipped plug-in resides), and press OK

  6. You will see the "Exadel JavaFX 1.0 Update Site" option in the list. Check the option and press Install. Follow the Installation procedure to install the plug-in. In the end you will be asked to restart the IDE.

  7. Configure JavaFX SDK

    1. Select Window/Preferences/JavaFX

    2. Click Add...

    3. Browse to the folder where you installed the JavaFX SDK

    4. Click Finish. You have now configured the JavaFX SDK.

  8. One final step is to test the plug-in (we will re-use this project later):

    1. Select File/New/Other.../

    2. Select JavaFX/JavaFX Project

    3. Click Next

    4. For Project name enter: javafx-seam

    5. Click Finish

    6. Expand the project, right-click src, and then select New/Package

    7. For a package name enter: test

    8. Click Finish

    9. Right-click test package and select New/Other.../JavaFX/JavaFX Script

    10. Click Next

    11. For File name enter: test (you don't need to enter .fx)

    12. Click Next

    13. Check Generate Stage. A file will be created with a simple JavaFX stage.

    14. Right-click anywhere in the source and select Run As/JavaFX Application. A window should open with a “Hello World” message. If you see this window, then everything is working.

JBoss AS

If you don't have JBoss AS 4.2.3, please download it. All you need to do is unzip the downloaded file. This application was tested with JBoss AS 4.2.3 GA.

Seam application
  1. Download the Seam application.

  2. The application is finished and ready to be deployed. Copy the file to <jbossas>/server/default/deploy

  3. To start the server, run <jboss>/bin/run

  4. To make sure the application deploys OK, go to [http://localhost:8080/flamingods and click on the link on the page. . This is a JSF page to display users in a table. If you see this page, then the application was deployed successfully

Let's review the Seam application code.

There is a User class that looks like this:

public class User {

@Length(min=3, max=40)
private String name;


public User (){
}

public User(String name) {
super();
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return this.name;
}

}

User is basically our model in this application.There is also a userManager component that looks like this:

@Scope (ScopeType.SESSION)
@Name ("userManager")
public class UserManager {
@In (required=false)
@Out (scope=ScopeType.SESSION, required=true)
private List <User> userList;

@Logger
private Log log;

@Factory ("userList")
public void create () {
userList = new ArrayList <User> ();
User user1 = new User ("John");
User user2 = new User ("Charley");
User user3 = new User ("Sergey");
userList.add(user1);
userList.add(user2);
userList.add(user3);
}

public void remove (int index){
User userToDelete = userList.get(index);
log.info("Deleting user: "+userToDelete.getName());
userList.remove(userToDelete);
log.info("all users: "+userList);
}

public void addUser (String name){
User user = new User ();
user.setName(name);
userList.add(user);
log.info("addUser(String) Added new user: "+user.getName());
log.info("all users: "+userList);
}

}


The userManager component holds the list of users and knows how to add and delete users.

Flamingo

And finally we need to download Flamingo

  1. Download Flamingo

  2. Unzip the file (We will come back to Flamingo a little bit later.)

JavaFX Talking to Seam

Now that we have the server part (Seam) working, we are going to create a JavaFX user interface and connect it to the server-side. These are the general steps:

  1. Create JavaFX user interface

  2. Create client-side service interfaces

    1. Create a client-side factory

  3. Modifying JavaFX script

    1. Setting server URL

    2. Loading existing users

    3. Adding a user

    4. Deleting a user

    5. Validation

Creating a JavaFX user interface

You have already created a project (javafx-seam), so let's re-use it.

  1. Create a new Java class: example.model.User (notice the package name)

  2. Copy and paste the following:

    package example.model;

    public class User {
    private String name;

    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public User(String name) {
    super();
    this.name = name;
    }
    public User (){}
    @Override
    public String toString() {
    return this.name;
    }
    }

    This is a straightforward Java bean and will be used as a model object.

     

  3. Create a new package: example.javafx 

  4. Right click the created package and select New/Other.../JavaFX/JavaFX Script

  5. For a name enter: UsersView
  6. Click Finish
  7. Copy and paste the following JavaFX Script.
    package example.javafx;

    import javafx.scene.Scene;
    import javafx.stage.Stage;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.scene.layout.Tile;
    import javafx.scene.text.Font;
    import javafx.scene.text.Text;
    import javafx.scene.control.TextBox;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;

    import example.model.User;

    var users: User[];

    function add () : Void {
    var newUser:User = new User ();
    newUser.setName (inputText.text);
    insert {newUser} into users;
    }
    function remove (idx : Integer) : Void {
    delete users[idx];
    }
    var inputText : TextBox = TextBox {
    columns: 20
    }
    var buttonAdd : Button = Button {
    text: "Add"
    style: "base: blue"
    action: function () {add()}
    }
    var buttonClear : Button = Button {
    text: "Clear"
    style: "base: blue"
    action: function () {inputText.text = "";}
    }
    Stage {
    title: 'JavaFX and Seam'
    scene: Scene {
    width: 500
    height: 300
    content: [
    VBox {
    translateX: 5
    translateY: 5
    content: [
    VBox {
    spacing: 8
    content: [
    HBox {
    content: [inputText]
    }
    HBox {
    spacing: 8
    content: [buttonAdd, buttonClear]
    }
    ]
    },
    VBox {
    translateX: 10
    translateY: 20
    spacing: 5
    content: bind for (p in users) {
    HBox {
    spacing: 8
    content:[
    Text {
    font: Font { size: 16 }
    content: (p.getName() )
    }
    Button {
    height: 16
    style: "base: blue"
    text: 'Delete'
    action:function () {remove(indexof p)}}
    ]
    }
    }
    }
    ]
    }
    ]
    }
    }

 

What you see here is rather basic JavaFX script. It's not yet connected to anything, but we can already run it.Right-click in the editor and select Run/JavaFX Application. You should see the following:

You can also run this as an applet, by selecting Run/JavaFX Application (Applet). You should see the following:

Note: once we add communication with server, you will get errors when running as applet. We will fix that by signing the jar files. Just giving you a heads up if you run as applet again.

From now on, we will edit this JavaFX script file.

Creating client-side service interfaces

Before we can call Seam component methods from JavaFX, we need to know which methods are actually available in the Seam component. This is done by creating a service interface that looks like this:

package example.service;

public interface UserManager {
public void remove (int index);
public void addUser (String name);
}

f you look at the Seam code, there is a userManager component with the same methods.There is also one more for a Binding service

package example.service;

public interface BindingManager {
public Object getObject(String componentName);
}

BindingManager is a Flamingo-built in server-side component so you don't need to create it.

Creating a client-side service factory

At this point we have to add the Flamingo and Hessian .jar files. (Hessian is the binary protocol that is used in Flamingo to communicate with the server.)

  1. Create a lib directory in the javafx-seam project. You can use Eclipse to create the directory

  2. Copy the <flamingo>/bin/flamingo-javafx-1.8.1.jar to the javafx-seam/lib directory

  3. Download the Hessian jar,  http://hessian.caucho.com/download/hessian-3.1.5.jar and copy it to javafx-seam/lib as well.

  4. Expand the lib folder and select both files. Right-click and select Build Path/Add to Build Path

Next we need to create a client-side reference (or proxy) to Seam components:

package example.service;

import java.util.List;
import com.exadel.flamingo.javafx.ServiceFactory;
import example.model.User;

public class AppServiceFactory {
public static BindingManager getBindingManager() {
return (BindingManager) ServiceFactory.getService(BindingManager.class,
"com.exadel.flamingo.service.binding.bindingManager");
}
public static UserManager getUserManager() {
return (UserManager) ServiceFactory.getService(UserManager.class, "userManager");
}
public static User[] getUserList() {
List<User> list = (List<User>) getBindingManager().getObject("userList");
User[] temp = new User[list.size()];
User[] users = list.toArray(temp);
return users;
}
}

 

The getService in Flamingo takes two arguments: (1) service interface and (2) Seam component name. com.exadel.flamingo.service.bindingManager is a built-in Flamingo component that binds a Seam variable in some context. userManager is a Seam component defined by us (see the server-side code).

The last method, getUserList(), uses BindingManager to bind to the Seam userList variable. That's all we need to start calling Seam components.

Modifying the JavaFX script

Setting the server URL

Before we can make any calls to Seam components, we need to tell JavaFX where the components are by setting the server URL. Open UsersView.fx and add the following:

import com.exadel.flamingo.javafx.ServiceFactory;
...
ServiceFactory.setUrl('http://localhost:8080/flamingo-ds/seam/resource/hessian/');

s etUrl(..) can go anywhere before the add(..) function.

When running as a stand-alone JavaFX application, you also need to add the following (changes are in bold) in order to support cookies (to have session support on the server):

import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
...
ServiceFactory.setUrl('http://localhost:8080/flamingo-ds/seam/resource/hessian/');
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

Note: When you run as an applet, the Java plug-in has this support by default so you don't have to do anything.

 

Once you add this, you will start getting compile errors. This is because JavaFX SDK ships with a trimmed down version of rt.jar file (called rt15.jar). We are going to use rt.jar from your JVM. These are the steps:

  1. Rename <javafxsdk>/lib/desktop/rt15.jar to rt15_original.jar

  2. Copy <jvm>/lib/rt.jar to <javafxsdk>/lib/desktop/

  3. Rename the just copied file to rt15.jar

Loading existing users

Inside the Seam component, there are three existing users. When we launch the JavaFX application, we would like to display the users. In order to do that, we are going to bind to the userList variable.

Inside AppServiceFactory, there is a list of Users that needs to be inserted into an array on the JavaFX side. We need to create a sequence (similar to an array) to hold the users.. That's one of the beauties of JavaFX, it naturally integrates with Java.

Replace this line:

var users: User[] ;

with this:

import com.exadel.flamingo.javafx.FlamingoServiceFactory;
import example.service.*;
...
var users: User[] = AppServiceFactory.getUserList ();

  1. Save all changes

  2. Start JBoss AS server, <jbossas>/bin/run

  3. Right-click in the JavaFX script editor and select Run/JavaFX Application. You should get this:

Adding a user

To add a user on the server, we need to make a call to a Seam component :

function add () : Void {

var newUser:User = new User ();
AppServiceFactory.getUserManager().add(inputText.text);
newUser.setName (inputText.text);
insert {newUser} into users;
}

You can also look in JBoss AS console to see that a user was inserted on the server.

Deleting a user

Deleting a user is equally simple

function remove (idx : Integer) : Void {
AppServiceFactory.getUserManager().remove(idx);
delete users[idx];
}

 

Run the application and try deleting Charley. You should get this:

Validation

One last thing we are going to do is add validation. Right now you can click the Add button without entering anything. Let's fix that.

Add a variable to hold the actual error message returned from the server:

var message : String;

Then, we need to create a new Text node that will display the error message:

 

var messageText  : Text = Text{
font: Font { size: 16 }
content: bind message
}

Adding the new node to scene graph

HBox {
content: [inputText , messageText]
}

Now we need to validate against Hibernate Validator annotations defined in the user component in Seam. At the beginning of the add() function, add this:

message = FlamingoServiceFactory.getHessianEntityValidator().validate("user.name", inputText.text);
if ( message != null ){
return;
}

FlamingoServiceFactory is a built-in factory (just like our AppServiceFactory). It creates an entity validator component that validates against Hibernate Validator annotations. user is a Seam component name, and name is a property. inputText.text is a JavaFX script node where we enter the name.

Save and run the application. If you don't enter anything in the input field or input less than 3 characters, you will get this:

Launching as an applet

Before we can launch as an applet, we have to sign the jar files.

  1. Go to <workspace>/<javafx-users/build

  2. Enter the following command:
    keytool -genkey -dname "cn=JavaFX Example, ou=Flamingo Project, o=Exadel, c=US" -keypass changeit -storepass changeit -keystore ./keystore.dat -keyalg rsa -alias flamingokey

    this step generates a key called keystore.dat in current directory

  3. Next, we are going to sign the three jar files needed on the client-side. Each time you will be prompted for a password which is: change it (see step 2)

    1. jarsigner -keystore ./keystore.dat build/UsersView.jar flamingokey

    2. jarsigner -keystore ./keystore.dat build/lib/hessian-3.1.5.jar flamingokey

    3. jarsigner -keystore ./keystore.dat build/lib/flamingo-javafx-1.8.1.jar flamingokey

  4. Right-click in the JavaFX Script editor and select JavaFX Application (Applet).

    1. You will see a message asking if you trust the publisher. Click Run.


Web browser will be launched and you should see the following:

Finished Application

If you want to just run the finished application, follow the steps below:

  1. Download the finished application

  2. Copy it to <jbossas>/server/defualt/deploy.

  3. Run <jbossas>/bin/run

  4. In browser, enter http://localhost:8080/flamingods-finished/

  5. Select Users (JavaFX) link

  6. You will see a dialog asking if you trust the publisher. Click Run.

Note: This setup is slightly different than the steps in this tutorial. The tutorial developed and deployed the JavaFX application separately. The finished application is packaged as a complete web application.

Final Words

It might seem like there have been a lot of moving parts in this article. In reality, connecting JavaFX to a Seam backend is very transparent and straightforward. The goal of the 2nd part was to show you (in a a hands-on way) how the various parts fit together to create seamless integration, so we didn’t take any shortcuts. However, remember, the first part of the article mentioned a CRUD-like framework. Using this, you can generate most of the parts. Future articles will cover how to use that.

Looking down the road, both Flamingo and Exadel JavaFX Studio plug-in for Eclipse have lots of new features planned. One of them is, of course, Flamingo and plug-in integration. Also, tasks such as signing JARs and deployment will be automated even further.

Finally, if you have any feedback, please post it on the [Flamingo forum, http://exadel.com/web/portal/flamingo/forum] or the [JavaFX Studio forum, http://groups.google.com/group/exadel-javafx-plug-in-for-eclipse].

Resources

Exadel Flamingo - http://exadel.com/web/portal/flamingo

Exadel JavaFX plug-in for Eclipse - http://exadel.com/web/portal/javafxstudio

Authors blog – http://mkblog.exadel.com

Published at DZone with permission of Max Katz, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Sheldon Du Trevou replied on Thu, 2010/06/24 - 7:38am

REALLY Cool idea and would love to get it working but all the links to the files are broken so I cant download any of the files.  Guide doesnt show all steps exactly so im guessing my config files are not right.  Also tried the Flamingo create project and when you try and build it it fails when trying to get seam files from Mavn Repo.

Max Katz replied on Thu, 2010/06/24 - 6:39pm in response to: Sheldon Du Trevou

Please post more details on which links are not working and what exact error message you are getting on Flamingo forum: http://exadel.org/forum/flamingo.

Sheldon Du Trevou replied on Fri, 2010/06/25 - 1:51am in response to: Max Katz

The links I am refering to are the links to the article source code that is why I posted it here under the article.

http://download.exadel.com/max/flamingods.war (doesn't exist)

Max Katz replied on Mon, 2010/06/28 - 10:49am

Don't know what happened, but these are the correct links:

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.