TableView不刷新

时间:2015-05-11 10:49:10

标签: java javafx

我有一个用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。

1 个答案:

答案 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属性。