0

グリッド ( 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ですか?

更新:ここで 解決策を見つけましたが、なぜそれが機能しないのかを完全には理解できません。

4

1 に答える 1

1

ここでの理由は、3つRunnablesをすばやく連続して公開し、FXキューがその間に実際に再描画する機会を得られない可能性があります。より適切な名前がないため、再描画はすぐには実行されず、イベントキューの最後に追加されます。したがって、基本的に、外側のループは3つ起動しRunnables、イベントキューは次のようになります:| GridChange | GridChange | GridChange | Repaint | Repaint |Repaint|。

さらに、あなたの睡眠は実際にイベントキューをブロックしています-あなたは決してThread#sleep(...)内で呼び出すべきではありませんPlatform#runLater(...)。実際には、再描画やユーザー入力を含むすべてのイベント処理を3x1500ミリでブロックしています。

から移動するThread.sleep()と、Runnable両方の問題が解決します。イベントキューはGridChangeを受信し、UIを更新するのに1.5秒かかり、次のGridChangeを受信します...

于 2012-12-11T18:27:20.527 に答える