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 *
* *