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

TableView's columns auto-resize if a CSS class is added/removed on MouseEnter/Exit of a wrapping pane

    XMLWordPrintable

    Details

      Description

      *** ISSUE ***

      If a TableView is wrapped in a BorderPane (in my case, could possibly work with any parent-style control) that has a CSS class added or removed on MouseEnter and MouseExit, the TableView inside suddenly starts to re-size the columns whenever the CSS class of the parent control changes. This makes the column(s) to re-size for each enter/exit (I've had it happen that it re-sizes it infinitely larger and the column can't be resized back smaller).

      Do note that it's not normally necessary that the mouse move outside the Stage window itself, it can be to anther part of the GUI if there is more to it, it's just easier to do so in the test to keep the code to a minimum.

      *** HOW TO RUN TEST ***

      Re-size the first column to be smaller than the cell-text-content (truncated). Then move the mouse outside the Stage. Table columns suddenly re-size.

      If you comment out the CSS add/remove code, normal (expected) behavior is observed.

      *** TEST CODE ***

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.beans.property.SimpleStringProperty;
      import javafx.beans.property.StringProperty;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.event.EventHandler;
      import javafx.geometry.Insets;
      import javafx.scene.Scene;
      import javafx.scene.control.Label;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableView;
      import javafx.scene.control.cell.PropertyValueFactory;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;

      /**
       * Problem class to show a table column "Auto sizing" when CSS is applied to an
       * outer pane on MouseEnter/Exit
       */
      public class FXColumnResizeProblem extends Application {

      // some CSS class, doesn't have to exist anywhere, if it does that's fine too
      public static final String CSS_CLASS_MOUSE_FOCUSED = "mouseFocused";

      @Override
      public void start(final Stage stage) throws Exception {

      Label top = new Label("Resize the first column then move the mouse outside the window frame above");
      top.setPadding(new Insets(10));

      final BorderPane wrapper = new BorderPane();
      // apply CSS on MouseEnter and remove it on MouseExit, comment this out and test will work as expected
      wrapper.setOnMouseEntered(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent event) {
      System.out.println("Mouse Entered BorderPane");
      wrapper.getStyleClass().add(CSS_CLASS_MOUSE_FOCUSED);
      }
      });
      wrapper.setOnMouseExited(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent event) {
      System.out.println("Mouse Exited BorderPane");
      wrapper.getStyleClass().remove(CSS_CLASS_MOUSE_FOCUSED);
      }
      });

      TableView<OneRow> table = new TableView<OneRow>();
      table.getSelectionModel().setCellSelectionEnabled(false);
      table.setEditable(false);

      final ObservableList<OneRow> tableData = FXCollections.synchronizedObservableList(FXCollections.observableArrayList());
      for (int i = 0; i < 30; i++) {
      tableData.add(new OneRow("Something Long That Will Be Auto Sized #" + i, "Surname #" + i));
      }

      TableColumn<OneRow, String> col1 = new TableColumn<OneRow, String>("First Name");
      col1.setCellValueFactory(new PropertyValueFactory<OneRow, String>("firstName"));
      TableColumn<OneRow, String> col2 = new TableColumn<OneRow, String>("Last Name");
      col2.setCellValueFactory(new PropertyValueFactory<OneRow, String>("lastName"));

      table.setItems(tableData);
      table.getColumns().add(col1);
      table.getColumns().add(col2);

      wrapper.setTop(top);
      wrapper.setCenter(table);

      Scene mainScene = new Scene(wrapper, 800, 600);
      stage.setScene(mainScene);

      stage.show();

      stage.setOnCloseRequest(e -> {
      Platform.exit();
      System.exit(0);
      });

      }

      public static void main(final String[] args) {
      launch();
      }

      public class OneRow {

      public OneRow(String firstName, String lastName) {
      setFirstName(firstName);
      setLastName(lastName);
      }

      private StringProperty _firstNameProperty;

      private StringProperty _lastNameProperty;

      public StringProperty firstNameProperty() {
      if (_firstNameProperty == null) {
      _firstNameProperty = new SimpleStringProperty();
      }

      return _firstNameProperty;
      }

      public void setFirstName(String firstName) {
      firstNameProperty().set(firstName);
      }

      public String getFirstName() {
      return firstNameProperty().get();
      }

      public StringProperty lastNameProperty() {
      if (_lastNameProperty == null) {
      _lastNameProperty = new SimpleStringProperty();
      }

      return _lastNameProperty;
      }

      public void setLastName(String lastName) {
      lastNameProperty().set(lastName);
      }

      public String getLastName() {
      return lastNameProperty().get();
      }

      }
      }

        Attachments

          Activity

            People

            Assignee:
            jgiles Jonathan Giles
            Reporter:
            ecrumhornjfx Emil Crumhorn (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported: