ADDITIONAL SYSTEM INFORMATION :
Java 12 Open JDK (but can be reproduced also with older Java 1.8), Windows 10
A DESCRIPTION OF THE PROBLEM :
A Swing based application has a top level menu containing a menu item with an accelerator (in this case Ctrl-V).
A JavaFX panel is added inside the Swing application, it contains an opened HTML page with a form control (a text field for example). Focus inside the text field from the JavaFX browser and press Ctrl-V, content is pasted there but the paste action from the top level menu is triggered as well. So the panel has failed to consume the local keyboard shortcut so the shortcut also triggers a menu item inside the main application.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create Swing JFrame containing a top level menu with an action having the accelerator "Ctrl-V".
Inside add a JavaFX frame with a browser which presents a text field.
Click inside the text field, ctrl-v pastes the content there but also triggers the top level paste action.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ctrl-v inside the inner browser's text field should not trigger an action from the main menu.
ACTUAL -
ctrl-v triggers two events, the paste in the field and the action in the main menu.
---------- BEGIN SOURCE ----------
public class Test {
public static void main(String[] args) {
JFrame fr = new JFrame();
JTextArea jta = new JTextArea();
jta.setPreferredSize(new Dimension(200, 200));
fr.getContentPane().add(jta, BorderLayout.EAST);
JFXPanel jfxPanel = new JFXPanel();
javafx.application.Platform.runLater(new Runnable() {
@Override
public void run() {
StackPane sceneLayout = new javafx.scene.layout.StackPane();
WebView browser = new javafx.scene.web.WebView();
browser.setContextMenuEnabled(false);
WebEngine webengine = browser.getEngine();
webengine.load("https://www.google.com");
sceneLayout.getChildren().add(browser);
Scene scene = new javafx.scene.Scene(sceneLayout);
jfxPanel.setScene(scene);
}
});
fr.getContentPane().add(new JScrollPane(jfxPanel), BorderLayout.CENTER);
fr.getContentPane().add(new JLabel("WORKS"), BorderLayout.WEST);
fr.setSize(800, 800);
JMenuBar jmb = new JMenuBar();
JMenu menu = new JMenu("bla");
jmb.add(menu);
AbstractAction action = new AbstractAction("PASTE") {
@Override
public void actionPerformed(ActionEvent e) {
System.err.println("THIS SHOULD NOT GET TRIGGERED ...");
new Exception().printStackTrace();
}
};
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK, false));
menu.add(action);
fr.setJMenuBar(jmb);
fr.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Overwrite the processKeyEvent in the JavaFX panel and force consume various shortcuts:
final JFXPanel jfxPanel = new JFXPanel(){
@Override
protected void processKeyEvent(KeyEvent e) {
if(e.getModifiers() == KeyEvent.CTRL_MASK && e.getKeyCode() == KeyEvent.VK_V){
//Consume it...
e.consume();
}
super.processKeyEvent(e);
}
};
FREQUENCY : always