Test application code reproduced below.
Steps to reproduce:
1) Select 'Child Node 1'
2) Expand 'Child Node 1' by clicking on arrow
3) Collapse 'Child Node 1' by clicking on arrow
Output from before fix applied:
expandedItems: 4
select range 2 to 4
collapsed, selectedIndices: [1, 2, 3]
collapsed, selectedItems: [TreeItem [ value: Child Node 1 ], null, null]
The issue is that only index 1 is selected (so 2 and 3 should not be in selected indices), and there should not be two nulls in the selected items list.
Test application:
import javafx.application.Application;
import javafx.collections.*;
import javafx.collections.transformation.*;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.stage.Stage;
import java.util.Collection;
import java.util.Objects;
public class TreeTableViewSample extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
final TreeItem<String> childNode1 = new TreeItem<>("Child Node 1");
childNode1.getChildren().addAll(
new TreeItem<String>("Node 1-1"),
new TreeItem<String>("Node 1-2")
);
final TreeItem<String> root = new TreeItem<>("Root node");
root.setExpanded(true);
root.getChildren().add(childNode1);
TreeTableColumn<String,String> column = new TreeTableColumn<>("Column");
column.setPrefWidth(190);
column.setCellValueFactory((CellDataFeatures<String, String> p) ->
new ReadOnlyStringWrapper(p.getValue().getValue()));
final TreeTableView<String> treeTableView = new TreeTableView<>(root);
treeTableView.getColumns().add(column);
treeTableView.setPrefWidth(200);
treeTableView.setShowRoot(true);
treeTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
// Select all children of expanded node.
treeTableView.expandedItemCountProperty().addListener((observable, oldCount, newCount) -> {
if (newCount.intValue() > oldCount.intValue()) {
System.out.println("expandedItems: " + newCount);
selectChildrenOfRows(treeTableView, treeTableView.getSelectionModel().getSelectedIndices());
} else {
System.out.println("collapsed, selectedIndices: " + treeTableView.getSelectionModel().getSelectedIndices());
System.out.println("collapsed, selectedItems: " + treeTableView.getSelectionModel().getSelectedItems());
}
});
final Scene scene = new Scene(new Group(), 200, 400);
Group sceneRoot = (Group)scene.getRoot();
sceneRoot.getChildren().add(treeTableView);
stage.setTitle("Tree Table View Samples");
stage.setScene(scene);
stage.show();
}
private void selectChildrenOfRows(TreeTableView<String> table, Collection<Integer> selectedRows) {
for (int index: selectedRows) {
TreeItem<String> item = table.getTreeItem(index);
if (item != null && item.isExpanded() && !item.getChildren().isEmpty()) {
int startIndex = index + 1;
int maxCount = startIndex + item.getChildren().size();
System.out.println("select range " + startIndex + " to " + maxCount);
table.getSelectionModel().selectRange(startIndex, maxCount);
}
}
}
}