TreeView doesn't always update the selection list after TreeItem is removed from the model.
The sample application replicates the problem.
Steps to reproduce:
- expand Root 1
- select Child 1
- press Delete on keyboard
Result: Root 1 is visually selected
output >>
{ [TreeItem [ value: Child 1 ]] added at 0, }
[TreeItem [ value: Child 1 ]]
Missing notification that Root 1 is now selected. Changing the selection produces output:
{ [TreeItem [ value: Root 1 ]] replaced by [TreeItem [ value: Child 2 ]] at 0, }
[TreeItem [ value: Child 2 ]]
Doing the same actions with Child 2 on version 8u11 produces correct results (there is an event that Root 2 is now selected). However on version 8u20 build b23 actions on Child 2 also fail the same as for Child 1.
This problem occurs whenever items from model are removed, for example drag and drop can also result in this bug.
package treeview.selection;
import javafx.application.Application;
import javafx.collections.ListChangeListener.Change;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TreeViewSelectionBug extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
final StackPane stackPane = new StackPane();
final TreeItem<String> root = new TreeItem<>();
root.setExpanded(true);
root.getChildren().addAll(createItem(1), createItem(2));
final TreeView<String> treeView = new TreeView<>(root);
treeView.setShowRoot(false);
treeView.getSelectionModel().getSelectedItems().addListener(this::handleChange);
treeView.setOnKeyPressed(event -> {
if (event.getCode() == KeyCode.DELETE) {
final TreeItem<String> selectedItem = treeView.getSelectionModel().getSelectedItem();
selectedItem.getParent().getChildren().remove(selectedItem);
}
});
stackPane.getChildren().add(treeView);
final Scene scene = new Scene(stackPane, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private TreeItem<String> createItem(final int number) {
final TreeItem<String> root = new TreeItem<>("Root " + number);
final TreeItem<String> child = new TreeItem<>("Child " + number);
root.getChildren().add(child);
return root;
}
private void handleChange(final Change<? extends TreeItem<String>> change) {
System.out.println(change);
System.out.println(change.getList());
}
}
The sample application replicates the problem.
Steps to reproduce:
- expand Root 1
- select Child 1
- press Delete on keyboard
Result: Root 1 is visually selected
output >>
{ [TreeItem [ value: Child 1 ]] added at 0, }
[TreeItem [ value: Child 1 ]]
Missing notification that Root 1 is now selected. Changing the selection produces output:
{ [TreeItem [ value: Root 1 ]] replaced by [TreeItem [ value: Child 2 ]] at 0, }
[TreeItem [ value: Child 2 ]]
Doing the same actions with Child 2 on version 8u11 produces correct results (there is an event that Root 2 is now selected). However on version 8u20 build b23 actions on Child 2 also fail the same as for Child 1.
This problem occurs whenever items from model are removed, for example drag and drop can also result in this bug.
package treeview.selection;
import javafx.application.Application;
import javafx.collections.ListChangeListener.Change;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TreeViewSelectionBug extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
final StackPane stackPane = new StackPane();
final TreeItem<String> root = new TreeItem<>();
root.setExpanded(true);
root.getChildren().addAll(createItem(1), createItem(2));
final TreeView<String> treeView = new TreeView<>(root);
treeView.setShowRoot(false);
treeView.getSelectionModel().getSelectedItems().addListener(this::handleChange);
treeView.setOnKeyPressed(event -> {
if (event.getCode() == KeyCode.DELETE) {
final TreeItem<String> selectedItem = treeView.getSelectionModel().getSelectedItem();
selectedItem.getParent().getChildren().remove(selectedItem);
}
});
stackPane.getChildren().add(treeView);
final Scene scene = new Scene(stackPane, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private TreeItem<String> createItem(final int number) {
final TreeItem<String> root = new TreeItem<>("Root " + number);
final TreeItem<String> child = new TreeItem<>("Child " + number);
root.getChildren().add(child);
return root;
}
private void handleChange(final Change<? extends TreeItem<String>> change) {
System.out.println(change);
System.out.println(change.getList());
}
}
- relates to
-
JDK-8118846 [ListView, TreeView, TableView, TreeTableView] selectionModel selectedItem returns wrong item.
- Closed