modules/controls/src/main/java/com/sun/javafx/scene/control/behavior/ComboBoxBaseBehavior.java

Print this page
rev 9038 : RT-34620: [ComboBox, DatePicker] Buttons set to default/cancel are not reacting to ComboBox enter/esc keys

@@ -25,19 +25,24 @@
 
 package com.sun.javafx.scene.control.behavior;
 
 import javafx.event.EventTarget;
 import javafx.scene.Node;
+import javafx.scene.control.ComboBox;
 import javafx.scene.control.ComboBoxBase;
+import javafx.scene.control.DatePicker;
+import javafx.scene.control.TextField;
 import javafx.scene.input.KeyEvent;
 import javafx.scene.input.MouseButton;
 import javafx.scene.input.MouseEvent;
 import java.util.ArrayList;
 import java.util.List;
 import static javafx.scene.input.KeyCode.DOWN;
 import static javafx.scene.input.KeyCode.ENTER;
+import static javafx.scene.input.KeyCode.ESCAPE;
 import static javafx.scene.input.KeyCode.F4;
+import static javafx.scene.input.KeyCode.F10;
 import static javafx.scene.input.KeyCode.SPACE;
 import static javafx.scene.input.KeyCode.UP;
 import static javafx.scene.input.KeyEvent.KEY_PRESSED;
 import static javafx.scene.input.KeyEvent.KEY_RELEASED;
 

@@ -50,10 +55,16 @@
      **************************************************************************/
 
     private TwoLevelFocusComboBehavior tlFocus;
     
     /**
+     * Used to keep track of the most recent key event. This is used when
+     * the event needs to be forwarded to the parent for bubbling up.
+     */
+    private KeyEvent lastEvent;
+
+    /**
      * 
      */
     public ComboBoxBaseBehavior(final ComboBoxBase<T> comboBox, final List<KeyBinding> bindings) {
         super(comboBox, bindings);
 

@@ -110,14 +121,19 @@
         COMBO_BOX_BASE_BINDINGS.add(new KeyBinding(SPACE, KEY_PRESSED, PRESS_ACTION));
         COMBO_BOX_BASE_BINDINGS.add(new KeyBinding(SPACE, KEY_RELEASED, RELEASE_ACTION));
 
         COMBO_BOX_BASE_BINDINGS.add(new KeyBinding(ENTER, KEY_PRESSED, PRESS_ACTION));
         COMBO_BOX_BASE_BINDINGS.add(new KeyBinding(ENTER, KEY_RELEASED, RELEASE_ACTION));
+
+        // The following keys are forwarded to the parent container
+        COMBO_BOX_BASE_BINDINGS.add(new KeyBinding(ESCAPE, "Cancel"));
+        COMBO_BOX_BASE_BINDINGS.add(new KeyBinding(F10, "ToParent"));
     }
 
     @Override protected void callActionForEvent(KeyEvent e) {
         // If popup is shown, KeyEvent causes popup to close
+        lastEvent = e;
         showPopupOnMouseRelease = true;
         super.callActionForEvent(e);
     }
 
     @Override protected void callAction(String name) {

@@ -128,10 +144,14 @@
         } else if ("showPopup".equals(name)) {
             show();
         } else if ("togglePopup".equals(name)) {
             if (getControl().isShowing()) hide();
             else show();
+        } else if ("Cancel".equals(name)) {
+            cancelEdit(lastEvent);
+        } else if ("ToParent".equals(name)) {
+            forwardToParent(lastEvent);
         } else {
             super.callAction(name);
         }
     }
 

@@ -168,11 +188,35 @@
                 }
             }
         }
     }
     
+    protected void forwardToParent(KeyEvent event) {
+        if (getControl().getParent() != null) {
+            getControl().getParent().fireEvent(event);
+        }
+    }
     
+    protected void cancelEdit(KeyEvent event) {
+        /**
+         * This can be cleaned up if the editor property is moved up
+         * to ComboBoxBase.
+         */
+        ComboBoxBase comboBoxBase = getControl();
+        TextField textField = null;
+        if (comboBoxBase instanceof DatePicker) {
+            textField = ((DatePicker)comboBoxBase).getEditor();
+        } else if (comboBoxBase instanceof ComboBox) {
+            textField = comboBoxBase.isEditable() ? ((ComboBox)comboBoxBase).getEditor() : null;
+        }
+
+        if (textField != null && textField.getTextFormatter() != null) {
+            textField.cancelEdit();
+        } else {
+            forwardToParent(event);
+        }
+    }
     
     /**************************************************************************
      *                                                                        *
      * Mouse Events                                                           *
      *                                                                        *