5

JavaFX アプリケーションから定期的にタスクを実行したいと考えています。このタスクは、リモート ストリームからデータをプルします。

以下に示すようにタイマーを使用できることはわかっていますが:

JavaFX の定期的なバックグラウンド タスク

これは、JavaFX Serviceオブジェクトを使用して実行できるはずです。カスタムエグゼキューターの指定についてJavadocに言及があります(ここではScheduledThreadPoolExecutorが思い浮かびます)が、期間と遅延をどのように指定しますか? 理想的には、これはサービスの通常の開始、リセット、再起動、および状態バインディングを使用します...

public class MyFirstLineService extends Service<String> {
     private StringProperty url = new SimpleStringProperty(this, "url");
     public final void setUrl(String value) { url.set(value); }
     public final String getUrl() { return url.get(); }
     public final StringProperty urlProperty() { return url; }

     public MyFirstLineService() {
         setExecutor(new ScheduledThreadPoolExecutor());
     }

     protected Task createTask() {
         final String _url = getUrl();
         return new Task<String>() {
             protected String call() throws Exception {
                 URL u = new URL(_url);
                 BufferedReader in = new BufferedReader(
                         new InputStreamReader(u.openStream()));
                 String result = in.readLine();
                 in.close();
                 return result;
             }
         };
     }
 }
4

3 に答える 3

3

ScheduledServiceがJavaFX課題トラッカー(RT18702 )で要求されました。

トラッカーには、2.2ブランチに組み込まれていない予備実装のソースが含まれています。必要に応じて、そのソースを調べて、ソリューションの改善に役立つかどうかを確認できます。

于 2012-12-27T19:07:43.803 に答える
2

上記のsarcanからのコメントに基づいて、これを行う方法を見つけました...

通常は UI 要素をアニメーション化するために使用される Timeline オブジェクトを、FX アプリケーション スレッドで動作するタイマーとして作成できます。これを使用すると、Service オブジェクトを再起動できます。これにより、バックグラウンド スレッドで長時間実行される操作が実行されますが、FX アプリケーション スレッド バインディングを介してプロパティ アクセスと更新が保持されます。

元:

    final MyFirstLineService svc = new MyFirstLineService();
    final Duration oneFrameAmt = Duration.seconds(5);
    final KeyFrame oneFrame = new KeyFrame(oneFrameAmt,
            new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent evt) {
                    svc.restart();
                }
            });
    Timeline timer = TimelineBuilder.create()
                            .cycleCount(Animation.INDEFINITE)
                            .keyFrames(oneFrame)
                            .build();
    timer.playFromStart();
于 2012-12-26T16:06:18.910 に答える
1

同じ問題に遭遇します。例はScheduledThreadPoolExecutor次のとおりです。

ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);

Service s = new Service(){
    @Override
    protected Task<String> createTask() {
        return new Task<String>() {
            @Override
            protected String call() throws Exception {
                // code...  
            }
        };
    }
}

// created tasks shall be run in thread pool
s.setExecutor(executor);

// start the service the first time
s.start();

// restart the service every 5 seconds
s.scheduleWithFixedDelay(new Runnable() {
        @Override
        public void run() {
            // need runLater here since trigger needs to be in the javaFX thread
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    checker.restart();
                }
            });
        }
    }, 0, 5, TimeUnit.SECONDS);
}

で解決できTimerますが、JavaFXデータバインディング機能を失いました(すでに述べたように)。Java8に期待!

于 2013-12-11T08:29:59.843 に答える