javafx将场景1中的文本添加到第二个场景中的listview

slmsl1lt  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(385)

我正在尝试制作一个javafx程序,它将从场景一获取用户输入,并在场景二的listview中显示它,当按下按钮时。此外,用户可以返回到第一个场景并添加另一个输入,而在第二个场景中,用户可以删除listview中的一个输入。我有下面的代码,但出于某种原因,它没有在前一个输入下面添加每个新输入,而是覆盖第一个输入。你能帮我弄清楚吗?谢谢!
在第一幕我有以下代码

public class Controller {

    @FXML
    private TextField userEmail;

    @FXML
    public void handleRegisterButton(ActionEvent event) throws IOException{
        Data data = Data.getInstance();
        data.setEmailAddress(userEmail.getText());

        Parent viewEmailsParent = FXMLLoader.load(getClass().getResource("../view/viewUserEmails.fxml"));
        Scene viewEmailsScene = new Scene(viewEmailsParent);

        Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();

        window.setScene(viewEmailsScene);
        window.show();

    }

}

在第二幕,我要处理大部分的事情,我有这样的代码:

public class secondController implements Initializable {
    ObservableList<String> listOfEmails;

    @FXML
    ListView<String> emailList = new ListView<>();

    @FXML
    public void handleBackButton(ActionEvent event) throws IOException {
        Parent viewEmailsParent = FXMLLoader.load(getClass().getResource("../view/register.fxml"));
        Scene viewEmailsScene = new Scene(viewEmailsParent);

        Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();

        window.setScene(viewEmailsScene);
        window.show();
    }
    @FXML
    public void handleDeleteButton(ActionEvent event) throws IOException{
        String selected = emailList.getSelectionModel().getSelectedItem();
        listOfEmails.remove(selected);
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        listOfEmails = FXCollections.observableArrayList(Data.getInstance().getEmailAddress());
        emailList.setItems(listOfEmails);
    }
}

如果有帮助的话,这就是数据类

public class Data {
    public static Data emailStorage;
    private String emailAddress;

    private Data(){
    }

    public static Data getInstance(){
        if(emailStorage == null){
            emailStorage = new Data();
        }
        return emailStorage;
    }

    public String getEmailAddress(){
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress){
        this.emailAddress = emailAddress;
    }
}
nuypyhwy

nuypyhwy1#

因为你重新加载了fxml文件 viewUserEmails.fxml 每一次,一个新的 ListView 每次都会创建可观察列表,只显示数据模型类中的单个项。
因此,数据模型类应该包含完整的列表,而不仅仅是最近添加的单个项:

public class Data {
    public static Data emailStorage;
    private ObservableList<String> emailAddresses;

    private Data(){
    }

    public static Data getInstance(){
        if(emailStorage == null){
            emailStorage = new Data();
        }
        return emailStorage;
    }

    public ObservableList<String> getEmailAddresses(){
        return emailAddress;
    }

}

现在你可以做:

public class SecondController implements Initializable {

    // ...

    @FXML
    ListView<String> emailList ;

    // ...

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        listOfEmails = FXCollections.observableArrayList(Data.getInstance().getEmailAddresses());
        emailList.setItems(listOfEmails);
    }

}

public class Controller {

    @FXML
    private TextField userEmail;

    @FXML
    public void handleRegisterButton(ActionEvent event) throws IOException{
        Data data = Data.getInstance();
        data.getEmailAddresses().add(userEmail.getText());

        // ...

    }

}

您还可以考虑修改代码,以便 viewUserEmails.fxml 只加载一次,然后重新显示。上面的代码仍将与该修改一起工作。
请注意,代码中还有大量与实际问题无关的错误:
永远不要初始化带注解的字段 @FXML . 注解i已替换

@FXML private ListView<String> emailList = new ListView<>();

具有

@FXML private ListView<String> emailList ;

如果这给了你空指针异常,那么其他的东西就错了
您的资源路径错误。如果您将其打包为jar文件,它们将不起作用。请参阅如何确定我的javafx应用程序所需的fxml文件、css文件、图像和其他资源的正确路径?
对数据模型使用单例是个坏主意(一般来说,使用singleton反模式是个坏主意。)相反,最好创建一个数据模型示例并将其传递给需要它的控制器。请参见传递参数javafx fxml
坚持java命名约定。它将使您的代码更易于其他程序员阅读,并帮助语法突出显示工具正确解释您的代码。

相关问题