2014-09-16 1 views
0

Что я пытаюсь сделать, это печатать тексты на textarea в реальном времени даже после нажатия кнопки.Как запустить прослушиватель без зависания на JavaFX?

Когда я нажимаю кнопку, пользовательский интерфейс замерзает до завершения работы, а затем печатает все тексты вместе в отличие от System.out.println.

Код ниже - это то, что я пробовал, и он не работает так, как я ожидал. Пользовательский интерфейс просто висит и не показывает мне «тест» на textarea.

Нет необходимости использовать слушателя, и это нормально использовать только appendText, , но я просто не могу понять, как разрешить ActionEvent для кнопки работать без замораживания пользовательского интерфейса.

Я по-настоящему признателен за вашу помощь или гораздо лучший код!

final TextField announcement = new TextField(); 
    Platform.runLater(new Runnable() { 
     @Override public void run() { 
      announcement.textProperty().addListener(new javafx.beans.value.ChangeListener<String>() { 
         public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
         textoutput.appendText(announcement.getText()); 
         } 
      }); 
     } 
    }); 

btn.setOnAction(new EventHandler<ActionEvent>() { 
    @Override 
     public void handle(ActionEvent event) { 
      announcement.setText("test"); 
      // bunch of codes below 
     } 
}); 
+0

Вы должны запустить, что бы вы ни делали в действии кнопки, в новой теме. Вы можете использовать 'JavaFX Task' для его достижения. – ItachiUchiha

+0

@ItachiUchiha Если возможно, можете ли вы привести мне пример? Спасибо. – Keibee

ответ

1

Вы пытались использовать Platform.runLater? У меня есть код, где у меня есть длительный Tasks, который периодически обновляет пользовательский интерфейс, используя вызовы Platform.runLater(). Он делает это, запустив Runnable в основном потоке приложения JavaFX, поэтому он выполняется отдельно от вашей длинной задачи.

E.g. (С использованием Java8 лямбды - вы можете просто передать в новом Runnable реализации вместо, я предпочитаю лямбды в этой ситуации для ясности):

btn.setOnAction(new EventHandler<ActionEvent>() { 
@Override 
    public void handle(ActionEvent event) { 
     // Somewhere in your new Task() 
     Platform.runLater(() -> { 
      // Update UI 
      announcement.setText("test"); 
     }); 
     // bunch of codes below 
    } 
}); 
+0

Даже с платформой.runlater пользовательский интерфейс зависает, как только я нажимаю кнопку, и отображает весь текст вместе, а «тест» находится на последней строке. – Keibee

0

Причина этого заключается в том, что ваш обработчик события выполняется на FX потоке, так Пользовательский интерфейс не может быть обновлен до его завершения. Как уже было сказано Итачиучи, вы должны поместить свой код в Task. Когда вам нужно обновить текст в TextArea, используйте метод Задачи updateMessage(). Поместите свойство сообщения ChangeListener on Tasks и установите текст из этого прослушивателя.