【问题标题】:Extrange behaviour on expandNode TreeTableView JavaFxexpandNode TreeTableView JavaFx 上的异​​常行为
【发布时间】:2019-03-05 00:50:52
【问题描述】:

我有一个 TreeTableView,它有 3 个级别,我只想让用户选择一种类型的节点(仅第一级)。所以我使用这个解决方案TreeView - Certain TreeItems are not allowed to be selected 进行一些必要的更改以适应 TreeTableView。

它工作正常,但是当我选择一个节点并展开上面的节点时,选择会移动到一个禁止的选择节点。

谁能指出我正确的方向。

public class ViviendaSelectionModel extends TreeTableViewSelectionModel<Treeable<?>> {

    private final TreeTableViewSelectionModel<Treeable<?>> selectionModel;

    public ViviendaSelectionModel(TreeTableViewSelectionModel<Treeable<?>> selectionModel, TreeTableView<Treeable<?>> tree) {
        super(tree);
        this.selectionModel = selectionModel ;
        this.selectionModel.setSelectionMode(SelectionMode.MULTIPLE);
        this.selectionModel.setCellSelectionEnabled(false);
        selectionModeProperty().bindBidirectional(selectionModel.selectionModeProperty());
    }


    @Override
    public ObservableList<Integer> getSelectedIndices() {
        return selectionModel.getSelectedIndices() ;
    }

    @Override
    public ObservableList<TreeItem<Treeable<?>>> getSelectedItems() {
        return selectionModel.getSelectedItems() ;
    }

    @Override
    public void selectIndices(int index, int... indices)

            List<Integer> indicesToSelect = Stream.concat(Stream.of(index), IntStream.of(indices).boxed())
                    .filter(i -> getTreeTableView().getTreeItem(i).getValue() instanceof Vivienda)
                    .collect(Collectors.toList());


            if (indicesToSelect.isEmpty()) {
                return ;
            }
            selectionModel.selectIndices(indicesToSelect.get(0), 
                    indicesToSelect.stream().skip(1).mapToInt(Integer::intValue).toArray());

    }

    @Override
    public void selectAll() {

            List<Integer> indicesToSelect = IntStream.range(0, getTreeTableView().getExpandedItemCount())
                    .filter(i -> getTreeTableView().getTreeItem(i).getValue() instanceof Vivienda)
                    .boxed()
                    .collect(Collectors.toList());
            if (indicesToSelect.isEmpty()) {
                return ;
            }
            selectionModel.selectIndices(0, 
                    indicesToSelect.stream().skip(1).mapToInt(Integer::intValue).toArray());
    }

    @Override
    public void selectFirst() {
            IntStream.range(0, getTreeTableView().getExpandedItemCount())
                .filter(i -> getTreeTableView().getTreeItem(i).getValue() instanceof Vivienda)
                .findFirst()
                .ifPresent(selectionModel::select);
    }

    @Override
    public void selectLast() {
        IntStream.iterate(getTreeTableView().getExpandedItemCount() - 1, i -> i - 1)
                .limit(getTreeTableView().getExpandedItemCount())
                .filter(i -> getTreeTableView().getTreeItem(i).getValue() instanceof Vivienda)
                .findFirst()
                .ifPresent(selectionModel::select);
    }

    @Override
    public void clearAndSelect(int index) {
            int toSelect = index ;
            int direction = selectionModel.getSelectedIndex() < index ? 1 : -1 ;
            while (toSelect >= 0 && toSelect < getTreeTableView().getExpandedItemCount() && ! (getTreeTableView().getTreeItem(toSelect).getValue() instanceof Vivienda)) {
                toSelect = toSelect + direction  ;
            }
            if (toSelect >= 0 && toSelect < getTreeTableView().getExpandedItemCount()) {
                selectionModel.clearAndSelect(toSelect);
            }
    }

    @Override
    public void select(int index) {
            int toSelect = index ;
            int direction = selectionModel.getSelectedIndex() < index ? 1 : -1 ;
            while (toSelect >= 0 && toSelect < getTreeTableView().getExpandedItemCount() && ! (getTreeTableView().getTreeItem(toSelect).getValue() instanceof Vivienda)) {
                toSelect = toSelect + direction  ;
            }
            if (toSelect >= 0 && toSelect < getTreeTableView().getExpandedItemCount()) {
                selectionModel.select(toSelect);
            }
    }

    @Override
    public void select(TreeItem<Treeable<?>> obj) {;
            if (obj.getValue() instanceof Vivienda) {
                selectionModel.select(obj);
            }
    }

    @Override
    public void clearSelection(int index) {
        selectionModel.clearSelection(index);
    }

    @Override
    public void clearSelection() {
        selectionModel.clearSelection();
    }

    @Override
    public boolean isSelected(int index) {
        return selectionModel.isSelected(index);
    }

    @Override
    public boolean isEmpty() {
        return selectionModel.isEmpty();
    }

    @Override
    public void selectPrevious() {
            int current = selectionModel.getSelectedIndex() ;
            if (current > 0) {
                IntStream.iterate(current - 1, i -> i - 1).limit(current)
                    .filter(i -> getTreeTableView().getTreeItem(i).getValue() instanceof Vivienda)
                    .findFirst()
                    .ifPresent(selectionModel::select);
            }
    }

    @Override
    public void selectNext() {
        this.selectNext();
            int current = selectionModel.getSelectedIndex() ;
            if (current < getTreeTableView().getExpandedItemCount() - 1) {
                IntStream.range(current + 1, getTreeTableView().getExpandedItemCount())
                    .filter(i -> getTreeTableView().getTreeItem(i).getValue() instanceof Vivienda)
                    .findFirst()
                    .ifPresent(selectionModel::select);
            }
    }


    @Override
    public ObservableList<TreeTablePosition<Treeable<?>, ?>> getSelectedCells() {
        return this.selectionModel.getSelectedCells();
    }


    @Override
    public boolean isSelected(int row, TableColumnBase<TreeItem<Treeable<?>>, ?> column) {
            return this.selectionModel.isSelected(row, column);
    }


    @Override
    public void select(int row, TableColumnBase<TreeItem<Treeable<?>>, ?> column) {
        if (getTreeTableView().getTreeItem(row).getValue() instanceof Vivienda) {
                this.selectionModel.select(row, column);
            }
        System.out.println(row + " " + column.getText() + " " + column.getCellData(row));
    }


    @Override
    public void clearAndSelect(int row, TableColumnBase<TreeItem<Treeable<?>>, ?> column) {
            if (getTreeTableView().getTreeItem(row).getValue() instanceof Vivienda) {
                this.selectionModel.clearAndSelect(row, column);
            }else {
                clearSelection();
            }
    }


    @Override
    public void clearSelection(int row, TableColumnBase<TreeItem<Treeable<?>>, ?> column) {
        this.selectionModel.clearSelection(row, column);
    }


    @Override
    public void selectLeftCell() {
        this.selectionModel.selectLeftCell();

    }


    @Override
    public void selectRightCell() {
        this.selectionModel.selectRightCell();
    }


    @Override
    public void selectAboveCell() {
        this.selectionModel.selectAboveCell();
    }


    @Override
    public void selectBelowCell() {
        this.selectionModel.selectBelowCell();
    }

}

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    我不知道发生了什么,但现在可以了。 我已经从 java 11 改成了 java 8,但不知道是不是这个原因。

    无论如何,现在上面的代码似乎可以正常工作了。

    【讨论】:

      【解决方案2】:

      与您在引用的question 中使用的 TreeView 示例相比,为 TreeTableView 实现选择模型要复杂一些。您可以查看问题here,我在其中实现了自定义FilteredTreeTableViewSelectionModel

      对于您的特定示例,您只需要提供一个自定义 TreeItemSelectionFilter 来过滤 Vivienda 的实例,如下所示:

      TreeItemSelectionFilter<S> treeItemFilter = treeItem -> getValue() instanceof Vivienda;
      

      并且选择过滤应该可以工作。

      【讨论】:

        猜你喜欢
        • 2015-05-21
        • 1970-01-01
        • 2018-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-30
        • 2018-08-04
        • 1970-01-01
        相关资源
        最近更新 更多