Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8209017

CheckBoxTreeCell: graphic on TreeItem not always showing



    • b14


      To reproduce, compile and run the example below

      - expand and collapse root by clicking into the expansion icon
      - expected: graphic of root must be visible always
      - actual: graphic not showing

      Note that the actual # of expand/collapse or which children to expand/collapse and which graphics are effected is a bit unpredictable (read: could not find a pattern).

      A bit of digging revealed that the treeItem's graphic is set as the graphic of the checkBox and appears to not be removed properly. So on re-use of the cell, the checkBox still contains the old graphic which leads to removing it from its real target.

      While I don't know where exactly the cleanup of the box' graphic should happen, a quick hack seems to be to null the box' graphic in updateItem, see WCheckBoxTreeCell in the example below.

      public class CheckBoxTreeCellWithGraphic extends Application {

          private Parent createContent() {
              TreeItem<String> root = new TreeItem<>("ROOT", new Label("really"));
              root.getChildren().add(new TreeItem<>("firstChild"));
              root.getChildren().add(new TreeItem<>("secondChild"));
              root.getChildren().forEach(child -> {
                          new TreeItem<>(" of " + child.getValue(), new Label("grand1 "))
                          ,new TreeItem<>(" of " + child.getValue(), new Label("grand2"))
                  child.setGraphic(new Button(child.getValue()));
              TreeView<String> tree = new TreeView<>(root);
              // core checkBoxTreeCell
              // hacked checkBoxTreeCell
      // tree.setCellFactory(c -> new WCheckBoxTreeCell<>());
              return new BorderPane(tree);

          public static class WCheckBoxTreeCell<T> extends CheckBoxTreeCell<T> {
              CheckBox checkBoxAlias;
              public WCheckBoxTreeCell() {
                  InvalidationListener checkBoxGrabber = new InvalidationListener() {
                      public void invalidated(Observable observable) {
                          if (checkBoxAlias == null) {
                              if (getGraphic() instanceof CheckBox) {
                                  checkBoxAlias = (CheckBox) getGraphic();
              public void updateItem(T item, boolean empty) {
                  if (checkBoxAlias != null) {
                  super.updateItem(item, empty);

          public void start(Stage stage) throws Exception {
              stage.setScene(new Scene(createContent()));

          public static void main(String[] args) {

          private static final Logger LOG = Logger


        Issue Links



              nlisker Nir Lisker
              fastegal Jeanette Winzenburg
              0 Vote for this issue
              4 Start watching this issue