仍然不明白为什么我的TableView更改监听器不起作用

时间:2018-09-11 20:05:33

标签: java javafx

我知道我的问题很琐碎,解决方案已经浮出水面,但是我仍然无法解决它,因此需要帮助。问题是我的代码中的TableView ListChangeListener不显示更新的更改。在问一个问题之前,我已经阅读了许多主题,手册和示例

Javafx: Detect ALL changes made to tableView including addition/deletion of table rows and cell edits on any table rows

Java ListChangeListener WasUpdated() doesn't work

https://docs.oracle.com/javase/8/javafx/api/javafx/collections/ListChangeListener.Change.html#wasUpdated--

http://java-buddy.blogspot.com/2014/11/example-of-listchangelistener-for.html

,但仍然不明白为什么我的代码无法正常工作。我添加了extractor,但对我没有帮助。

这是我的代码的一部分

public class mainTableOverviewController {


    @FXML
    private TableView<EmailData> emailTableView;
    @FXML
    private TableColumn<EmailData, String> emailNameColumn;
    @FXML
    private TableColumn<EmailData, String> emailLoginColumn;
    @FXML
    private TableColumn<EmailData, String> emailPasswordColumn;
    @FXML
    private TableColumn<EmailData, String> emailCommentsColumn;

    @FXML
    private Button handleDeletePerson;


    private MainApp mainApp;

    public mainTableOverviewController() {

    }

    @FXML
    private void initialize() {
        emailTableView.setEditable(true);
        emailTableView.getSelectionModel().setCellSelectionEnabled(true);
        emailTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        Callback<TableColumn<EmailData, String>, TableCell<EmailData, String>> cellFactory =
                new Callback<TableColumn<EmailData, String>, TableCell<EmailData, String>>() {
                    public TableCell call(TableColumn p) {
                        return new EditingCell();
                    }
                };
        emailNameColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        emailNameColumn.setCellFactory(cellFactory);
        emailNameColumn.setOnEditCommit(
                t -> t.getTableView().getItems().get(
                        t.getTablePosition().getRow()).setName(t.getNewValue())
        );

        emailLoginColumn.setCellValueFactory(cellData -> cellData.getValue().loginProperty());
        emailLoginColumn.setCellFactory(cellFactory);
        emailLoginColumn.setOnEditCommit(
                t -> t.getTableView().getItems().get(
                        t.getTablePosition().getRow()).setLogin(t.getNewValue())
        );
        emailPasswordColumn.setCellValueFactory(cellData -> cellData.getValue().passwordProperty());
        emailPasswordColumn.setCellFactory(cellFactory);
        emailPasswordColumn.setOnEditCommit(
                t -> t.getTableView().getItems().get(
                        t.getTablePosition().getRow()).setPassword(t.getNewValue())
        );
        emailCommentsColumn.setPrefWidth(120);
        emailCommentsColumn.setCellValueFactory(cellData -> cellData.getValue().commentsProperty());
        emailCommentsColumn.setCellFactory(cellFactory);
        emailCommentsColumn.setOnEditCommit(
                t -> t.getTableView().getItems().get(
                        t.getTablePosition().getRow()).setComments(t.getNewValue())
        );

        emailData.addListener((Change<? extends EmailData> c) -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    System.out.println("Added:");
                    c.getAddedSubList().forEach(System.out::println);
                    System.out.println();
                }
                if (c.wasRemoved()) {
                    System.out.println("Removed:");
                    c.getRemoved().forEach(System.out::println);
                    System.out.println();
                }
                if (c.wasUpdated()) {
                    System.out.println("Updated:");
                    emailData.subList(c.getFrom(), c.getTo()).forEach(System.out::println);
                    System.out.println();
                }
            }
        });

        emailTableView.getColumns().setAll(emailNameColumn, emailLoginColumn, emailPasswordColumn, emailCommentsColumn, actionCol);
    }
}

    @FXML
    private void handleDeletePerson() {
        int selectedIndex = emailTableView.getSelectionModel().getSelectedIndex();
        if (selectedIndex >= 0) {
            deletedDataList.add(emailTableView.getItems().get(selectedIndex));
            emailTableView.getItems().remove(selectedIndex);
            menuItemDisable.set(false);
        } else {
            nothingSelected();
        }
    }
    class EditingCell extends TableCell<EmailData, String> {
        TextField textField;

        EditingCell() {
        }

        @Override
        public void startEdit() {
            if (!isEmpty()) {
                super.startEdit();
                if (textField == null) {
                    createTextField();
                }

                setGraphic(textField);
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        textField.requestFocus();
                        textField.selectAll();
                    }
                });
            }
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();
            setText((String) getItem());
            setGraphic(null);
        }


        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setGraphic(textField);
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                } else {
                    emailTableView.getColumns().get(0).setVisible(false);
                    emailTableView.getColumns().get(0).setVisible(true);
                    setText(getString());
                    setContentDisplay(ContentDisplay.TEXT_ONLY);
                }
            }
        }

        private void createTextField() {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()
                    * 2);

            textField.focusedProperty().addListener(
                    new ChangeListener<Boolean>() {
                        @Override
                        public void changed(
                                ObservableValue<? extends Boolean> arg0,
                                Boolean arg1, Boolean arg2) {
                            if (!arg2) {
                                commitEdit(textField.getText());
                            }
                        }
                    });

            textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
                @Override
                public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(textField.getText());
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    } else if (t.getCode() == KeyCode.TAB) {
                        commitEdit(textField.getText());
                        TableColumn nextColumn = getNextColumn(!t.isShiftDown());
                        if (nextColumn != null) {
                            getTableView().edit(getTableRow().getIndex(),
                                    nextColumn);
                        }

                    }
                }

            });
        }

        private String getString() {
            return getItem() == null ? "" : getItem();
        }

         private TableColumn<EmailData, ?> getNextColumn(boolean forward) {
            List<TableColumn<EmailData, ?>> columns = new ArrayList<>();
            for (TableColumn<EmailData, ?> column : getTableView().getColumns()) {
                columns.addAll(getLeaves(column));
            }
            // There is no other column that supports editing.
            if (columns.size() < 2) {
                return null;
            }
            int nextIndex = columns.indexOf(getTableColumn());
            if (forward) {
                nextIndex++;
                if (nextIndex > columns.size() - 1) {
                    nextIndex = 0;
                }
            } else {
                nextIndex--;
                if (nextIndex < 0) {
                    nextIndex = columns.size() - 1;
                }
            }
            return columns.get(nextIndex);
        }

        private List<TableColumn<EmailData, ?>> getLeaves(
                TableColumn<EmailData, ?> root) {
            List<TableColumn<EmailData, ?>> columns = new ArrayList<>();
            if (root.getColumns().isEmpty()) {
                if (root.isEditable()) {
                    columns.add(root);
                }
                return columns;
            } else {
                for (TableColumn<EmailData, ?> column : root.getColumns()) {
                    columns.addAll(getLeaves(column));
                }
                return columns;
            }
        }
    }
}

以及列表声明所在的Class:

public class MainApp extends Application {
    public static ObservableList<EmailData> backupList = FXCollections.observableArrayList();

    public static ObservableList<EmailData> emailData = FXCollections.observableArrayList(ed ->
            new Observable[]{
                    ed.nameProperty(),
                    ed.loginProperty(),
                    ed.passwordProperty(),
                    ed.commentsProperty()
            });

    private BorderPane rootLayout;

    public MainApp() {
        }
        public static void readCryptedData(String s) {
        try {
            switch (s) {
                    case "initData":
                    emailData = readDataFromStream(decryptFileBytes(libraryPath, salt, nonce));
                    break;
                default:
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

    }
               public static ObservableList<EmailData> getEmailData() {
        return emailData;
    }


    @Override
    public void start(Stage primaryStage) {
        MainApp.primaryStage = primaryStage;
        MainApp.primaryStage.setResizable(false);
        MainApp.primaryStage.getIcons().add(new Image(imageFile.toURI().toString()));
        initRootLayout();
        try {
            showFirstView();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
           private void initRootLayout() {

        try {
            FXMLLoader loader = new FXMLLoader();
 loader.setLocation(MainApp.class.getResource("/fxml/RootLayout.fxml"));
            rootLayout = loader.load();
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.show();
            menuItemDisable.set(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public Stage getPrimaryStage() {
        return primaryStage;
    }



    @Override
    public void stop() {
        if (emailData.size() != 0) {
            saveDataToFile();
        }

    }

}

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

在寻找问题的注释和缺点之后,我发现我需要自己在代码中查找问题。希望有人会发现这个问题并回答有用。 问题出在我的读取方法readDataFromStream()中。在阅读上述主题之前,我使用了ObservableList

这样的声明
public static ObservableList<EmailData> emailData = FXCollections.observableArrayList(); 

我的readDataFromStream如下:

public static ObservableList<EmailData> readDataFromStream(byte[] bytes) {
    ObservableList<EmailData> emailData = FXCollections.observableArrayList();
    try {
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        List<EmailData> list = (List<EmailData>) ois.readObject();
        emailData = FXCollections.observableList(list);
        bis.close();
        ois.close();
    } catch (ClassNotFoundException | IOException e) {
        e.printStackTrace();
    }
    return emailData;
}

然后,我读到我需要使用提取器创建列表。然后将ObservableList声明更改为:

ObservableList<EmailData> emailData = FXCollections.observableArrayList(ed ->
        new Observable[]{
                ed.nameProperty(),
                ed.loginProperty(),
                ed.passwordProperty(),
                ed.commentsProperty()
        });

但是我的readDataFromStream()方法保持不变。现在,我将其更改为:

public static ObservableList<EmailData> readDataFromStream(byte[] bytes) {
ObservableList<EmailData> emailData = FXCollections.observableArrayList(ed ->
        new Observable[]{
                ed.nameProperty(),
                ed.loginProperty(),
                ed.passwordProperty(),
                ed.commentsProperty()
        });
    try {
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        List<EmailData> list = (List<EmailData>) ois.readObject();
            emailData = FXCollections.observableList(
        list,
        (EmailData tp) -> new Observable[]{tp.nameProperty(), tp.passwordProperty(),
                tp.loginProperty(), tp.commentsProperty()});
        bis.close();
        ois.close();
    } catch (ClassNotFoundException | IOException e) {
        e.printStackTrace();
    }
    return emailData;
}

wasUpdated()的{​​{1}}方法现在就像一个超级按钮一样。

希望它将对像我这样的新手有所帮助。