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