我有一个用JavaFX编写的项目,我试图在没有结果的情况下刷新tableview。 我已经google了一下,尝试了一些我发现的例子,但它仍然没有用。
我使用信息填充tableview,通过双击该行,此表中的每一行都可以添加新注释。打开一个新的Tabpane,可以在那里添加新的评论。在这个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);
}
当评论窗格关闭时,似乎没有调用call-function。
CommentController
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);
}
就像我说的,我已经在Stackoverflow上尝试了很多解决方案,但没有结果。 Tableview不刷新。如果这很重要,则商店和评论位于不同的数据库表中 有人能指出我正确的方向吗? 谢谢!
**** **** EDIT 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。
答案 0 :(得分:1)
两个问题:
首先,您需要区分列中的单元格正在显示的数据,以及实际显示这些数据的单元格。 cellValueFactory
确定显示的数据。 PropertyValueFactory
是引用JavaFX属性的cellValueFactory
实现,因此当您调用
storeNumberColumn.setCellValueFactory(new PropertyValueFactory<Store, String>("id"));
它有效地告诉storeNumberColumn
中的单元格调用当前行中idProperty()
对象上的Store
方法来获取单元格的数据。 (如果不存在此类方法,则会尝试使用getId()
作为备份计划。)
默认情况下,您会收到一个cellFactory
,其中显示了对toString()
生成的数据调用cellValueFactory
所产生的文字。如果您的数据只是String
,那么这通常就是您所需要的。在其他情况下,您经常需要提供自己的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来保持其内容“实时”。如果在显示表格时值可能会发生变化,则必须提供可以观察到的实际属性:使用ReadOnlyObjectWrapper
是不行的(因为它是只读的,所以它的包装值将会没变)。如果您没有JavaFX属性访问器方法(即,如果它只使用PropertyValueFactory
方法来访问数据),ReadOnlyObjectWrapper
也将返回getXXX()
。因此,您的模型类必须提供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
类以类似的方式使用JavaFX属性。