2014-09-25 3 views
1

У меня есть приложение JavaFX, которое должно запускаться всякий раз, когда файл переименовывается. Я новичок в WatchService, я сделал демо, и он работает.WatchService freezes JavaFX GUI

Хотя, демонстрация представляет собой простые приложения с 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(); в RunLater, надеясь, что это не повлияет на основной поток приложений JavaFX.

(я знаю, что это работает, потому что всякий раз, когда я создаю/переименовать файл в «D: \ Test»! «Создать срабатывает» на выходе будет продолжать отвечать на запросы)

+0

Хорошо, я не совсем уверен в работе runlater, но из собственного опыта, если вы хотите, чтобы тяжелый материал вызывался из фрейма, тогда позвоните в runnable, и когда runnable закончил, он должен вызвать runthable Platform.RunLater, который обработчик пользовательского интерфейса в основном – AntJavaDev

+1

'Platform.runLater (...)' расписывает что-то для запуска в приложении приложения FX, что прямо противоположно тому, что вы хотите. –

ответ

1

Спасибо за подсказку James_D

Я ve сделал WatchDirectory a Runnable. В моем главном классе я запускаю его с

new Thread(watchdirectory).start(); 

Я был рядом с этим раствором и раньше, но тогда я использовал .run(); , которые снова заморозили графический интерфейс. Не понял разницы между .start(); и .run();

Никогда больше!

0

Platform.runLater() предназначена для в какой-то момент дать выполнение процесса приложения FX для запуска какой-либо другой небольшая программа, которая запускается и существует и исполнение возвращает обратно к приложению FX.

Если у вас есть бесконечный цикл внутри этого процесса, например, как используется Watch Service, выполнение никогда не возвращается от него, и, естественно, приложение FX замораживается.

Вы АБСОЛЮТНО НЕ СДЕЛАЙТЕ:

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

цикл опроса при использовании Platform.runLater().

Вместо этого вы должны заменить while(true) некоторым компонентом FX, таким как TimeLine, который запускает событие каждую секунду. И забудьте Runnable и Platform.runLater(), я думаю, для этого вам нужно сделать петлю опроса внутри FX.

До сих пор я не понял, как это сделать.