Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX - waiting for task to finish

Tags:

task

javafx

I have a JavaFX application which instantiates several Task objects.

Currently, my implementation (see below) calls the behavior runFactory() which performs computation under a Task object. Parallel to this, nextFunction() is invoked. Is there a way to have nextFunction() "wait" until the prior Task is complete?

I understand thread.join() waits until the running thread is complete, but with GUIs, there are additional layers of complexity due to the event dispatch thread. As a matter of fact, adding thread.join() to the end of the code-segment below only ceases UI interaction.

If there are any suggestions how to make nextFunction wait until its prior function, runFactory is complete, I'd be very appreciative.

Thanks,

// High-level class to run the Knuth-Morris-Pratt algorithm.
public class AlignmentFactory {
    public void perform() {
        KnuthMorrisPrattFactory factory = new KnuthMorrisPrattFactory();
        factory.runFactory();   // nextFunction invoked w/out runFactory finishing.
        // Code to run once runFactory() is complete.
        nextFunction()   // also invokes a Task.
        ...
    }
}

// Implementation of Knuth-Morris-Pratt given a list of words and a sub-string.
public class KnuthMorrisPratt {
   public void runFactory() throws InterruptedException {
       Thread thread = null;
       Task<Void> task = new Task<Void>() {

           @Override public Void call() throws InterruptedException {
           for (InputSequence seq: getSequences) {
                KnuthMorrisPratt kmp = new KnuthMorrisPratt(seq, substring);
                kmp.align();

            }
            return null; 
        }
    };
    thread = new Thread(task);
    thread.setDaemon(true);
    thread.start();
}
like image 906
mtor.signaling Avatar asked Mar 05 '13 06:03

mtor.signaling


1 Answers

When using Tasks you need to use setOnSucceeded and possibly setOnFailed to create a logic flow in your program, I propose that you also make runFactory() return the task rather than running it:

// Implementation of Knuth-Morris-Pratt given a list of words and a sub-string.
public class KnuthMorrisPratt {
   public Task<Void> runFactory() throws InterruptedException {
       return new Task<Void>() {

       @Override public Void call() throws InterruptedException {
       for (InputSequence seq: getSequences) {
        KnuthMorrisPratt kmp = new KnuthMorrisPratt(seq, substring);
        kmp.align();

        }
        return null; 
    }
    };
}

// High-level class to run the Knuth-Morris-Pratt algorithm.
public class AlignmentFactory {
    public void perform() {
    KnuthMorrisPrattFactory factory = new KnuthMorrisPrattFactory();
    Task<Void> runFactoryTask = factory.runFactory();
    runFactoryTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle(WorkerStateEvent t)
        {
            // Code to run once runFactory() is completed **successfully**
            nextFunction()   // also invokes a Task.
        }
    });

    runFactoryTask.setOnFailed(new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle(WorkerStateEvent t)
        {
            // Code to run once runFactory() **fails**
        }
    });
    new Thread(runFactoryTask).start();
    }
}
like image 113
Dreen Avatar answered Oct 04 '22 04:10

Dreen