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,43 **** --- 25,48 ---- 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,59 **** --- 55,70 ---- **************************************************************************/ 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,123 **** --- 121,139 ---- 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,137 **** --- 144,157 ---- } 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,178 **** --- 188,222 ---- } } } } + 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 * * *