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

Fixed size TableCells are not removed from sene graph when column is removed

    XMLWordPrintable

Details

    • x86_64
    • windows_10
    • Not verified

    Description

      ADDITIONAL SYSTEM INFORMATION :
      JDK-Version: 11.0.8
      JavaFX-SDK-Version: 15.0.1


      A DESCRIPTION OF THE PROBLEM :
      Given there is a table with fixed size cells and multiple columns and multiple items. When some of the columns are removed after the tables is displayed, then the cells of the removed columns are not removed from the scene graph.

      In JavaFX 8 the same problem also occurs when the columns are set invisible (TableColumn.setVisible(false)). Since then the problem has been partially resolved by removing the cells of invisible columns in TableRowSkinBase#updateCells(boolean). This method could be extended so that cells are removed, if the tableViewProperty of row and column are not equal.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      General Steps:
      1. Create a TableView instance and add it to a window.
      2. Set a fixed cell size (TableView#setFixedCellSize(double))
      3. Add some columns and items to the table.
      4. Display the window.
      5. Remove some of the columns from the end of the column list. The combined width of the remaining columns must not exceed the visible area, otherwise the obsolete cells will not be visible.

      Steps to run the attached example:
      1. javac --module-path %PATH_TO_FX% --add-modules javafx.controls TestApp.java
      2. java --module-path %PATH_TO_FX% --add-modules javafx.controls TestApp
      3. Press the button labeled "Execute Test-Case"

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      TableCells of the removed columns are no longer visible.
      ACTUAL -
      TableCells of the removed columns stay in the table. Most of them are now empty but recognizable by the vertical lines.

      ---------- BEGIN SOURCE ----------

      import java.util.ArrayList;
      import java.util.List;

      import javafx.application.Application;
      import javafx.beans.property.SimpleStringProperty;
      import javafx.collections.FXCollections;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableView;
      import javafx.scene.control.ToolBar;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;

      public class TestApp extends
                           Application {

      private static final int ITEM_COUNT = 100;
      private static final int COLUMN_COUNT = 100;
      private static final int TAIL_LENGTH = 90;

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

      @Override
      public void start(Stage stage) {

      TableView<String> table = new TableView<>();
      table.getColumns().setAll(createColumns());
      table.setItems(FXCollections.observableArrayList());
      table.getItems().addAll(createItems());
      table.setFixedCellSize(24);

      Button buttonExecuteTestCase = new Button("Execute Test-Case");
      buttonExecuteTestCase.setOnAction(event -> {
      removeTailColumns(table);
      });

      ToolBar toolbar = new ToolBar(buttonExecuteTestCase);

      BorderPane root = new BorderPane();
      root.setTop(toolbar);
      root.setCenter(table);

      stage.setTitle("Hello World!");
      stage.setScene(new Scene(root,
      800,
      500));
      stage.show();
      }

      private static List<TableColumn<String, ?>> createColumns() {
      List<TableColumn<String, ?>> columns = new ArrayList<>(COLUMN_COUNT);
      for (int i = 1; i <= COLUMN_COUNT; i++) {
      String name = "C"
      + i;
      TableColumn<String, String> column = new TableColumn<>(name);
      column.setCellValueFactory(cellDataFeatrues -> new SimpleStringProperty(name
      + " "
      + cellDataFeatrues.getValue()));

      columns.add(column);
      }
      return columns;
      }

      private static List<String> createItems() {
      List<String> items = new ArrayList<>(ITEM_COUNT);
      for (int i = 1; i <= ITEM_COUNT; i++) {
      items.add("R"
      + i);
      }
      return items;
      }

      private static void removeTailColumns(TableView<String> table) {
      int from = table.getColumns().size()
      - TAIL_LENGTH;
      int to = table.getColumns().size();
      table.getColumns().remove(from,
      to);
      }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      In JavaFX 8 the TableRowSkin can be extended as desribed above by the application developer. This is no longer possible in JavaFX 9+. No other workarounds known for more recent versions.

      Attachments

        Issue Links

          Activity

            People

              aghaisas Ajit Ghaisas
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: