Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
User interface Javafx使gui显示与基础数据保持同步_User Interface_Javafx_Properties_Binding - Fatal编程技术网

User interface Javafx使gui显示与基础数据保持同步

User interface Javafx使gui显示与基础数据保持同步,user-interface,javafx,properties,binding,User Interface,Javafx,Properties,Binding,我对Javafx和一般的GUI编程不熟悉。我正在开发一个应用程序,如标签需要更新,只要变量有任何变化。 我已经使用了属性和绑定,但是只有在我关闭并重新打开窗口时才能看到更改。 更清楚地说,我并不是说如果用户在文本文件中写入内容,就要更改标签,这样我就没有问题了。但标签中包含整数或字符串,并且实际上没有触发器 因此,我的一般问题是:当某些内容发生变化时,如何更新应用程序中的某些内容。 我重新创建了一个简单的示例,这样也许你们可以理解我想问的问题(对不起,不是母语人士),但不必选择关闭或重新打开窗口

我对Javafx和一般的GUI编程不熟悉。我正在开发一个应用程序,如标签需要更新,只要变量有任何变化。 我已经使用了属性和绑定,但是只有在我关闭并重新打开窗口时才能看到更改。 更清楚地说,我并不是说如果用户在文本文件中写入内容,就要更改标签,这样我就没有问题了。但标签中包含整数或字符串,并且实际上没有触发器

因此,我的一般问题是:当某些内容发生变化时,如何更新应用程序中的某些内容。 我重新创建了一个简单的示例,这样也许你们可以理解我想问的问题(对不起,不是母语人士),但不必选择关闭或重新打开窗口

主要内容:

数据模型:

public class DataModel {
    public static IntegerProperty number = new SimpleIntegerProperty(0);
                
    public static void getNumber(int number) {
        DataModel.number.set(number);
        System.out.println("DataModel " + number);     
    }
}

请查看注释以遵循对代码所做的更改。要运行,请将整个代码复制到
Test.java
并运行:

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Test extends Application{
    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage primaryStage) throws Exception {

        Stage window = primaryStage;
        window.setTitle("Configuration");

        FlowPane numberOfDirPane = new FlowPane();
        Label dirLabel = new Label("Number of Directories: ");

        //construct a DataModel
        DataModel dataModel = new DataModel();

        //in the original code this label was constructed but never added to a panel
        Label numberOfDirLabel = new Label("");
        //bind label to the data model
        numberOfDirLabel.textProperty().bind( dataModel.numberProperty().asString());

        //add numberOfDirLabel to the panel
        numberOfDirPane.getChildren().addAll(dirLabel, numberOfDirLabel);
        numberOfDirPane.setAlignment(Pos.CENTER);

        FlowPane editDir = new FlowPane();
        Label editLabel = new Label("Edit Number of Directories: ");
        TextField numberDirText = new TextField();
        numberDirText.setMaxWidth(50);
        Button editDirNumberButton = new Button("Confirm");

        editDirNumberButton.setOnAction(e -> {
            dataModel.setNumber(Integer.parseInt(numberDirText.getText()));
        });

        editDir.getChildren().addAll(editLabel, numberDirText, editDirNumberButton);
        editDir.setAlignment(Pos.CENTER);
        editDir.setHgap(40);
        //to demonstrate the problem the following Flowpane is not needed
        //and should be removed. see https://stackoverflow.com/help/minimal-reproducible-example
        FlowPane buttons = new FlowPane();
        Button confirmEditButton = new Button("Confirm");

        Button closeButton = new Button("Close");
        closeButton.setOnAction(e -> window.close());

        buttons.getChildren().addAll(confirmEditButton, closeButton);
        buttons.setAlignment(Pos.CENTER);
        buttons.setHgap(20);

        VBox layout = new VBox(20);
        layout.getChildren().addAll(numberOfDirPane, editDir, buttons);
        layout.setAlignment(Pos.CENTER);
        Scene scene = new Scene(layout, 500, 300);
        window.setScene(scene);
        window.show();
    }
}

class DataModel {

    //there is no need to use static fieilds and methods here
    private final IntegerProperty numberProperty = new SimpleIntegerProperty(0);

    public  void setNumber(int number) {
        numberProperty.set(number);
    }

    //add a getter
    public IntegerProperty numberProperty() {
        return numberProperty;
    }
}

一件可怕的事情是,你真的想在每次触发动作时保持绑定吗<代码>numberOfDirLabel.textProperty().bind(DataModel.number.asString())
DataModel.getNumber
看起来应该是一个setter。另外,我相信您应该有方法
getNumberProperty
。这将允许您创建绑定。
DataModel.number.set(number)
JavaFX
中是非常糟糕的做法,可能应该避免。我建议你学习@Jame\D答案。无论你做什么,都不要使用静态范围!不要使用带有副作用的工具getter。。(这可能是@Sedrick已经指出的:)总的来说,您的代码看起来需要完成两个关于java语言基础知识和javafx基础知识的教程……一旦值发生变化,标签就会更新。您没有看到它的更改,因为您尚未将其添加到场景中。
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Test extends Application{
    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage primaryStage) throws Exception {

        Stage window = primaryStage;
        window.setTitle("Configuration");

        FlowPane numberOfDirPane = new FlowPane();
        Label dirLabel = new Label("Number of Directories: ");

        //construct a DataModel
        DataModel dataModel = new DataModel();

        //in the original code this label was constructed but never added to a panel
        Label numberOfDirLabel = new Label("");
        //bind label to the data model
        numberOfDirLabel.textProperty().bind( dataModel.numberProperty().asString());

        //add numberOfDirLabel to the panel
        numberOfDirPane.getChildren().addAll(dirLabel, numberOfDirLabel);
        numberOfDirPane.setAlignment(Pos.CENTER);

        FlowPane editDir = new FlowPane();
        Label editLabel = new Label("Edit Number of Directories: ");
        TextField numberDirText = new TextField();
        numberDirText.setMaxWidth(50);
        Button editDirNumberButton = new Button("Confirm");

        editDirNumberButton.setOnAction(e -> {
            dataModel.setNumber(Integer.parseInt(numberDirText.getText()));
        });

        editDir.getChildren().addAll(editLabel, numberDirText, editDirNumberButton);
        editDir.setAlignment(Pos.CENTER);
        editDir.setHgap(40);
        //to demonstrate the problem the following Flowpane is not needed
        //and should be removed. see https://stackoverflow.com/help/minimal-reproducible-example
        FlowPane buttons = new FlowPane();
        Button confirmEditButton = new Button("Confirm");

        Button closeButton = new Button("Close");
        closeButton.setOnAction(e -> window.close());

        buttons.getChildren().addAll(confirmEditButton, closeButton);
        buttons.setAlignment(Pos.CENTER);
        buttons.setHgap(20);

        VBox layout = new VBox(20);
        layout.getChildren().addAll(numberOfDirPane, editDir, buttons);
        layout.setAlignment(Pos.CENTER);
        Scene scene = new Scene(layout, 500, 300);
        window.setScene(scene);
        window.show();
    }
}

class DataModel {

    //there is no need to use static fieilds and methods here
    private final IntegerProperty numberProperty = new SimpleIntegerProperty(0);

    public  void setNumber(int number) {
        numberProperty.set(number);
    }

    //add a getter
    public IntegerProperty numberProperty() {
        return numberProperty;
    }
}