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.