简体   繁体   中英

Extrange behaviour on expandNode TreeTableView JavaFx

I have a TreeTableView wich have 3 levels, and I just want to let users to select nodes of one type (Only first level). So i use this solution TreeView - Certain TreeItems are not allowed to be selected with some necesary changes to fit TreeTableView.

It works fine but when I select one node and expand above's node, selection moves to one prohibited selection node.

Can anyone point me in the right direction.

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();
    }

}

I do not know what happened, but now it woks. I Have changed from java 11 to java 8, but i don't know if this is the reason.

Anyway, now the above code seems to work properly.

Implementing a selection-model for a TreeTableView is a bit more complex compared to the TreeView example you worked from in the question you referenced. You can take a look at at the question here where I implement a custom FilteredTreeTableViewSelectionModel .

For your particular example you just need to provide a custom TreeItemSelectionFilter that filters on instances of Vivienda as follows:

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

and the selection-filtering should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM