0

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

名称列使用我的数据模型中的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 项目相关联。但是,列表中滚动到屏幕外的小部件将被树小部件丢弃。

我没有办法判断我正在使用的物品是被扔掉还是不再被使用。因此,代码所做的工作比它需要的要多得多,因为它试图绘制不再使用或显示的单元格。最终这将导致其他问题,因为我认为垃圾收集。

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

4

1 回答 1

0

你需要在这里担心吗?什么仍然是“不再使用的绘图单元”?您是否在 WaveformTraceBox 的后台线程中运行某种更新?

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

首先,(不太重要)为什么你的WaveformTraceBoxTreeTableViewCell通用?你肯定想要

protected static class WaveformTraceBoxTreeTableViewCell extends TreeTableCell<DrawRow, WaveformTraceBox>

然后你可以TWaveformTraceBox整个替换并摆脱演员表等。

第二:如果我理解正确的话,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将显示的数据,并提供WaveFormTraceBoxasetData(WaveFormData)方法。如果您正在使用任何需要清理的资源,则调用setData(...)将表明该 不再访问以前的数据WaveformTraceBox

于 2014-04-17T19:43:31.667 回答