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

Combobox (with many items) layout slow until scrolled.

XMLWordPrintable

    • x86_64
    • windows_10

      A DESCRIPTION OF THE PROBLEM :
      When comboboxes have many items, or complex cells, layouts can take a long time. The layout time dramatically improves once the combobox is even slightly scrolled because a single cell gets added to the pile in the virtualflow.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the attached code. Open the combobox and hover over the items. Each one takes a long time to render. If you scroll slightly, then the hover actions happen immediately.

      Each time you move the mouse to a new cell, the cell selection triggers a layout which is slow because it recalculates the combobox width. Once you scroll the combobox however, one or more cells are added to the pile in virtualflow, and those are used to determine the combobox width which massively improves performance.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Combobox layout should be fast after the initial slow layout.
      ACTUAL -
      All layouts are slow until the combobox is scrolled slightly.

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

      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.scene.Scene;
      import javafx.scene.control.ComboBox;
      import javafx.scene.control.ListCell;
      import javafx.scene.control.ListView;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;
      import javafx.util.Callback;

      public class ComboBoxTest extends Application {

          @Override
          public void start(Stage primaryStage) {

              StackPane root = new StackPane();
              Scene scene = new Scene(root, 800, 600);
              primaryStage.setTitle("Hello World!");
              primaryStage.setScene(scene);
              ComboBox<String> comboBox = new ComboBox();
              comboBox.setEditable(true);
              comboBox.setItems(getItems());
              comboBox.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
                  @Override
                  public ListCell<String> call(ListView<String> arg0) {

                      return new ListCell<String>() {
                          {
                              this.setOnMouseEntered((MouseEvent e) -> {
                                  comboBox.getSelectionModel().select(this.getIndex());
                              });
                          }

                          @Override
                          protected void updateItem(String text, boolean empty) {
                              super.updateItem(text, empty);
                              setText(text);
                          }

                      };
                  }

              });

              root.getChildren().add(comboBox);

              primaryStage.show();
          }

          public ObservableList<String> getItems() {
              ObservableList<String> list = FXCollections.observableArrayList();
              for (int i = 0; i < 500000; i++) {
                  list.add("" + Math.random());
              }
              return list;
          }
      }

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

      FREQUENCY : always


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

              Created:
              Updated: