JDK-8096725 : RT-34620: [ComboBox, DatePicker] Buttons set to default/cancel are not reacting to ComboBox enter/esc keys
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2013-12-02
  • Updated: 2017-12-11
  • Resolved: 2015-05-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8u60Fixed
Related Reports
Blocks :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
See the attached sample.

Run the sample.
Click on the TextField (the second element) and press enter. You will see that the button (which is set to "defaultButton") is pressed. 
Now click on the ComboBox textField like you would want to type something. Press enter and you will see that the button is not being pressed. 

Is it a normal behavior?

If it is, comment out the specified line in the sample. I've made a link between the comboBox actionProperty and the button's one.
Launch the sample, the caret should be inside the comboBox textField. Press enter et nothing happens. Now click on the second textField and click back to the comboBox textField. Press enter and then the button is triggered.

Is it a normal behavior?

Sample code: http://pastebin.com/SCcV3yDc
Comments
Changesets: http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/5174eec73c77 http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/c819c6066a09
13-05-2015

Updated webrev: http://cr.openjdk.java.net/~leifs/rt34620/webrev.02/ This adds a fix to DatePickerContent to consume the ESCAPE event after hiding the popup, to prevent the event from bubbling up. This is needed due to the fix for RT-36121, which disabled the automatic consumption.
12-05-2015

This may be possible. When you have bandwidth we can chat about my prototype - we can experiment with your suggested changes.
11-05-2015

Ideally, if the behaviors are being renovated, then maybe these controls should inherit behavior from TextField rather than trying to emulate it. A delegation model might also work.
11-05-2015

+1, although I should note that in the 'new world' of JavaFX 9, this is not going to merge in nicely with what I'm doing and we'll need to manually reapply this fix. I've added a label so that we'll keep this in mind.
11-05-2015

Fix for review: http://cr.openjdk.java.net/~leifs/rt34620/webrev.01/ This fixes the bubbling up of ENTER events (if no action listener is present), as well as ESCAPE and F10 events. The DatePicker and Editable ComboBox controls should mimic TextField behavior as much as possible. This was previously achieved by letting the ComboBoxPopupControl skin class forward key events to the embedded TextField while making sure not to cause an infinite back-and-forth triggering of events. One issue is that the code path was different depending on whether the outer (ComboBoxBase) or inner control (TextField) had the focus, making it hard to allow events not used by TextField to bubble up. Typically, the TextField would have focus if gained by mouse click, but not if gained by focus traversal. This fix disables focus for the TextField and forces all events to reach the ComboBoxBase first. Through code partly in ComboBoxBaseBehavior and partly in ComboBoxPopupControl, it can now decide which events to forward down to the TextField, and which events (like Escape and F10) to send up to the parent instead. The ENTER event is a special case, just like in TextFieldBehavior. It is first used to apply the current text as a value, and then, if no action listener is registered on the ComboBox/DatePicker, forward it upwards to the parent for bubbling.
11-05-2015

Attaching expanded test RT34620.java with optional action listeners.
11-05-2015

Interesting. Thanks.
19-08-2014

The code is not complete and has not been tested much. The idea is to eat the ENTER event and force it to go to the default button when the popup is not visible. Jonathan is likely to have a better / safer way to do this.
19-08-2014

... boolean [] showing = new boolean [1]; box.setOnShowing(e -> { showing[0] = true; }); box.setOnHiding(e -> { showing[0] = false; }); box.getEditor().addEventFilter(KeyEvent.KEY_PRESSED, e -> { if (showing[0]) return; if (e.getCode() == KeyCode.ENTER) { defaultButton.fire(); e.consume(); } }); ...
19-08-2014

Actually, I was suggesting that Jonathan do this in the implementation of ComboBox based on his last comment. I have the following work around
19-08-2014

I have not tried that solution yet, no. I can see why that might work. Thanks.
19-08-2014

Can you not add and remove the key bindings when the popup is hidden and shown? If not, Jonathan, is there a work around that you can provide for this problem?
19-08-2014

My project is also affected by this issue. It seems impossible to create a temporary work-around. We've tried adding all sorts of event listeners and filters both to the ComboBox itself and to its internal editor, but it seems the ENTER key is out of reach. If anyone has created a successful work-around for this or have any suggestions we could try out, I am all ears.
19-08-2014

I've partially resolved this issue (and added an @Ignore'd unit test to ComboBoxTest), but to fully resolve this issue requires a change to ComboBoxBehavior that at this point would require too great of a refactoring to be possible right now. In short, for the test to pass (and the above test app to work), the following two lines of ComboBoxBehavior have to be removed: 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 thing is, these two behaviors are only valid when the ComboBox popup is showing, but because they are always registered in the behavior list they are causing the event to be consumed when it shouldn't be. Ideally this would be resolved as part of RT-21598.
12-12-2013

This bug is because ComboBoxListViewSkin is consuming enter key presses to commit the changes in the textfield back into the ComboBox value property. I'm not comfortable making any changes here for 8.0, but will investigate during the 8u20 cycle.
02-12-2013

It seems to me that the default button should be activated. I have verified that this is not a regression since 2.2.
02-12-2013

package bugs; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.TextField; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class RT34620 extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { stage.setTitle("Table View Sample"); stage.setWidth(450); stage.setHeight(550); VBox hbox = new VBox(10); ComboBox<String> box = new ComboBox<>(); box.getItems().add("test"); box.setEditable(true); box.getSelectionModel().selectFirst(); TextField textfield = new TextField(); Button defaultButton = new Button("press"); defaultButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent arg0) { System.out.println("button pressed!"); } }); defaultButton.setDefaultButton(true); // Comment out this line for the second test // box.onActionProperty().bind(defaultButton.onActionProperty()); hbox.getChildren().addAll(box, textfield,defaultButton); Scene scene = new Scene(hbox); stage.setScene(scene); stage.show(); } }
02-12-2013