Question about Flow API

207 views
Skip to first unread message

Tariq Ahsan

unread,
Jan 30, 2014, 1:44:03 PM1/30/14
to dataf...@googlegroups.com
Hi,
 
I am re-writing our JavaFX application using specifically the DataFX Flow API at this point. I am trying to create the Flow object in the main where I want to execute a button action in one of the controller. Here's some part of the codes  -
 
mainApp -
 
..
 

Flow flow = new Flow(BaseScreenController.class).withLink(BaseScreenController.class, "startTest", <Need to execute the button action>);

// Should I have to use something like -

//Flow flow =

//new Flow(BaseScreenController.class
).withAction(BaseScreenController.class, "startTest", <FlowAction object>)?

 

Here's BaseScreenController :

...

@FXMLViewFlowContext

private ViewFlowContext context;

@FXML

@FXMLFlowAction("startTest")

private Button startTest;

...

// Handler for Button[fx:id="startTest"] onAction
 
// Handler for MenuItem[fx:id="startNew"] onAction

 public void

startTest(ActionEvent event) {
...
 

Hendrik Ebbers

unread,
Jan 30, 2014, 3:06:23 PM1/30/14
to dataf...@googlegroups.com
Hi,

there are two different ways how custom actions can be defined. If the action has a public constructor and should be created at runtime you can do the following:

new Flow(BaseScreenController.class).withAction(BaseScreenController.class, "startTest", ActionClass.class)

If your action needs some parameters you can create it when creating the flow:

myActionTask = new Runnable() {
//Do something
}

new Flow(BaseScreenController.class).withTaskAction(BaseScreenController.class, "startTest", myActionTask)

The first sample is the preferred one because injection can be used in the ActionClass class.

Does this short description helps?

Tariq Ahsan

unread,
Jan 31, 2014, 8:54:09 AM1/31/14
to dataf...@googlegroups.com
Hi Hendrik,
 
Thanks for your quick response. Actually I was more thinking of calling a method for the button action within the controller if possible. It makes sense to separate the action in a separate class. But to me it seems to be an overkill. Would like to do the same within the flow if possible. By the way, if I am not missing is there any javadoc for the Flow methods like withAction, withGlobalAction, withTaskAction etc.? I couldn't find any. Also, found in your ViewFactory.java comment -
"... By doing so the fxml files has to be in the package as the controller and
* must fit to a naming convention ...".  I had to put both the fxml and the controller in the same package to make the fxml accesible to the controller? Is there a workaround to keep those two in separate folders?
The concept of Flow is superb. But would be great if the Flow itself could be in an external configuration XML file the way Spring WebFlow has it with little bit more functionality like SWF.

 

Thank you again. Appreciate your invaluable contribution.

Hendrik Ebbers

unread,
Jan 31, 2014, 10:26:33 AM1/31/14
to dataf...@googlegroups.com
Ok, now I understand your problem ;)

I will try to answer all of your questions:

Calling a method in the controller as a action: That will be a new feature. Can you please create a issue at bitbucket and describe what you need. I think that I can create a solution.

JavaDoc: Most of the Flow API has currently no JavaDoc... We will include a complete doc for the DataFX 8 release. Currently some of the methods and parameters may change (Names, additiona parameters). I think that this won't be a big change cause the base classes are all stable as far as I now. So you can use them now ;) I plan to ad a JavDoc to all new classes in DataFX-core and all teh Flow base classes in the next two weeks.

FXML file in a seperate folder: That will be a new feature. Can you please create a issue at bitbucket and describe what you need. I think that I can create a solution.

A static Flow description: I really want this and I think that this will be needed (to provide a Flow WYSIWYG-Editor for example). Currently that can't be done because not all classes are created at runtime (adding a Runnable instance as an Action). I'm thinking about removing this methods and provide a static Flow model. Then the flow can be created in a XML or JSON file. This is on of the points where the Flow API may change in the next two month. Currently I play with some ideas here...

I hope this will help you. Thank for your feedback!

Tariq Ahsan

unread,
Jan 31, 2014, 12:33:25 PM1/31/14
to dataf...@googlegroups.com
Since the ActionClass is Runnable so if I decide to have my current button action logic in the controller moved to this ActionClass I wouldn't need any use of javafx.concurrent.Task<Integer>? I am using this task object within the button action method to spawn of a new Thread.


On Thursday, January 30, 2014 1:44:03 PM UTC-5, Tariq Ahsan wrote:

Hendrik Ebbers

unread,
Jan 31, 2014, 1:23:46 PM1/31/14
to dataf...@googlegroups.com
Can you give a short example how you use the Task class in the button call?

Tariq Ahsan

unread,
Feb 3, 2014, 9:22:50 AM2/3/14
to dataf...@googlegroups.com
Here's some of the relevant codes -
 
Have this class :

public class NewTestTask extends Task<TestResult> implements ValidationStatusListener {

...


// Constructor
    public NewTestTask(File testFile, FileEditsService service) {
        this.testFile = testFile;
        this.service = service;
        this.service.registerValidationStatusListener(this);
        this.max = testFile.length()
                / service.getAppConfig().getFileType().getValue();
    }
...

BaseScreenController.java :


public void startTest(ActionEvent event) {

...

FileChooser chooser=new FileChooser();
        chooser.setTitle("Please Enter File Name to be Tested");
        chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All Files", "*.*"));
        File file = chooser.showOpenDialog(primaryStage);

...

FileChooser chooser=new FileChooser();
        chooser.setTitle("Please Enter File Name to be Tested");
        chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All Files", "*.*"));
        File file = chooser.showOpenDialog(primaryStage);
        if (file != null) {
            testedRecordsScreenController.initializeDataFields();
            recordsErrorsScreenController.initializeDataFields();
            task = new NewTestTask(file, getService());
            task.setOnFailed(new EventHandler<WorkerStateEvent>() {
                @Override
                public void handle(WorkerStateEvent event) {
                    getLogger().error("the new testing failed", event.getSource().getException());
                   
                    // This handler will be called when an exception occurs in the task execution
                    Dialogs.showErrorDialog(new Stage(),
                            "If the problem persists please email the "
                            + "Help Mailbox for more options at "
                            + "He...@myweb.com",
                            "Testing failed due to an unexpected error. Please re-start AccuWage",
                            "Error");
                }
            });
           
            task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
                @Override
                public void handle(WorkerStateEvent event) {
                    System.out.println("Validation finished, error size: "
                            + getService().getTestResult().getTestedRecordCount());
                    setEnableDisable();
                    if (getService().getTestResult().getTotalErrorCount() == 0) {
                        DialogResponse response = Dialogs.showConfirmDialog(
                            new Stage(),
                            "Would you like to connect to Business Services "
                            + "Submit your question?",
                            "Testing Completed.\n There were no errors found.",
                            "Results",
                            DialogOptions.YES_NO);

                        if (DialogResponse.YES.equals(response)) {
                            if (hostServices != null) {
                                try {
                                    hostServices.showDocument("http://www.myweb.com");
                                } catch (Exception e) {
                                    Dialogs.showWarningDialog(new Stage(), "",
                                            "Your default Web Browser could not be opened.",
                                            "Connect to Business Services Online");
                                }
                            } else {
                                Dialogs.showWarningDialog(new Stage(), "",
                                        "Could not find a default Web Browser",
                                        "Browser Not Found");
                            }
                        }
                    } else {
                        if (recordsErrorsScreenController != null) {
                            actionScreen = setContentScreen(actionScreen,
                                    ActionType.VIEW_RECORDS_WITH_ERRORS);
                            recordsErrorsScreenController.updateView();
                        }
                       
                    }
                   
                }
            });

            startScreenController.getProgress().progressProperty().bind(
                    task.progressProperty());
            startScreenController.getProgress().setVisible(true);
            new Thread(task).start();
Reply all
Reply to author
Forward
0 new messages