グリッド ( GridPane ) とスタート/ストップ ボタンを備えたシンプルなツールバーを備えたシンプルなアプリがあります。私のボタンアクションは次のようになります:
startButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
grid.change();
}
});
クリックすると、グリッドが変更されます。シーン グラフはスレッド セーフではなく、FX アプリケーション スレッドによってのみレンダリングされるため、グリッドを更新するサービスを配置しました。
private Service task = new Service(){
@Override
protected Task createTask() {
System.out.println("Task created");
return new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i < 3; i++) {
System.out.println("calling");
Platform.runLater(new Runnable(){
@Override
public void run() {
System.out.println("running");
grid.changeGeneration();
try {
Thread.sleep(1500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
return null;
}
};
}
};
アプリを実行しているとき、ボタンを押すと、これが表示されます
タスクが作成されました 呼び出し中 呼び出し中 実行中 実行中
グリッド モデルを再計算しますが、ビューをレンダリングする必要はありません。実際には、すべての Platform.runLater が完了した後で FX アプリ スレッドによってグリッドがレンダリングされますが、各 .runLater の後ではレンダリングされませんrunning
。私の間違いはどこですか?FX App Thread にグリッドをレンダリングさせるにはどうすればよいrunning
ですか?
更新:ここで 解決策を見つけましたが、なぜそれが機能しないのかを完全には理解できません。