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

Typing space in ComboBox causes expanded list to close.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 7u21
    • javafx
    • None
    • Running JavaFX version bundled with Java 1.7.0_21

      In the ComboBoxListViewSkin there is a key press handler added to the ListView that calls ComboBox.hide() when enter, escape or space is pressed. While enter and escape seem valid, space does not. I have an editable ComboBox that I want to drill down contents as text is typed in, ensuring the popup is displayed with matching items. If the complete list has items displayed with spaces you would want to type space - however this causes the call to hide(), making the popup collapse then re-expand. It's fine for any other text than space. The code that causes this is in ComboBoxListViewSkin.createListView(), and there doesn't appear to be any way to override or intercept this:


              listView.setOnKeyPressed(new EventHandler<KeyEvent>() {
                  @Override public void handle(KeyEvent t) {
                      // TODO move to behavior, when (or if) this class becomes a SkinBase
                      if (t.getCode() == KeyCode.ENTER ||
                              t.getCode() == KeyCode.SPACE ||
                              t.getCode() == KeyCode.ESCAPE) {
                          comboBox.hide();
                      }
                  }
              });
              
      Example code showing this bug is listed below:

      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.event.EventHandler;
      import javafx.geometry.Insets;
      import javafx.scene.SceneBuilder;
      import javafx.scene.control.ComboBox;
      import javafx.scene.input.KeyEvent;
      import javafx.scene.layout.FlowPane;
      import javafx.scene.layout.FlowPaneBuilder;
      import javafx.stage.Stage;

      public class ComboBoxTest extends Application {

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

          @Override
          public void start(Stage stage) throws Exception {
              ObservableList<String> list = FXCollections.observableArrayList(
                      "aa a", "aab", "aa c",
                      "ab a", "abb", "ab c",
                      "ac a", "acb", "ac c",
                      "ba a", "bab", "ba c",
                      "bb a", "bbb", "bb c",
                      "bc a", "bcb", "bc c",
                      "ca a", "cab", "ca c",
                      "cb a", "cbb", "cb c",
                      "cc a", "ccb", "cc c");
              FilterComboBox fcb = new FilterComboBox(list);

              FlowPane pane = FlowPaneBuilder.create()
                      .padding(new Insets(10))
                      .children(fcb)
                      .build();

              stage.setScene(SceneBuilder.create().root(pane).build());
              stage.setResizable(true);
              stage.show();
          }

          private class FilterComboBox extends ComboBox<String> {
              private ObservableList<String> allItems;
              private ObservableList<String> filteredItems = FXCollections.observableArrayList();
              private String searchString = "";

              FilterComboBox(ObservableList<String> allItems) {
                  super(allItems);
                  this.allItems = allItems;
                  setEditable(true);
                  setOnKeyReleased(new KeyHandler());
              }

              private class KeyHandler implements EventHandler<KeyEvent> {
                  @Override
                  public void handle(KeyEvent event) {
                      if (!event.getCode().isNavigationKey()) {
                          String newSearchString = getEditor().getText();
                          if(!searchString.equals(newSearchString)) {
                              processTextChanged(newSearchString);
                          }
                      }
                  }

                  private void processTextChanged(String newSearchString) {
                      searchString = newSearchString;
                      if(searchString.isEmpty()) {
                          setItems(allItems);
                      } else {
                          filteredItems.clear();
                          for (String item : allItems) {
                              if (item.startsWith(searchString)) {
                                  filteredItems.add(item);
                              }
                          }
                          setItems(filteredItems);
                      }
                      show();
                  }
              }
          }
      }

          

            Unassigned Unassigned
            duke J. Duke
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Imported: