TableView 不刷新

TableView doesn't refresh

我有一个用 JavaFX 编写的项目,我正在尝试刷新 table 视图,但没有结果。 我用谷歌搜索并尝试了一些我发现的例子,但它仍然不起作用。

我用此 table 中每一行的信息填充了一个 table 视图,双击该行可以添加新评论。将打开一个新的 Tabpane,可以在其中添加新评论。在关闭此选项卡窗格时,我希望刷新我单击的选项卡窗格。 我一定做错了什么。我只是不知道。

在我的 StoreController 中

private void populateTableView(List<Store> stores) {
    ObservableList<Store> data = FXCollections.observableArrayList(stores);
    storeNumberColumn.setCellValueFactory(
            new PropertyValueFactory<Store, String>("id"));
    storePhoneColumn.setCellValueFactory(
            new PropertyValueFactory<Store, String>("phoneNbr"));
    chainColumn.setCellValueFactory(
            new PropertyValueFactory<Store, String>("chainId"));
    commentColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Store, ImageView>, ObservableValue<String>>() {
        @Override
        public ObservableValue<String> call(TableColumn.CellDataFeatures<Store, ImageView> p) {
            Integer numberOfComments = p.getValue().getCommentsCount();
            ReadOnlyObjectWrapper wrapper = null;
            if (numberOfComments == 0) {
                wrapper = null;
            } else if (numberOfComments == 1) {
                wrapper = new ReadOnlyObjectWrapper(new ImageView(COMMENT_SINGLE_FLAG_SOURCE));
            } else {
                wrapper = new ReadOnlyObjectWrapper(new ImageView(COMMENT_DOUBLE_FLAG_SOURCE));
            }
            return wrapper;
        }
    });
    storeTable.setItems(data);
    sortTable(storeTable, missedColumn);
}

@FXML
public void handleTableAction(MouseEvent event) {
    if (event.getClickCount() == 2) {
        showNewCommentStage();
    }
}

private void showNewCommentStage() {
    initCommentController();
    Store store
            = storeTable.getSelectionModel().selectedItemProperty().getValue();
    commentController.showNewStage(commentPane, store);
}

评论面板关闭时似乎没有调用调用函数。

评论控制器

public void showNewStage(Pane pane, Store store) {
    this.store = store;
    initStage(pane);
    windowHandler = new WindowHandler(stage);
    effectHandler.playEffect(pane);
    constructCommentHeaders();
    List<Comment> comments;
    comments = commentService.listByStoreId(store.getId());
    populateCommentTable(comments);
}

就像我说的,我已经尝试了很多在 Whosebug 上找到的解决方案,但没有结果。 Tableview 不刷新。商店和评论在不同的数据库 table 中,如果这很重要的话 有人能指出我正确的方向吗? 谢谢!

****编辑**** Store.class

public class Store extends CommentEntity {
    private String id;
    private String chainId;
    private String phoneNbr;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getChainId() {
        return chainId;
    }

    public void setChainId(String chainId) {
        this.chainId = chainId;
    }

    public String getPhoneNbr() {
        return phoneNbr;
    }

    public void setPhoneNbr(String phoneNbr) {
        this.phoneNbr = phoneNbr;
    }

    @Override
    public String toString() {
        return "Store{" + "id=" + id + ", chainId=" + chainId + '}';
    }

    @Override
    public String getCommentIdentifier() {
        return id;
    }

}

CommentEntity.Class

public abstract class CommentEntity {
    private int commentsCount;

    public int getCommentsCount() {
        return commentsCount;
    }

    public void setCommentsCount(int commentsCount) {
        this.commentsCount = commentsCount;
    }

    public abstract String getCommentIdentifier();
}

感谢您的输入,我什至没有考虑过 ImageView / String。

两个问题:

首先,您需要区分列中单元格显示的 data 和实际显示这些数据的 cells . cellValueFactory 决定显示的 数据 PropertyValueFactory 是引用 JavaFX 属性 的 cellValueFactory 实现,因此当您调用

storeNumberColumn.setCellValueFactory(new PropertyValueFactory<Store, String>("id"));

它有效地告诉 storeNumberColumn 中的单元格调用当前行中 Store 对象的 idProperty() 方法来获取单元格的数据。 (如果不存在这样的方法,它将尝试使用 getId() 作为备份计划。)

默认情况下,您会得到一个 cellFactory,它显示对 cellValueFactory 生成的数据调用 toString() 后产生的文本。如果您的数据只是 Strings,这通常就是您所需要的。在其他情况下,您通常需要提供自己的 cellFactory 以获得显示数据的正确方式。

在您的例子中,commentColumn 的数据只是评论数。您将根据该数值选择图像来显示它。

所以你应该

TableColumn<Store, Number> commentColumn = new TableColumn<>("Comments");

对于cellValueFactory,你可以直接使用

commentColumn.setCellValueFactory(new PropertyValueFactory<>("commentsCount"));

那么你需要一个 cellFactory 来显示合适的 ImageView:

commentColumn.setCellFactory(new Callback<TableColumn<Store, Number>, new TableCell<Store, Number>>() {
    @Override
    public TableCell<Store, Number>() {
        private ImageView imageView = new ImageView();

        @Override
        public void updateItem(Number numberOfComments, boolean empty) {
            super.updateItem(count, empty) ;
            if (empty) {
                setGraphic(null);
            } else {
                if (numberOfComments.intValue() == 0) {
                    setGraphic(null);
                } else if (numberOfComments.intValue() == 1) {
                    imageView.setImage(new Image(COMMENT_SINGLE_FLAG_SOURCE));
                    setGraphic(imageView);
                } else {
                    imageView.setImage(new Image(COMMENT_DOUBLE_FLAG_SOURCE));
                    setGraphic(imageView);
                }
            }
        }
    }
});

第二期其实是关于更新的。 TableView 通过观察由 cellValueFactory 作为 ObservableValue 提供的 JavaFX properties 来保持其内容 "live"。如果显示 table 时值可能会发生变化,您 必须 提供可以观察到的实际 属性:使用 ReadOnlyObjectWrapper 是不好的(因为它是只读的,所以它的包装值不会改变)。如果您没有 JavaFX 属性 访问器方法(即,如果它仅使用 getXXX() 方法访问数据),PropertyValueFactory 也将 return ReadOnlyObjectWrapper .所以你的模型 class 必须提供 JavaFX 属性。

您可以通过更新 CommentEntity 以使用 IntegerProperty:

来立即修复此问题
public abstract class CommentEntity {
    private final IntegerProperty commentsCount = new SimpleIntegerProperty();

    public final int getCommentsCount() {
        return commentsCountProperty().get();
    }

    public final void setCommentsCount(int commentsCount) {
        commentsCountProperty().set(commentsCount);
    }

    public IntegerProperty commensCountProperty() {
        return commentsCount ;
    }

    public abstract String getCommentIdentifier();
}

我还强烈建议更新 Store class 以类似方式使用 JavaFX 属性。