Обновить метку из вложенной функции, вызываемой из Task API в JavaFX
Я выполняю некоторые фоновые задачи, используя этот класс
class Download extends Task{
protected Object call() throws Exception {
try {
updateMessage("Establishing Connection");
DownloadHelper downloadHelper = new DownloadHelper();
downloadHelper.performTask();
return null;
} catch (IOException | ParseException ex) {
logger.error(ExceptionUtils.getStackTrace(ex));
throw ex;
}
}
}
Эта задача, в свою очередь, вызывает DownloadHelper для выполнения некоторой задачи.
class DownloadHelper{
public DownloadHelper(){
}
public void performTask(){
----
----
}
}
Есть ли способ обновить сообщение о статусе Task API (updateMessage()) из класса DownloadHelper.?
1 ответ
Целесообразный подход заключается в передаче ссылки на Download
Задача в качестве параметра к DownloadHelper
конструктор. Чтобы свести к минимуму связь, вы можете вместо этого передать ссылку на вашу реализацию updateMessage()
как параметр типа Consumer
, "операция, которая принимает один входной аргумент и не возвращает результата".
DownloadHelper helper = new DownloadHelper(this::updateMessage);
Реализация вашего помощника performTask()
может тогда спросить updater
в accept()
сообщения по мере необходимости.
Consumer<String> updater;
public DownloadHelper(Consumer<String> updater) {
this.updater = updater;
}
public void performTask() {
updater.accept("Helper message");
}
Соответствующий пример можно увидеть здесь.
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* @see https://stackru.com/q/45708923/230513
*/
public class MessageTest extends Application {
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("MessageTest");
StackPane root = new StackPane();
Label label = new Label();
root.getChildren().add(label);
Scene scene = new Scene(root, 320, 120);
primaryStage.setScene(scene);
primaryStage.show();
Download task = new Download();
task.messageProperty().addListener((Observable o) -> {
label.setText(task.getMessage());
});
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
}
private static class Download extends Task<String> {
@Override
protected String call() throws Exception {
updateMessage("Establishing connection");
DownloadHelper helper = new DownloadHelper(this::updateMessage);
helper.performTask();
return "MessageTest";
}
@Override
protected void updateMessage(String message) {
super.updateMessage(message);
}
}
private static class DownloadHelper {
Consumer<String> updater;
public DownloadHelper(Consumer<String> updater) {
this.updater = updater;
}
public void performTask() {
updater.accept("Helper message");
}
}
public static void main(String[] args) {
launch(args);
}
}