Your mistake is that you check for isDone() immediately after calling Platform.runLater(), at which point the FutureTask hasn't been called yet for certain. This program shows that it actually is updating x, but later:
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class FutureTaskTest extends Application {
public static void main(String[] args) {
launch(args);
}
static int x = 5;
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
FutureTask<String> futTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("in thread");
x = 6;
return "foobar";
}
});
Platform.runLater(futTask);
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
System.out.println(" x = " + x);
}
}));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
}
output:
x = 5
x = 5
x = 5
in thread (clicked button here)
x = 6
x = 6
x = 6