JavaFx 将数据从一个窗口/类发送到另一个窗口/类。未接收数据

标签 java user-interface javafx

我最近学习了 javaFx,并且正在尝试自学。我创建了这几个类来干扰我正在创建的 GUI,这些类是:

图书馆、AccHolder、引用书目。 一个图书馆可以有许多 AccHolders 和许多书目, 然后我有这两个类:

import java.util.ArrayList;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;


public class Main extends Application{

    Stage window;
    Button b1;
    AccHolder userInputFromAcc; 

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

    @Override
    public void start(Stage primaryStage){
        Library lib = new Library();

        window = primaryStage;
        window.setTitle("Main Window");
        b1 = new Button("Press Me!");
        b1.setOnAction(
                e->{
                    userInputFromAcc = MainWindow.display("New Card Holder");
                    lib.addAccount(userInputFromAcc);
                    lib.printAllAccounts();
                });

        StackPane layout = new StackPane();
        layout.getChildren().add(b1);

        Scene scene = new Scene(layout,1300, 650);
        window.setScene(scene);
        window.show();

    }
}

import java.util.ArrayList;
import javafx.beans.binding.BooleanBinding;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;

public class MainWindow  {
    private static AccHolder x;
    public static AccHolder display(String title){
        Stage window = new Stage();
        window.initModality(Modality.APPLICATION_MODAL);
        window.setTitle(title);
        ArrayList<String> list = new ArrayList<>();

        GridPane grid1 = new GridPane();
        grid1.setPadding(new Insets(10,10,10,10));
        grid1.setVgap(8);
        grid1.setHgap(10);

        //Aplicants's name and text field:
        Label apNameLabel = new Label("Aplicant's Name: ");
        GridPane.setConstraints(apNameLabel, 0,0);

        TextField apNameInput = new TextField();
        GridPane.setConstraints(apNameInput, 2,0);
        apNameInput.setPromptText("Name");

        //Aplicant's age
        Label apAgeLabel = new Label("Aplicant's Age: ");
        GridPane.setConstraints(apAgeLabel, 0,1);

        TextField apAgeInput = new TextField();
        GridPane.setConstraints(apAgeInput, 2,1);
        apAgeInput.setPromptText("Enter Age ");

        //Aplicant's ID card
        Label apIDlabel = new Label("Aplicant's ID Card Number: ");
        GridPane.setConstraints(apIDlabel, 0,2);

        TextField apIDInput = new TextField();
        GridPane.setConstraints(apIDInput, 2,2);
        apIDInput.setPromptText("Enter ID ");

        Button b1 = new Button("Create Account");
        GridPane.setConstraints(b1, 0,6);

        BooleanBinding bb= new BooleanBinding(){
            {
                super.bind(apNameInput.textProperty(), 
                        apAgeInput.textProperty(), 
                        apIDInput.textProperty());
            }
            @Override
            protected boolean computeValue() {
                return (apNameInput.getText().isEmpty() 
                        || apAgeInput.getText().isEmpty()
                        || apIDInput.getText().isEmpty());

            }
        };
        b1.disableProperty().bind(bb);
        b1.setOnAction(e->{
            String a,c;
            int b = 0;
            a = apNameInput.getText();
            try{
                b = Integer.parseInt(apAgeInput.getText());
            } catch(Exception e1){
                apAgeInput.setText("");
            }
            c = apIDInput.getText();
            // Save User Input into an array list.  
               x = new AccHolder(a, b, c);
            window.close();
        } );


        Button b2 = new Button("Close");
        GridPane.setConstraints(b2, 1,6);
        b2.setOnAction(e-> window.close() );

        grid1.getChildren().addAll(apNameLabel, apNameInput, apAgeLabel, apAgeInput, apIDlabel, apIDInput, b1, b2);

        Scene scene = new Scene(grid1, 500, 200);
        window.setScene(scene);
        window.setResizable(false);
        window.show();

        return x;

    }

}

基本上,主窗口中的按钮打开第二个窗口,该窗口具有要填充用户信息的文本字段,我的目的是在收集后返回这些值,并在主窗口中创建一个 Tipe AccHolder 对象并保存它到库。

我遇到了一些复杂情况,其中一个是,一旦按下第一个按钮,程序就会给我一个错误,就好像信息没有从窗口 2 收集并传递到窗口 1 一样。

请注意,我从来不想在窗口 2 中创建对象,我的主要想法是以纯粹的形式收集信息,然后将其传递到窗口 1,然后在窗口 1(主)中创建对象。

我对 javaFx 和 lanmda 表达式非常陌生,因此我可能无法有效地使用它们。以下是当我在窗口 1 上按 b1 时打印出的错误的一部分:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at Library.printAllAccounts(Library.java:45)
    at Main.lambda$0(Main.java:30)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)... 

等等

不知道为什么会发生这种情况,这确实阻碍了我的学习过程。

最佳答案

MainWindow.display() 中,直到实际按下按钮 b1 后才设置变量 x。但是,您在显示窗口后立即返回该值。因此返回值将为null

您实际上尚未发布引发异常的代码(Library 第 45 行),但我假设它尝试对传递到 addAccount 的值调用方法code> 方法(如上所述,为 null)。

而不是调用

window.show();

MainWindow.display()中,调用

window.showAndWait();

这将 show the window and block execution until it closes .

可能还有其他错误,但这很可能是导致您观察到的空指针异常的原因。

关于JavaFx 将数据从一个窗口/类发送到另一个窗口/类。未接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32491706/

相关文章:

java - 如何启动 aicas license provider ?并使用 jamaicaVM 调用文件?

java - 如何在java中使用 "ls *.c"命令?

ADT合理实现的java语法帮助[错误: cannot find symbol]

c++ - Win API C++ 控制编辑必修

JavaFX - 如何定位轴标签以避免与刻度线冲突

java - Java 应用程序的生产级 Cassandra 客户端配置

android - 如何在android jetpack compose ui中实现水平滚动?

java - 是否有不同的方法来编写此代码,使其不使用循环

JavaFX 我无法通过 observableList 填充表格 View

java - 在另一个类中更改 TextArea