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()
后产生的文本。如果您的数据只是 String
s,这通常就是您所需要的。在其他情况下,您通常需要提供自己的 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 属性。
我有一个用 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()
后产生的文本。如果您的数据只是 String
s,这通常就是您所需要的。在其他情况下,您通常需要提供自己的 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 属性。