JavaFX:如何从普通的java类访问控制器方法?

时间:2014-11-23 19:20:15

标签: java logging controller javafx textarea

我正在编写一个能够将字符串连续记录到TextArea中的工具。 Controller类有一个简单的方法setText();这会将字符串附加到TextArea。我的问题:我真的不能让控制器不断观察我的日志记录类,因为这只会使GUI无法使用。我眼中唯一的解决方案是以某种方式访问​​控制器外部的TextArea或setText()方法。这是可能的吗?我在日志记录类中需要做些什么才能访问控制器方法?

2 个答案:

答案 0 :(得分:0)

您应该阅读 javafx 属性。使用 javafx 属性,您可以“观察”“外部”属性的值并将其绑定到可视控件。您还应该考虑使用列表控件而不是textarea。这是一个简短的代码段。

模特课程:

StringProperty someString = new SimpleStringProperty(""); // etc...

控制器类:

textField.textProperty().bind(model.someStringProperty());

https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm

答案 1 :(得分:0)

我不确定为什么你的控制器会看你的日志记录类?为任何耗时的工作运行一个单独的线程 - 直接从新线程登录。您可以从任何线程访问GUI组件,但是如果您使用任何GUI框架(如JAVAFX),请确保允许GUI时间处理您的响应,并在以后运行类型:您可以看到,这不会影响您在GUI前端的响应时间,让您远离事件派发线程。

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.Date;
import java.util.concurrent.Executors;

public class LogThing extends Application {

private TextField textField;
private TextField textField2;
private Button clickMeBtn;

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) {
    primaryStage.setTitle("Logger!");
    textField = new TextField();
    textField2 = new TextField();
    clickMeBtn = new Button("Click me for time");
    clickMeBtn.setOnAction(e -> {
                textField2.setText(new Date().toString());
            });
    StackPane root = new StackPane();
    VBox vBox = new VBox();
    vBox.getChildren().addAll(textField2, clickMeBtn, textField);
    root.getChildren().add(vBox);
    primaryStage.setScene(new Scene(root, 300, 250));
    primaryStage.show();
    Executors.newSingleThreadExecutor().submit(new BackGroundTask(this));
}

public void logALine(String line) {
    textField.setText(line);
}

class BackGroundTask implements Runnable {

    private final LogThing logThing;
    private int i = 1;

    public backGroundTask(LogThing logThing) {
        this.logThing = logThing;
    }

    @Override
    public void run() {
        while (true) {
            for (i = 1; i < 1000; i++) {
                try {
                    Thread.sleep(1000);
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            logThing.logALine("i : " + i);
                        }
                    });

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

}