Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX concurrent task setting state

I am creating the UI for my application which shares a core module with versions for other platforms. In JavaFX, I'm trying to use Tasks to do things in the background, but I can't figure out how to update the Task state.

This is what I'm trying to do. The user variable holds an instance of a class which performs xmlrpc requests:

public Task<Integer> doLogin()
{
    return new Task<Integer>() {
        @Override
        protected Integer call()
        {
            user.login();
            if (!user.getIsAuthorized())
            {
                // set the state to FAILED
            }
            else
            {
                // set the state to SUCCEDED
            }
            user.remember();
        }
    };

}

In my UI Thread I want to be able to do something like this to update my graph UI:

loginTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent t) {
                // perform an UI update here depending on the state t
            }
        });

How am I supposed to set the state? There is nothing that does that in the Task API.

like image 660
Dreen Avatar asked Dec 18 '12 14:12

Dreen


1 Answers

Task states are not intended to be used for user logic. They are introduced to control Task flow. To add user logic into Task you need to use result conception. In your case you may want to use Task<Boolean> and result of your task will be TRUE for correct credentials and FALSE for incorrect:

Task creation:

public Task<Boolean> doLogin() {
    return new Task<Boolean>() {
        @Override
        protected Boolean call() {
            Boolean result = null;
            user.login();
            if (!user.getIsAuthorized()) {
                result = Boolean.FALSE;
            } else {
                result = Boolean.TRUE;
            }
            user.remember();
            return result;
        }
    };
}

Starting that task:

final Task<Boolean> login = doLogin();
login.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
    @Override
    public void handle(WorkerStateEvent t) {
        // This handler will be called if Task succesfully executed login code
        // disregarding result of login operation

        // and here we act according to result of login code
        if (login.getValue()) {
            System.out.println("Successful login");
        } else {
            System.out.println("Invalid login");
        }

    }
});
login.setOnFailed(new EventHandler<WorkerStateEvent>() {
    @Override
    public void handle(WorkerStateEvent t) {
        // This handler will be called if exception occured during your task execution
        // E.g. network or db connection exceptions
        System.out.println("Connection error.");
    }
});
new Thread(login).start();
like image 73
Sergey Grinev Avatar answered Oct 03 '22 13:10

Sergey Grinev