JavaFX如何保存tableview的状态

我正在研究JAVAFX应用程序.在我的应用程序中,单击一个按钮后,它会打开一个窗口,其中包含一个TableView,其中包含一个“应用并保存”按钮.单击“应用”按钮时,它将保留TableView的当前状态(如果我们添加/删除表行并单击“应用”并重新打开表,则应显示先前更新的TableView). “保存”按钮用于将表记录保存到数据库.假设表中有两行(来自数据库),如果我添加第三行并单击Apply,我的TableView窗口将被关闭.如果我重新打开表格,则第三行不存在.

如何保留以前添加的第三行,而不将其插入数据库?

最佳答案 您可以尝试将TableView的项(或者可选地只是TableView的添加项的列表)存储为打开窗口的类中的成员.

我创建了一个例子:

应用程序TableViewSample可用于打开第二个窗口.此应用程序存储TablePopUp的一个实例,该类可以显示第二个模态阶段,同时维护一个“缓冲区” – 一个Person列表(TableView上显示的数据模型)对象,它们被添加到TableView并被“应用” “但尚未存储在数据库中.

public class TableViewSample extends Application {

    // Stores the state of the TableView and opens the second window
    TablePopUp popUp = new TablePopUp();

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

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new BorderPane());
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(550);

        BorderPane root = (BorderPane) scene.getRoot();

        Button button = new Button("Open window");
        button.setOnAction((e) -> popUp.showTable());

        root.setCenter(button);

        stage.setScene(scene);
        stage.show();
    }

    class TablePopUp {

        // Stores the Person object which were added and applied but not stored
        // in DB
        ObservableList<Person> bufferAdd = FXCollections.observableArrayList();




        // Simulate the items coming from the DV
        private ObservableList<Person> dataFromDB = FXCollections.observableArrayList(
                new Person("Jacob", "Smith", "jacob.smith@example.com"),
                new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new Person("Ethan", "Williams", "ethan.williams@example.com"),
                new Person("Emma", "Jones", "emma.jones@example.com"),
                new Person("Michael", "Brown", "michael.brown@example.com"));

        void showTable() {
            // Temporary buffer for the added Persion objects
            ObservableList<Person> tempBuffer = FXCollections.observableArrayList();
            // Temporary buffer to store persons to be deleted on apply
            ObservableList<Person> bufferRemoveFromBuffer = FXCollections.observableArrayList();
            // Data what the TableView displays
            ObservableList<Person> tableData = FXCollections.observableArrayList();
            // Stores the person objects that will be removed from the DB if Save is pressed
            ObservableList<Person> bufferRemoveFromDB = FXCollections.observableArrayList();

            // The Table displays elements from the DB + the applied buffer
            tableData.addAll(dataFromDB);
            tableData.addAll(bufferAdd);

            // Create the table
            TableView<Person> table = new TableView<Person>();
            table.setItems(tableData);

            Scene scene = new Scene(new BorderPane());
            final Label label = new Label("Address Book");
            label.setFont(new Font("Arial", 20));

            TableColumn firstNameCol = new TableColumn("First Name");
            firstNameCol.setMinWidth(100);
            firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));

            TableColumn lastNameCol = new TableColumn("Last Name");
            lastNameCol.setMinWidth(100);
            lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));

            TableColumn emailCol = new TableColumn("Email");
            emailCol.setMinWidth(200);
            emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));

            table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

            TextField addFirstName = new TextField();
            addFirstName.setPromptText("First Name");
            addFirstName.setMaxWidth(firstNameCol.getPrefWidth());
            TextField addLastName = new TextField();
            addLastName.setMaxWidth(lastNameCol.getPrefWidth());
            addLastName.setPromptText("Last Name");
            TextField addEmail = new TextField();
            addEmail.setMaxWidth(emailCol.getPrefWidth());
            addEmail.setPromptText("Email");

            // Button to add a new Person
            Button addButton = new Button("Add");
            addButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent e) {

                    Person newPerson = new Person(addFirstName.getText(), addLastName.getText(), addEmail.getText());

                    // Add a new element to the temporary buffer and add it to
                    // the table data also
                    tempBuffer.add(newPerson);
                    tableData.add(newPerson);
                    addFirstName.clear();
                    addLastName.clear();
                    addEmail.clear();
                }
            });


            // Button to remove a Person
            Button removeButton = new Button("Remove");
            removeButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent e) {

                    Person selectedItem = table.getSelectionModel().getSelectedItem();

                    if(selectedItem != null) {

                        // Remove the item from the list of the displayed persons
                        tableData.remove(selectedItem);

                        // Check the buffers: if one of the buffer contains the selected item, remove it from the buffer
                        if(tempBuffer.contains(selectedItem))
                            tempBuffer.remove(selectedItem);
                        else if(bufferAdd.contains(selectedItem))
                            bufferRemoveFromBuffer.add(selectedItem);
                        else {
                            // The item is not in the buffers -> remove the item from the DB
                            bufferRemoveFromDB.add(selectedItem);
                        }
                    }
                }
            });

            HBox hb = new HBox();
            hb.getChildren().addAll(addFirstName, addLastName, addEmail, addButton, removeButton);
            hb.setSpacing(3);

            VBox vbox = new VBox();
            vbox.setSpacing(5);
            vbox.setPadding(new Insets(10, 0, 0, 10));
            vbox.getChildren().addAll(label, table, hb);

            BorderPane root = (BorderPane) scene.getRoot();
            root.setCenter(vbox);

            Stage stage = new Stage();

            HBox applySave = new HBox();

            // On Save:
            // Remove all elements from the buffer that were selected to be deleted
            // Remove all elements from the BD that were selected to be deleted
            // Add all the elements from the persistent buffer to the DB
            // Add all the elements from the temporary buffer to the DB
            // Clear both buffers
            Button saveButton = new Button("Save to DB");
            saveButton.setOnAction((e) -> {
                bufferAdd.removeAll(bufferRemoveFromBuffer);
                dataFromDB.removeAll(bufferRemoveFromDB);


                dataFromDB.addAll(bufferAdd);
                dataFromDB.addAll(tempBuffer);

                bufferAdd.clear();
                stage.close();
            });

            // On Apply:
            // Add elements from the temporary buffer to the persistent buffer
            // Remove elements from the buffer
            Button applyButton = new Button("Apply");
            applyButton.setOnAction((e) -> {
                bufferAdd.addAll(tempBuffer);

                bufferAdd.removeAll(bufferRemoveFromBuffer);

                stage.close();
            });

            applySave.getChildren().addAll(saveButton, applyButton);

            root.setBottom(applySave);

            stage.initModality(Modality.APPLICATION_MODAL);
            stage.setScene(scene);
            stage.show();
        }
    }

    public static class Person {

        private final SimpleStringProperty firstName;
        private final SimpleStringProperty lastName;
        private final SimpleStringProperty email;

        private Person(String fName, String lName, String email) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.email = new SimpleStringProperty(email);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public void setFirstName(String fName) {
            firstName.set(fName);
        }

        public String getLastName() {
            return lastName.get();
        }

        public void setLastName(String fName) {
            lastName.set(fName);
        }

        public String getEmail() {
            return email.get();
        }

        public void setEmail(String fName) {
            email.set(fName);
        }
    }
}

TablePopUp类实际上有两个缓冲区:一个临时缓冲区,用于存储添加的元素;一个持久缓冲区,保存在不同的窗口之间.如果按下“应用”按钮,则临时缓冲区存储在持久缓冲区中.如果按下“保存”按钮,则两个缓冲区都存储在DB中,然后清除它们.

在示例中,还删除了删除.在删除时,它会发现,选择要从数据库中删除的Person对象是否来自数据库.如果它来自数据库,它将被放置到缓冲区,如果按下保存按钮,它只会从数据库中删除.相同的工作流程对于已添加但尚未放入数据库的人员有效:在删除时,如果按下“应用”按钮,则仅删除它们.

点赞