JavaFX:来自封装变量的服务类更新消息



我将提供一个我想做什么的简单示例。

我有控制器,它有3个私有方法:

private void before(){
//value = "Start";
//do something
//value = "Credentials are OK";
}
private void process(){
//value = "In process.."
//do smg
//value = "...";
}
private void after(){
//similar body
}

我有一个公共方法,它封装了这3种方法:

public void install(){
before();
process();
after();
}

这种安装方法用于后台线程:

  backgroundThread = new Service<Void>() {
                @Override
                protected Task<Void> createTask() {
                    return new Task<Void>() {
                        @Override
                        protected Void call() throws Exception {
                            String statusArea = "";
                            Controller.install();
                                    updateMessage(/*Here I want to put value variable from my Controller class*/);
                                }
                            }
                            return null;
                        }
                    };
                }
            };

            backgroundThread.setOnSucceeded(event -> {
                System.out.println("Done!");
                updateStatusArea.textProperty().unbind();
            });
            updateStatusArea.textProperty().bind(backgroundThread.messageProperty());

所以,我想在值变量更改后立即更新我的状态区域。我该怎么做?

这为您完成了任务

package application;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;

public class Main extends Application {
    private TextArea textArea;
    public SimpleStringProperty valueProperty = new SimpleStringProperty();
    private Service<Void> service;
    private void before(){
        valueProperty.set("Start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        valueProperty.set("Credentials are OK");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }
        private void process(){
            valueProperty.set("In process..");
            try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
            valueProperty.set("...");
        }
        private void after(){
        //similar body
        }
        public void install(){
            before();
            process();
            after();
            }
    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();
        Scene scene = new Scene(root, 450, 250, Color.WHITE);
        textArea = new TextArea();
        service = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                        Main.this.valueProperty.addListener(new ChangeListener<String>() {
                            @Override
                            public void changed(ObservableValue<? extends String> observable, String oldValue,
                                    String newValue) {
                                updateMessage(newValue);
                            }
                        });
                        Main.this.install();

                        return null;
                    }
                };
            }
        };
        textArea.textProperty().bind(service.messageProperty());
        service.setOnSucceeded(event -> {
            System.out.println("Done!");
            textArea.textProperty().unbind();
        });
        service.start();
        VBox vbox = new VBox();
        vbox.getChildren().addAll(textArea);
        vbox.fillWidthProperty().set(true);
        root.getChildren().add(vbox);

        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

有一件事我不明白,为什么要将线程的消息绑定到GUI元素,因为您的对象中直接有值。

因此,如果我说:,它的行为是一样的

textArea.textProperty().bind(valueProperty);

而不是

textArea.textProperty().bind(service.messageProperty());

最新更新