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

[CSS] Strange behavior of TreeItem's disclosure arrow // expanded/collapsed state not reflected correctly

XMLWordPrintable

      I have a TreeView similar to the following example.

      Since JavaFX 8, I noticed, that the disclosure node (the little arrow on the left) goes wild and/or is not reflecting the expanded/collapse state of the TreeItem correctly.

      Just manually collapse/expand the TreeItems a few times and hover over them in order to trigger the mouseenter event of the View.

      => The arrows behave very strange.

      It worked well in JavaFX 2.2.

      It's very strange, but I noticed, it is only when you add any (even non-existent) CSS class (or use setStyle) to the cell in the updateItem method (and remove it again or setStyle(null)).


      (I have to do it in the updateItem method because the CSS class depends on the item)

      Caspian seems to be more affected than Modena, but both have the problem.

      If there's a workaround, let me know, please.


      import javafx.application.Application;
      import javafx.event.EventHandler;
      import javafx.geometry.Pos;
      import javafx.scene.Scene;
      import javafx.scene.control.*;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;
      import javafx.util.Callback;

      public class TestApp4 extends Application {
          public static void main(String[] args) throws Exception {
              launch(args);
          }


          public void start(final Stage stage) throws Exception {

              Application.setUserAgentStylesheet(Application.STYLESHEET_CASPIAN);
              TreeItem<String> rootItem = new TreeItem<String>();
              TreeView<String> treeView = new TreeView<String>(rootItem);
              treeView.setShowRoot(false);
              treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {
                  @Override
                  public TreeCell<String> call(TreeView<String> stringTreeView) {
                      TreeCell<String> treeCell = new TreeCell<String>() {
                          @Override
                          protected void updateItem(String item, boolean empty) {
                              super.updateItem(item, empty);
                              if (empty) {
                                  setStyle(null); // This line is suspicious for the bug.
                                  setGraphic(null);
                                  setText(null);
                              } else {
                                  if (item.startsWith("Item")) {
                                      setStyle("-fx-background-color: lightblue");
                                      setGraphic(new View(item));
                                  } else {
                                      setText(item);
                                  }
                              }
                          }
                      };
                      return treeCell;
                  }
              });
              TreeItem<String> treeItem1 = new TreeItem<String>("Item1");
              treeItem1.getChildren().add(new TreeItem<String>("SubItem1"));

              TreeItem<String> treeItem2 = new TreeItem<String>("Item2");
              treeItem2.getChildren().add(new TreeItem<String>("SubItem2"));

              TreeItem<String> treeItem3 = new TreeItem<String>("Item3");
              treeItem3.getChildren().add(new TreeItem<String>("SubItem3"));

              rootItem.getChildren().addAll(treeItem1, treeItem2, treeItem3);

              Scene scene = new Scene(treeView, 300, 300);
              stage.setScene(scene);
              stage.show();
          }

          private static class View extends StackPane {

              private final HBox hBoxOverlay;

              public View(String item) {

                  getChildren().add(new Label(item));
                  hBoxOverlay = new HBox();
                  hBoxOverlay.setVisible(false);
                  hBoxOverlay.setAlignment(Pos.CENTER_RIGHT);
                  hBoxOverlay.getChildren().addAll(new Button("Test"));

                  setOnMouseEntered(new EventHandler<MouseEvent>() {
                      @Override
                      public void handle(MouseEvent mouseEvent) {
                          hBoxOverlay.setVisible(true);
                      }
                  });

                  setOnMouseExited(new EventHandler<MouseEvent>() {
                      @Override
                      public void handle(MouseEvent mouseEvent) {
                          hBoxOverlay.setVisible(false);
                      }
                  });
                  getChildren().add(hBoxOverlay);
              }
          }
      }

            dgrieve David Grieve
            cschudtjfx Christian Schudt (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: