2012-06-27 2 views
1

Я использую Task class из API JavaFx для выполнения сетевых операций. Класс обеспечивает систему прогресса, которая, как представляется, идеально подходит для этой ситуации, позволяя, например, сообщать количество файлов, загружаемых в поток вызывающего. С этой целью я вызываю updateMessage(x + "files uploaded") каждый раз, когда файл был успешно загружен.Как сделать задачу updateMessage() мгновенно?

Проблема в том, что единственное сообщение, которое я когда-либо получал, является последним, когда каждый файл загружен. Я предполагаю, что это явление объясняется каким-то образом с помощью Javadoc:

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

Как я могу заставить его правильно отчитываться каждый или, по крайней мере, некоторые из сообщений? Я попытался добавить вокруг него Thread.sleep (20), но он не работает. Есть идеи?

+1

Я не вижу, в каком виде этот вопрос слишком локализован. Тема - обработка сообщений JavaFX в рамках задач. –

ответ

3

Скорее всего, вы запускаете Task on event thread, поэтому он блокирует обновления. Задача реализует Runnable, который немного вводит в заблуждение, но, посмотрев в Javadoc вы можете обнаружить, что правильный способ выполнения задачи является assinging его новым Тема: new Thread(task).start();

Смотрите следующий пример:

public class TaskTask extends Application { 
    public static void main(String[] args) { launch(args); } 

    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle(VersionInfo.getRuntimeVersion()); 
     Button btn = new Button(); 

     final Task<Integer> task = new Task<Integer>() { 
      @Override 
      protected Integer call() throws Exception { 
       int iterations; 
       for (iterations = 0; iterations < 100; iterations++) { 
        if (isCancelled()) { 
         break; 
        } 
        Thread.sleep(100); // imitate activity 
        updateMessage("Iteration " + iterations); 
       } 
       return iterations; 
      } 
     }; 

     // here we monitor task updates 
     btn.textProperty().bind(task.messageProperty()); 

     btn.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       //here it goes 
       new Thread(task).start(); 
      } 
     }); 

     StackPane root = new StackPane(); 
     root.getChildren().add(btn); 
     primaryStage.setScene(new Scene(root, 300, 250)); 
     primaryStage.show(); 

    } 
} 
+0

Я запускаю задачу из потока, как указано в документе. Тем не менее, метод, из которого я вызываю updateMessage(), синхронизирован (на самом деле это более сложная структура с вложенной задачей, а некоторые wait() и notify() были добавлены). Считаете ли вы, что это может быть причиной? – Timst

+0

Спасибо за пример. Проблема на самом деле исходила от получения обновлений, а не их излучений. – Timst

1

Хорошо, мой неисправность. Я неправильно прослушивал обновления сообщений: я использовал EventHandler в Задаче вместо ChangeListener в messageProperty. В javadoc указывается, как отправлять обновления, а не получать их, поэтому я попробовал это, но ответ Сергея - правильный способ сделать это.

Смежные вопросы