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

时间:2016-05-19 08:58:46

标签: java javafx concurrency

我将提供一个我想做的简单例子。

我有Controller,它有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
}

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

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());

因此,我想在更改值变量后立即更新statusArea。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

这适合你:

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());