Обновить метку из вложенной функции, вызываемой из 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);
    }

}
Другие вопросы по тегам