This discussion is archived
2 Replies Latest reply: Dec 4, 2012 4:20 PM by bouye RSS

Task.cancel() throw exception

974885 Newbie
Currently Being Moderated
Hi,

I'm new to JavaFx and recently try out example on javafx.concurrent.Task:

Example is from a book:

The following is the model class
private static class Model {
        public Worker<String> worker;
        public AtomicBoolean shouldThrow = new AtomicBoolean(false);

        private Model() {
            worker = new Task<String>() {
                @Override
                protected String call() throws Exception {                    
                    updateTitle("Example Task");
                    updateMessage("Starting...");
                    final int total = 250;
                    updateProgress(0, total);
                    for (int i = 1; i <= total; i++) {
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            if (isCancelled()) //I modified this part to check for isCancelled()
                                return "Cancelled at " + System.currentTimeMillis();
                        }
                        
                        if (shouldThrow.get()) {
                            throw new RuntimeException("Exception thrown at " + System.currentTimeMillis());
                        }
                        
                        updateTitle("Example Task (" + i + ")");
                        updateMessage("Processed " + i + " of " + total + " items.");
                        updateProgress(i, total);
                    }
                    
                    return "Completed at " + System.currentTimeMillis();
                }
            };
        }
    }
On JavaFx, it has 2 Label that are bind to Worker.value and Worker.exception as shown below:
value.textProperty().bind(
                model.worker.valueProperty());
            exception.textProperty().bind(new StringBinding() {
                {
                    super.bind(model.worker.exceptionProperty());
                }

                @Override
                protected String computeValue() {
                    final Throwable exception = model.worker.getException();
                    if (exception == null) return "";
                    return exception.getMessage();
                }
            });
Next: There are 3 buttons "Start", "Cancel" and "Exception". Following is the method to hook up events to all three buttons:
private void hookupEvents() {
        view.startButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                new Thread((Runnable) model.worker).start();
            }
        });
        view.cancelButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                model.worker.cancel();
            }
        });
        view.exceptionButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                model.shouldThrow.getAndSet(true);
            }
        });
    }
Now, first test is when Task is successfully executed. Value label will be filled with the return value i.e: Completed at ......................

Second is throw exception and the result is as what in the book, the exception label is filled with the exception property. i.e. Exception thrown at ..................

But when I test the Cancel button, it throws and exception instead of return a String value.
The exception label is filled with:
"Task must only be used from the FX Application Thread"

Instead of having Value label filled with: "Cancelled at .................."

Can anybody help me please?


Regards,
Henri

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points