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

Details

    Description

      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);
              }
          }
      }

      Attachments

        Issue Links

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved:
                Imported: