I want to use JavaFX Menu in JFrame. I embedded it using JFXPanel and it is visible in the JFrame. BUT, the problem is, MenuItems don't respond to mouse. I can click the Menu, but not the MenuItems. If i select the MenuItem using keyboard and hit enter, it works. (MenuItems don't get highlighted when i hover mouse over them)
NOTE: I'm not having problem with Events. The click goes on component BELOW the menuItem.
Also, when the swing component is focused and then i want to click on the menu, it needs 2 clicks. First click only focuses the JFXPanel
package notepad;
import java.awt.BorderLayout;
import java.io.IOException;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class Notepad {
JFrame frame;
JFXPanel panel;
private void initSwing()
{
frame = new JFrame();
panel= new JFXPanel();
frame.setSize(1024,768);
frame.setLayout(new BorderLayout());
frame.add(panel, BorderLayout.NORTH);
Platform.runLater(() -> initFX(panel));
frame.add(new JTextArea(), BorderLayout.CENTER);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initFX(JFXPanel jfxPanel) {
try {
Parent root = FXMLLoader.load(getClass().getResource("FXBars.fxml"));
Scene scene = new Scene(root);
jfxPanel.setScene(scene);
} catch (IOException exc) {
exc.printStackTrace();
System.exit(1);
}
}
public static void main(String[] args) {
Notepad test = new Notepad();
SwingUtilities.invokeLater(() -> test.initSwing() );
}
}
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Button?>
<MenuBar xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="notepad.FXBarsController">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" onAction="#menuClose" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
FXML Controller:
package notepad;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
public class FXBarsController implements Initializable {
@FXML
private void menuClose()
{
System.out.println("CLOSE");
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}
This is how it basically works.
Click File -> Close, check the console output.
The requestFocus() method call, in the processMouseEvent() method of the JFXPanel class, is sent to the EventQueue and handled asynchronously and thus the click is not considered (due to lack of focus in the FX component).
To cascade the click to the underlying menu item, the same mouse click should be fired again when the FXPanel comes into focus.
To do it,
Override the processMouseEvent(MouseEvent e) method as below.
Replace JFXPanel() class by your new CustomJFXPanel() class.
This is fixed in JDK9.
(Collected from another source)