Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

JacpFX and DataFX-flows, a perfect match for JavaFX

DZone's Guide to

JacpFX and DataFX-flows, a perfect match for JavaFX

· Integration Zone
Free Resource

Today’s data climate is fast-paced and it’s not slowing down. Here’s why your current integration solution is not enough. Brought to you in partnership with Liaison Technologies.

JacpFX is a RCP framework based on JavaFX, supporting developers to structure an application with loosely coupled, reusable components and DataFX-flow is an API that allows you to define flows between controllers and views in JavaFX.
Both projects developed independently, and while I developed a JacpFX application I realized the lack of flow support. Integrating a simple DataFX-flow into JacpFX was quite easy, a JacpFX component is a controller with either a FXML view or a plain JavaFX view; on the other hand the FlowHandler of a DataFX-flow returns a StackPane which is easy to integrate in your current view. The drawback of this simple solution is the isolation of your DataFX-flow context from the JacpFX context which means, they have no direct access to each other.
At JavaOne I had the chance to spend a hour with Hendrik Ebbers (one of the DataFX committers) and to create a solution for this. The resulting JacpFX/DataFX-flow plugin allows you to inject the JacpFX context of a specific component to DataFX-flow controllers. It allows DataFX-flow controllers to communicate via the JacpFX message-bus with the rest of the JacpFX application. Beside this, the DataFX-flow controller gets access to resource-bundles and other methods/resources of the JacpFX component.


To demonstrate the usage of both frameworks I created a simple example application based on following steps:

Create a JacpFX application from archetype:

JacpFX provides a simple archetype with two example perspectives (FXML + JavaFX view) and two components, reused in both perspectives. To create a basic JacpFX application use the simple archetype:

mvn archetype:generate  -DarchetypeGroupId=org.jacpfx  -DarchetypeArtifactId=JacpFX-simple-quickstart  -DarchetypeVersion=2.0.2

To integrate the DataFX-flow plugin add following dependency to your pom:

  	<dependency>
            <groupId>org.jacpfx</groupId>
            <artifactId>jacpfx.JavaFXDataFXPlugin</artifactId>
            <version>1.0</version>
            <scope>compile</scope>
        </dependency>

Create a simple Flow between two DataFX-flow controllers

Now we create two DataFX-flow controllers, a WizardStartController and a Wizard1Controller. The Wizard1Controller will contain the JacpFX context and include a textfield, text input will be send via messages to a JacpFX component. The controller will look like this:

@FXMLController(value="/fxml/wizard1.fxml", title = "Wizard: Step 1")
public class Wizard1Controller {

    @FXML
    @ActionTrigger("back")
    private Button backButton;

    @FXML
    @ActionTrigger("next")
    private Button nextButton;

	/**
	** The JacpFX context
	**/
    @Resource
    private Context context;


    @FXML
    private TextField name;


    @PostConstruct
    public void init() {
        nextButton.setDisable(true);
        name.setOnKeyReleased(event->{
            context.send(BasicConfig.COMPONENT_BOTTOM, name.getText());
		});
    }

}

Integrate the DataFX-flow into a JacpFX component

To be able to inject a JacpFX context into a DataFX-flow controller I created a DataFX Flow-wrapper which additionally takes the ID of a JacpFX component who’s context should be injected. The usage of the DataFX Flow is exactly the same, so we create a FlowHandler and get the root node of the DataFX-flow when starting the FlowHandler. The root node can now be included to your JacpFX component view.
@View(id = BasicConfig.COMPONENT_TOP,
        name = "SimpleView",
        resourceBundleLocation = "bundles.languageBundle",
        initialTargetLayoutId = BasicConfig.TARGET_CONTAINER_TOP)
public class ComponentLeft implements FXComponent {
    private Node pane;
    @Resource
    private Context context;

    @Override
    public Node handle(final Message<Event, Object> message) {
        // runs in worker thread
        return null;
    }

    @Override
    public Node postHandle(final Node arg0,
                           final Message<Event, Object> message) {
        // runs in FX application thread
        return this.pane;
    }

    @PostConstruct
    public void onPostConstructComponent(final FXComponentLayout arg0,
                                         final ResourceBundle resourceBundle) {
        this.pane = createUI();
    }


    private Node createUI() {
        final VBox main = new VBox();
        Flow flow = new DataFXFlowWrapper(WizardStartController.class,BasicConfig.COMPONENT_TOP).
                withLink(WizardStartController.class, "next", Wizard1Controller.class).
                withGlobalBackAction("back");
        FlowHandler flowHandler = flow.createHandler();
        StackPane pane = null;
        try {
            pane = flowHandler.start(new AnimatedFlowContainer(Duration.millis(320), ContainerAnimations.ZOOM_IN));
			main.getChildren().add(pane);
        } catch (FlowException e) {
            e.printStackTrace();
        }

        return main;
    }


}

JacpFX and DataFX-flow needs Java 8 / JavaFX 8 to run, a packed jar you can download here: http://jacpfx.org/data/SimpleDataFX_JacpFX.jar  , simply execute:

java -jar SimpleDataFX_JacpFX.jar
The source of this example application can be found here:
The basics about DataFX-flow you can find on Hendrik's blog here: http://www.guigarage.com/2014/05/datafx-8-0-tutorials/  
The JacpFX homepage with all the documentation is  http://jacpfx.org  

Is iPaaS solving the right problems? Not knowing the fundamental difference between iPaaS and iPaaS+ could cost you down the road. Brought to you in partnership with Liaison Technologies.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}