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

Setting combo box index programmatically should scroll the selection in the popup list into view

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 8
    • javafx

      You can programmatically set the selected index of a combo box, and the "button cell" will display the value at that index. However, when you pop open the list, the item is not scrolled into view if it is deep in the list. Here's a demo app which shows the current behavior, and the expected behavior which can be obtained if you dig into the combo box skin API and invoke "scrollTo(index)".

      My feeling is that this "digging" should not be necessary. Changing the selection should automatically scroll the item into view when the combo box's list is shown.

      -----
      package org.pf.javafx.comboboxes;

      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.event.ActionEvent;
      import javafx.event.EventHandler;
      import javafx.geometry.Insets;
      import javafx.geometry.Pos;
      import javafx.scene.Scene;
      import javafx.scene.control.ComboBox;
      import javafx.scene.control.Label;
      import javafx.scene.control.ListView;
      import javafx.scene.control.TextField;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.Priority;
      import javafx.scene.layout.VBox;
      import javafx.scene.paint.Color;
      import javafx.stage.Stage;

      import com.sun.javafx.scene.control.skin.ComboBoxListViewSkin;

      public class ComboBoxSelectionTest extends Application {

          public ComboBoxSelectionTest() {
          }

          @Override
          public void start(Stage stage) throws Exception {
              stage.setTitle("ComboBox programmatic selection test");
              
              Insets insets = new Insets(12,12,12,12);
              
              Label description = new Label(
                  "Shouldn't setting the selected index of a combo box also cause the "
                  + "list in the popup to scroll the selected item into view?!");
              description.setWrapText(true);

              HBox hbox1 = new HBox();
              hbox1.setSpacing(12.0);
              hbox1.setAlignment(Pos.CENTER);
              hbox1.setPadding(insets);
              hbox1.getChildren().add(description);
              
              ObservableList<String> items = getItemsForComboBoxes();

              final ComboBox<String> cb1 = new ComboBox<>(items);
              cb1.getSelectionModel().select(0);
              cb1.setPrefSize(80, 24);
              
              final ComboBox<String> cb2 = new ComboBox<>(items);
              cb2.getSelectionModel().select(0);
              cb2.setPrefSize(80, 24);
              
              final Label label = new Label("Enter index # (0-99); press 'Return': ");
              final TextField comboIndexTF = new TextField("");
              comboIndexTF.setPrefSize(50, 24);
              
              comboIndexTF.setOnAction(new EventHandler<ActionEvent>() {
                  @Override
                  public void handle(ActionEvent event) {
                      try {
                          int index = Integer.valueOf(comboIndexTF.getText());
                          if (index < items.size()) {
                              cb1.getSelectionModel().select(index);
                              cb2.getSelectionModel().select(index);
                          }
                          else {
                              comboIndexTF.setText("");
                          }
                          
                          // Should we really have to do the following?!
                          ComboBoxListViewSkin<?> skin = (ComboBoxListViewSkin<?>)cb2.getSkin();
                          ((ListView<?>)skin.getPopupContent()).scrollTo(index);
                      } catch (NumberFormatException e) {
                          comboIndexTF.setText("");
                      }
                  }
              });

              HBox hbox2 = new HBox();
              hbox2.getChildren().addAll(label, comboIndexTF, cb1, cb2);
              hbox2.setSpacing(12.0);
              hbox2.setAlignment(Pos.CENTER);
              hbox2.setPadding(insets);
              
              Label instructions =
                  new Label(
                      "After pressing 'Return', inspect the list for each combo box. "
                      + "Even though the 'button cell' displays the selected value in "
                      + "both combo boxes, the list in the left one has not been scrolled to the "
                      + "selected index. The right one has been scrolled programmatically via the skin API. \n\n"
                      + "Should it really be necessary to dig into the skin API to have the "
                      + "combo box selection do the expected thing in the drop-down list?!");
              instructions.setWrapText(true);
              
              HBox hbox3 = new HBox();
              hbox3.getChildren().addAll(instructions);
              hbox3.setSpacing(12.0);
              hbox3.setAlignment(Pos.CENTER);
              hbox3.setPadding(insets);
              
              VBox vbox = new VBox(24, hbox1, hbox2, hbox3);
              VBox.setVgrow(hbox2, Priority.NEVER);
              
              Scene scene = new Scene(vbox, 600, 320);
              scene.setFill(Color.WHITE);
              stage.setScene(scene);
              stage.show();
          }

          protected ObservableList<String> getItemsForComboBoxes() {
              String[] values = new String[100];
              for (int i = 0; i < values.length; i++) {
                  values[i] = String.valueOf(i);
              }
              
              ObservableList<String> items = FXCollections.observableArrayList(values);
              return items;
          }

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

            Unassigned Unassigned
            pfurbachejfx Paul Furbacher (Inactive)
            Votes:
            3 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Imported: