1

JavaFX の下にカスタム キャンバス ウィジェットを作成しようとしています。これは、関連のない多くの作業スレッドから情報を収集します。「更新」イベントはさまざまな速度で発生する可能性があり、速すぎる場合もあれば、まったく発生しない場合もあります。つまり、「速すぎる更新」と「アイドル時間」の要件に適切に対処する必要があります。更新の数が多すぎるため、更新が実行されるたびにRunnableを発行することは適切な解決策ではありません。

テストのためだけに、私の強引なアプローチは、AnimationTimerを作成して Canvas オブジェクトのビジュアルを更新することでした。このソリューションは問題なく機能しますが、もちろん、Canvas を更新する必要がない場合もあり、手順全体が非効率になります。

私の問題に対する最も近い答えは、GUIUpdater ヘルパー クラスを使用したこの投稿のようですが、Canvas には直接更新プロパティがないようです。必要な更新機能をバインドされたパラメーターで「プラグイン」する方法を見つけようとしていますが、運が良ければ. Canvasに「更新」イベントがあるかどうかも理解しようとしましたが、見つかりませんでした。私が見つけた他のすべての回答は、私が理解している限り、要件を満たしていませんでした。

前もって感謝します

編集

データが変更された場合にのみキャンバスが描画されるようにするために使用するコードを次に示します。

new AnimationTimer() {
    @Override
    public void handle(long now) {
        if (needsUpdate.getAndSet(false)) {
            myCustomCanvasRepaint();
        }
    }
}.start();

次のようなものでトリガーされます。

AtomicBoolean needsUpdate = new AtomicBoolean(true);
...
public void needsUpdate() {
    needsUpdate.set(true);
}
4

1 に答える 1

0

これは実際にはThrottling javafx gui updatesの複製ですが、実行できます

private final AtomicBoolean updated = new AtomicBoolean();

// ...

Thread someBackgroundThread = new Thread(() -> {
    while (true) {
        waitArbitraryTimeForData() ;
        if (updated.getAndSet(false)) {
            updateCanvas();
        }
    }
});

private void updateCanvas() {
    Platform.runLater(() -> {
        updated.set(true);
        // repaint canvas...
    }
}

更新が依存するデータによっては、Platform.runLater(). AtomicBooleanまたは(おそらくより良い)、累積更新を不変クラスで表し、をそのクラスへのアトミック参照に置き換えます。

于 2016-04-12T15:54:00.870 に答える