我想在 JFrame 中使用 JavaFX 菜单。我使用 JFXPanel 嵌入它,它在 JFrame 中可见。但是,问题是,菜单项不响应鼠标。我可以单击菜单,但不能单击菜单项。 如果我使用键盘选择菜单项并按 Enter 键,它就会起作用。 (当我将鼠标悬停在菜单项上时,菜单项不会突出显示)
注意:我的 Activity 没有问题。单击菜单项下方的组件。
另外,当 swing 组件获得焦点然后我想单击菜单时,需要单击 2 次。第一次单击仅聚焦 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 文件:
<?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) {
}
}
最佳答案
JFXPanel 类的 processMouseEvent() 方法中的 requestFocus() 方法调用被发送到 EventQueue 并异步处理,因此不考虑单击(由于 FX 组件中缺乏焦点)。
要将单击级联到底层菜单项,当 FXPanel 成为焦点时,应再次触发相同的鼠标单击。
要做到这一点,
- 扩展 JFXPanel 类并创建您自己的 CustomeJFXPanel(CustomJFXPanel 扩展了 JFXPanel)。
重写 processMouseEvent(MouseEvent e) 方法,如下所示。
@Override protected void processMouseEvent(MouseEvent e) { try { if ((e.getID() == MouseEvent.MOUSE_PRESSED)&& (e.getButton() == MouseEvent.BUTTON1)) { if (!hasFocus()) { requestFocus(); AppContext context = SunToolkit.targetToAppContext(this); if (context != null) { SunToolkit.postEvent(context, e); } } } } catch (Exception ex) { //DO SOMETHING } super.processMouseEvent(e); }
将 JFXPanel() 类替换为新的 CustomJFXPanel() 类。
这在 JDK9 中已修复。
(从其他来源收集)
关于JFrame 中的 JavaFX 菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27210522/