滚动项的JavaFX TreeTableView通知

时间:2014-04-17 18:42:26

标签: javafx-8 treetableview

我正在编写一个使用JavaFX8 TreeTableView的应用程序。树表有三列,其中两列是字符串属性(名称),另一列有一个Canvas小部件,用于从a中的数据中绘制图片数据库(波形)。在应用程序上还有一个控件,允许(所有图纸的)显示被缩小或缩小(或者左右滚动)。

name value 列使用我的数据模型中的StringProperty值,因此为这些列设置了CellValueFactory。绘图列使用CellFactory和CellValueFactory,如下所示:

    // Waveform column
    TreeTableColumn<DrawRow, WaveformTraceBox> waveColumn = new TreeTableColumn<>();
    waveColumn.setCellFactory(new Callback<TreeTableColumn<DrawRow, WaveformTraceBox>, TreeTableCell<DrawRow, WaveformTraceBox>>() {
        @Override
        public TreeTableCell<DrawRow, WaveformTraceBox> call(TreeTableColumn<DrawRow, WaveformTraceBox> param) {
            return new WaveformTraceBoxTreeTableViewCell<>();
        }
    });
    waveColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<DrawRow, WaveformTraceBox>, ObservableValue<WaveformTraceBox>>() {
        @Override
        public ObservableValue<WaveformTraceBox> call(TreeTableColumn.CellDataFeatures<DrawRow, WaveformTraceBox> param) {
            return new ReadOnlyObjectWrapper<>(new WaveformTraceBox());
        }
    });

WaveformTraceBoxTreeTableViewCell是:

protected static class WaveformTraceBoxTreeTableViewCell<T> extends TreeTableCell<DrawRow, T> {

    public WaveformTraceBoxTreeTableViewCell() {
        super();
    }

    @Override
    protected void updateItem(T value, boolean empty) {
        super.updateItem(value, empty);
        setText(null);
        setGraphic(null);
        if (!empty && getTreeTableRow().getItem() != null) {
            getTreeTableRow().getItem().setTraceBox((WaveformTraceBox)value);
            setGraphic((WaveformTraceBox) value);
        }
    }

DrawRow是我的数据模型。当用户通过窗口上的控件缩小或缩小时,绘图行模型将通知其关联的Canvas绘图项目以重新绘制其显示。显示图的绘制可能需要一些时间,因为需要处理大量数据才能生成显示。

现在我的问题:当滚动TreeTableView小部件时,它将要求新的Canvas小部件 - 它与数据模型中的DrawRow项相关联。但是,从列表中滚动的窗口小部件将被树窗口小部件抛弃。

我发现无法判断我正在使用的物品是否已被丢弃或是否已被使用。因此,代码正在做更多的工作,因为它试图绘制不再使用或显示的单元格。最终,由于我认为垃圾收集会导致其他问题。

所以我真正的问题是如何判断一个单元格是否已被树表放弃,以便我可以停止尝试更新它?任何帮助都将非常感激。我无法在我所做的各种网络搜索中找到它。

1 个答案:

答案 0 :(得分:0)

你需要担心吗?什么是&#34;绘制不再使用的细胞&#34;?您是否在WaveformTraceBox的后台线程中运行某种更新?

无论如何,你的结构很奇怪。

首先,(不太重要)为什么你的WaveformTraceBoxTreeTableViewCell是通用的?当然你想要

protected static class WaveformTraceBoxTreeTableViewCell extends TreeTableCell<DrawRow, WaveformTraceBox>

然后你可以用T替换WaveformTraceBox并摆脱演员表等。

第二:如果我理解正确,WaveformTraceBox是某种自定义Node子类;即它是一个UI组件。单元格值工厂不应该真正返回UI组件 - 它应该返回要显示的数据。然后,单元工厂应使用一些UI组件来显示数据。

这样,您可以在单元格实现中创建一个WaveFormTraceBox,并更新它在updateItem(...)方法中显示的数据。

类似于:

// Waveform column
TreeTableColumn<DrawRow, WaveformData> waveColumn = new TreeTableColumn<>();
waveColumn.setCellFactory(new Callback<TreeTableColumn<DrawRow, WaveformData>, TreeTableCell<DrawRow, WaveformData>>() {
    @Override
    public TreeTableCell<DrawRow, WaveformData> call(TreeTableColumn<DrawRow, WaveformData> param) {
        return new WaveformTraceBoxTreeTableViewCell();
    }
});
waveColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<DrawRow, WaveformData>, ObservableValue<WaveformData>>() {
    @Override
    public ObservableValue<WaveformTraceBox> call(TreeTableColumn.CellDataFeatures<DrawRow, WaveformTraceBox> param) {
        return new ReadOnlyObjectWrapper<>(getDataToDisplayForItem(param.getValue()));
    }
});



protected static class WaveformTraceBoxTreeTableViewCell extends TreeTableCell<DrawRow, WaveFormData> {

    private WaveformTraceBox traceBox = new WaveformTraceBox();

    public WaveformTraceBoxTreeTableViewCell() {
        super();
    }

    @Override
    protected void updateItem(WaveFormData value, boolean empty) {
        super.updateItem(value, empty);
        setText(null);
        setGraphic(null);
        if (!empty && getTreeTableRow().getItem() != null) {
            traceBox.setData(value);
            setGraphic(traceBox);
        } else {
            setGraphic(null);
        }
    }
}

显然,您需要定义WaveFormData类来封装WaveFormTraceBox将显示的数据,并为WaveFormTraceBox提供setData(WaveFormData)方法。如果您正在使用需要清理的任何资源,则setData(...)的调用将指示WaveformTraceBox不再访问先前的数据。