-
Bug
-
Resolution: Fixed
-
P3
-
jfx13, 8, 9, 10.0.1
happens if the actionHandler is registered via addEventHandler(ActionEvent), does not happen if registered via setOnAction
To reproduce, compile and run the example
- focus the textField
- press Enter
- expected: neither accelerator nor keyHandler on parent must execute
- actual: both execute
Example code:
public class TextFieldActionHandler extends Application {
private TextField textField;
private Parent createContent() {
textField = new TextField("added handler: ");
textField.addEventHandler(ActionEvent.ACTION, e -> {
System.out.println("in added: " + e);
e.consume();
});
VBox pane = new VBox(10, textField);
pane.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
System.out.println("in parent: " + e);
});
return pane;
}
@Override
public void start(Stage stage) throws Exception {
Scene scene = new Scene(createContent());
scene.getAccelerators().put(KeyCombination.keyCombination("ENTER"),
() -> System.out.println("in accelerator"));
stage.setScene(scene);
// stage.setTitle(FXUtils.version());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I think the reason for the misbehaviour is in TextFieldBehaviour.fire:
@Override protected void fire(KeyEvent event) {
TextField textField = getNode();
EventHandler<ActionEvent> onAction = textField.getOnAction();
ActionEvent actionEvent = new ActionEvent(textField, null);
textField.commitValue();
textField.fireEvent(actionEvent);
// ---> intention not met
if (onAction == null && !actionEvent.isConsumed()) {
forwardToParent(event);
}
}
the intention seems to be to not forward if either the field has an onAction handler or any other handler consumed the event. The latter never happens, because node.fireEvent (ultimately) sends around copies of an event if target != node, that is handlers consuming the event do so on a copy, not on the original.
A tentative solution might be to construct the actionEvent with both source and target set the field (working but not formally tested), that's what menuItem does in its fire method.
set priority to p3 because this seems to play a role in other recently reported issues, like JDK-8207385 (acts as exposer of the bug in MenuItemContaine) and maybeJDK-8207759 (though that's slightly different, registering a keyhandler directly)
To reproduce, compile and run the example
- focus the textField
- press Enter
- expected: neither accelerator nor keyHandler on parent must execute
- actual: both execute
Example code:
public class TextFieldActionHandler extends Application {
private TextField textField;
private Parent createContent() {
textField = new TextField("added handler: ");
textField.addEventHandler(ActionEvent.ACTION, e -> {
System.out.println("in added: " + e);
e.consume();
});
VBox pane = new VBox(10, textField);
pane.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
System.out.println("in parent: " + e);
});
return pane;
}
@Override
public void start(Stage stage) throws Exception {
Scene scene = new Scene(createContent());
scene.getAccelerators().put(KeyCombination.keyCombination("ENTER"),
() -> System.out.println("in accelerator"));
stage.setScene(scene);
// stage.setTitle(FXUtils.version());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I think the reason for the misbehaviour is in TextFieldBehaviour.fire:
@Override protected void fire(KeyEvent event) {
TextField textField = getNode();
EventHandler<ActionEvent> onAction = textField.getOnAction();
ActionEvent actionEvent = new ActionEvent(textField, null);
textField.commitValue();
textField.fireEvent(actionEvent);
// ---> intention not met
if (onAction == null && !actionEvent.isConsumed()) {
forwardToParent(event);
}
}
the intention seems to be to not forward if either the field has an onAction handler or any other handler consumed the event. The latter never happens, because node.fireEvent (ultimately) sends around copies of an event if target != node, that is handlers consuming the event do so on a copy, not on the original.
A tentative solution might be to construct the actionEvent with both source and target set the field (working but not formally tested), that's what menuItem does in its fire method.
set priority to p3 because this seems to play a role in other recently reported issues, like JDK-8207385 (acts as exposer of the bug in MenuItemContaine) and maybe
- relates to
-
JDK-8207385 CustomMenuItem in MenuButton triggers wrong EventHandler
- Open
-
JDK-8207759 VK_ENTER not consumed by TextField when default Button exists
- Resolved
-
JDK-8229467 Fired ActionEvent not consumed if (unrelated!) EventFilter in dispatch chain
- Open
- links to