A DESCRIPTION OF THE PROBLEM :
I have a MenuButton containing several MenuItems and one CustomMenuItem containing a Textfield. The TextField has an EventHandler added (not set), the other MenuItems also have an EventHandler.
When I select the TextField and hit Enter, the TextField's EventHandler gets triggered, BUT ALSO the one of the item above.
This behaviour does NOT occur, if I use setOnAction(.) to add the TextField's Handler instead of (or in addition to) addEventHandler(.).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In the code below, a GUI containing just a button gets started.
Click inside the Textfield to place the cursor, then hit enter.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
TextField's listener gets triggered and prints "ADD: <Text you typed> ..."
ACTUAL -
TextField's listener gets triggered and prints "ADD: <Text you typed> ..."
AND above Button's listener gets triggered and prints "World! ...". This should only happen, if I click "World".
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class CustomMenuTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
MenuButton menu = new MenuButton("Fancy Menu...");
MenuItem hello = new MenuItem("Hello");
hello.setOnAction(event -> System.out.println("Hello | " + event.getSource()));
MenuItem world = new MenuItem("World!");
world.setOnAction(event -> System.out.println("World! | " + event.getSource()));
/*
Set the cursor into the TextField, maybe type something, and hit enter.
--> Expected: "ADD: <Text you typed> ..."
--> Actual: "ADD: <Text you typed> ..." AND "World! ..." - so the button above gets triggered as well.
If I activate listener (II) or (III), everything works fine - even the empty action in (III) does is job, but this is ugly...
(And I can't use (II), because I need (I).
*/
TextField textField = new TextField();
/* I */ textField.addEventHandler(ActionEvent.ACTION,
event -> System.out.println("ADD: " + textField.getText() + " | " + event.getSource()));
/* II */ // textField.setOnAction(event -> System.out.println("SET: " + textField.getText() + " | " + event.getSource()));
/* III */ // textField.setOnAction(__ -> {/* do nothing */});
CustomMenuItem custom = new CustomMenuItem(textField, false);
menu.getItems().addAll(hello, world, custom);
primaryStage.setScene(new Scene(menu));
primaryStage.show();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
textField.setOnAction(__ -> {/* do nothing */});
this way, everything works fine and only "ADD: ..." gets printed.
FREQUENCY : always
I have a MenuButton containing several MenuItems and one CustomMenuItem containing a Textfield. The TextField has an EventHandler added (not set), the other MenuItems also have an EventHandler.
When I select the TextField and hit Enter, the TextField's EventHandler gets triggered, BUT ALSO the one of the item above.
This behaviour does NOT occur, if I use setOnAction(.) to add the TextField's Handler instead of (or in addition to) addEventHandler(.).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In the code below, a GUI containing just a button gets started.
Click inside the Textfield to place the cursor, then hit enter.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
TextField's listener gets triggered and prints "ADD: <Text you typed> ..."
ACTUAL -
TextField's listener gets triggered and prints "ADD: <Text you typed> ..."
AND above Button's listener gets triggered and prints "World! ...". This should only happen, if I click "World".
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class CustomMenuTest extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
MenuButton menu = new MenuButton("Fancy Menu...");
MenuItem hello = new MenuItem("Hello");
hello.setOnAction(event -> System.out.println("Hello | " + event.getSource()));
MenuItem world = new MenuItem("World!");
world.setOnAction(event -> System.out.println("World! | " + event.getSource()));
/*
Set the cursor into the TextField, maybe type something, and hit enter.
--> Expected: "ADD: <Text you typed> ..."
--> Actual: "ADD: <Text you typed> ..." AND "World! ..." - so the button above gets triggered as well.
If I activate listener (II) or (III), everything works fine - even the empty action in (III) does is job, but this is ugly...
(And I can't use (II), because I need (I).
*/
TextField textField = new TextField();
/* I */ textField.addEventHandler(ActionEvent.ACTION,
event -> System.out.println("ADD: " + textField.getText() + " | " + event.getSource()));
/* II */ // textField.setOnAction(event -> System.out.println("SET: " + textField.getText() + " | " + event.getSource()));
/* III */ // textField.setOnAction(__ -> {/* do nothing */});
CustomMenuItem custom = new CustomMenuItem(textField, false);
menu.getItems().addAll(hello, world, custom);
primaryStage.setScene(new Scene(menu));
primaryStage.show();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
textField.setOnAction(__ -> {/* do nothing */});
this way, everything works fine and only "ADD: ..." gets printed.
FREQUENCY : always
- relates to
-
JDK-8207774 TextField: must not forward ENTER if actionHandler consumed the actionEvent
- Resolved