我有一个JavaFX应用程序。我有一个按钮,当单击时调用一个动作并加载另一个fxml文件。这非常有效。
我决定在应用程序的菜单中放置此功能。
因此,我创建了一个菜单,并在“场景”构建器中添加了“菜单项”。我正确分配'On Action'事件,就像我用其他按钮一样。但是,当我点击时出现以下错误:
Glass detected outstanding Java exception at -[GlassViewDelegate sendJavaMouseEvent:]:src/com/sun/mat/ui/GlassViewDelegate.m:541
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
Caused by: java.lang.ClassCastException: javafx.scene.control.MenuItem cannot be cast to javafx.scene.Node
at plataformavalidezpredictiva.MainController.handleAction(MainController.java:60)
... 38 more
这是处理程序的代码。再次,这适用于我放置在UI中的按钮,并且不能从菜单栏中运行:
public void handleAction(ActionEvent event) throws Exception{
Node node = (Node)event.getSource();
Stage stage=(Stage) node.getScene().getWindow();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/GUIFile.fxml"));
Parent root = (Parent)fxmlLoader.load();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
似乎给我的问题的一句话是:
Node node = (Node)event.getSource();
有什么想法吗?
编辑:我在这里看到帖子Unable to get Scene from MenuItem in JavaFX,但这对我不起作用,因为它没有找到菜单栏的getScene()方法。
答案 0 :(得分:3)
将一些节点(例如MenuBar
,但它实际上可以是同一场景中的任何节点)注入控制器。在该节点上调用getScene()
,在场景上调用getWindow()
。
E.g。
Main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="exitfrommenu.MainController">
<top>
<MenuBar fx:id="menuBar">
<Menu text="File">
<MenuItem text="Exit" onAction="#exit"/>
</Menu>
</MenuBar>
</top>
</BorderPane>
MainController.java
package exitfrommenu;
import javafx.fxml.FXML;
import javafx.scene.control.MenuBar;
public class MainController {
@FXML
private MenuBar menuBar ;
@FXML
private void exit() {
Stage stage = (Stage) menuBar.getScene().getWindow() ;
// This exits the application, but of course you can do anything
// you like with the stage, such as showing a new scene in it:
stage.hide();
}
}
Main.java
package exitfrommenu;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}