Seam conversations from JavaFX

This post covers starting/stopping Seam conversations from JavaFX. See other posts in this series:

Calling Seam component from JavaFX
Invoking Hibernate Validator from JavaFX
Binding to server-side context variable from JavaFX
Using Expression Language (EL) in JavaFX to communicate with server

Server side

Seam component:

@Name ("wizard")
@Scope (ScopeType.CONVERSATION)
public class Wizard {
   @In Conversation conversation;

   public String info (){
	return "Id: "+conversation.getId() +", active: "+conversation.isLongRunning();
   }
   @Begin
   public void start (){
	// do something
   }
   @Conversational
   public String nextStep (){
	return "Id: "+conversation.getId() +", active: "+conversation.isLongRunning();
   }
   @End
   public void end (){
       // do something
   }
}

Above is a pretty simple Seam component with conversation scope. It has method to start the conversation (@Begin) and end the conversation (@End). It also has nextStep() annotated with @Conversation, that means that the method can only be invoked within a long running conversation.

Client side

Component interface:

public interface Wizard {
   public void end();
   public void start();
   public String nextStep ();
   public String info ();
}

JavaFX script:

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
FXServiceFactory.URL = "http://localhost:8080/server-javafx/seam/resource/hessian/";
var wizardService = WizardServiceFactory.getWizardService();

def red: RadialGradient = RadialGradient{
    centerX: 8, centerY: 8, radius: 12, proportional: false
    stops: [
    Stop {offset: 0.0 color: Color.WHITE},
    Stop {offset: 1.0 color: Color.RED}
    ]
}
def green: RadialGradient = RadialGradient{
    centerX: 8, centerY: 8, radius: 12, proportional: false
    stops: [
    Stop {offset: 0.0 color: Color.WHITE},
    Stop {offset: 1.0 color: Color.GREEN}
    ]
}
var light = Circle {
    centerX: 10 centerY: 10 radius: 10 stroke: Color.BLACK
    fill: bind if (longRunning) green else red
}
var infoButton:Button = Button {
    text : "Info"
    style : "-fx-font-size: x-large"
    action: function () {
        var newInfo = wizardService.info();
        insert newInfo into info;
    }
}
var longRunningOnly:Button = Button {
    text : "Only if active"
    style : "-fx-font-size: x-large"
    action: function () {
        try {
            var newInfo = wizardService.nextStep();
            insert newInfo into info;
        }
        catch (exception: Exception) {
            Alert.inform("Not active conversation");
        }
    }
}
var longRunning = false;
var convButton:Button = Button {
    style : "-fx-font-size: x-large"
    text : bind
    if (longRunning) "Stop" else "Start"
    action: function () {
        if (longRunning==false){
            wizardService.start();
            longRunning = true;
            var newInfo = wizardService.info();
            insert newInfo into info;
        }
        else if (longRunning==true) {
            wizardService.end();
            longRunning = false;
            var newInfo = wizardService.info();
            insert newInfo into info;
        }
    }
}
var info = [wizardService.info()];
var list:VBox = VBox {
    content: {
        VBox {
            content :  bind for (item in info){
                Text {
                    content: item
                    style : "-fx-font-size: x-large"
                }
            }
        }
    }
}
Stage {
    title: "Application"
    width: 450 height: 400
    scene: Scene {
        fill: LinearGradient {
            endX: 0.0
            stops: [Stop { offset: 0.0 color: Color.LIGHTGRAY }
            Stop { offset: 1.0 color: Color.GRAY }]
        }
        content: [
        VBox {
            spacing : 4
            content: [
            HBox {
                spacing: 4
                content: [
                infoButton, convButton, light, longRunningOnly
                ]
            },
            list
            ]
        }
        ]
    }
};

Line 3: we get reference to WizardService and now can call all methods in the interface.
Lines 23-30: info button which returns the current conversation status
Lines 31-43: button that calls a method which should be called only when a long running conversation is active. If clicked outside of a long running conversation, an error dialog will be shown
Lines 45-63: button that starts/stops the conversation

Notice that nothing special needs to be done when using conversations, it is just a simple component method invocation.

No long running conversation:

Long running conversation:

Trying to invoke a method with @Conversation outside of a long running conversation:

That’s it.

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