1

ファイルの名前が変更されるたびにトリガーする必要があるJavaFXアプリケーションがあります。私は WatchService が初めてで、デモを行って動作します。

ただし、デモは 1 クラスの単純なアプリケーションです。今度は、WatchService を処理する別のクラスを作成して、自分のアプリケーションに実装したいと考えています。

メインクラス:

public class KochFractalDraw extends Application {
     @Override
        public void start(Stage primaryStage) throws IOException, InterruptedException {

                          //..define GUI etc..

            watchdirectory = new WatchDirectory();
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        watchdirectory.Register();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(JSF31KochFractalFX.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
    }

WatchDirectory の場合:

public class WatchDirectory {

    WatchService watchService;
    Path path;
    WatchKey key;

    public WatchDirectory() throws IOException {

        this.watchService = FileSystems.getDefault().newWatchService();
        path = Paths.get("D:\\Test");
        path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
    }

    public void Register() throws InterruptedException {
        for (;;) {

            this.key = watchService.take();
            for (WatchEvent<?> event : key.pollEvents()) {
                WatchEvent.Kind kind = event.kind();
                switch (kind.name()) {
                    case "ENTRY_CREATE":
                        System.out.println("Create triggered!");
                        break;
                    default:
                        System.out.println("Wrong event called.");
                        break;
                }

                boolean valid = key.reset();

                if (!valid) {
                    break;
                }
            }
        }
    }
}

私が抱えている問題は、それが機能することですが、GUI がすぐにフリーズします。したがって、watchdirectory.Register(); を入れた理由 メインのJavaFXアプリケーションスレッドに影響を与えないことを期待して、RunLaterで。

(「D:\Test」でファイルを作成/名前変更するたびに、出力が「作成がトリガーされました!」と応答し続けるため、機能することはわかっています)

4

2 に答える 2

1

ヒントをありがとう

WatchDirectory を Runnable にしました。私のメインクラスでは、それを実行します

new Thread(watchdirectory).start();

以前はこのソリューションに近かったのですが、その後 .run(); を使用しました。、GUIが再びフリーズしました。.start(); の違いに気づきませんでした。および .run();

二度と!

于 2014-09-25T17:02:44.247 に答える
0

Platform.runLater() は、ある時点でFX アプリケーション プロセスを実行して、実行および存在する 他の小さなプログラムを実行し、実行が FX アプリケーションに戻ることを目的としています。

監視サービスのように、そのプロセス内に無限ループがあると、そこから実行が戻らず、当然 FX アプリがフリーズします。

あなたは絶対にできません:

 while(true) {
    key = watchService.take();  
    ...
 }

Platform.runLater() 使用時のポーリング ループ。

代わりに、while(true)毎秒イベントをトリガーする TimeLine などの FX コンポーネントに置き換える必要があります。Runnable とPlatform.runLater()を忘れてください。それが機能するには、FX 内でポーリング ループを実行する必要があると思います。

これまでのところ、これを行う方法がわかりませんでした。

于 2015-11-24T15:55:40.377 に答える