解析onAction ='#initialize',事件处理程序不在命名空间中,或者脚本中有错误

时间:2017-02-27 22:29:19

标签: java javafx

这是我在javafx的第一个程序。我刚刚在scene Builder的帮助下创建了一个AnchorPane。我想要的是当我们点击AncherPane中的任何位置时,它应该显示该像素的坐标点。 这是控制器类

package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
public class AxisController implements Initializable{

    @FXML
    private AnchorPane anchr;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
         assert anchr != null : "fx:id=\"anchr\" was not injected: check your FXML file 'AxisFxml.fxml'.";
         anchr.setOnMouseClicked(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                System.out.println(event.getX());
                System.out.println(event.getY());
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>


<AnchorPane fx:id="anchr" onMouseClicked="#initialize" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.AxisController">
    <!-- TODO Add Nodes -->
</AnchorPane>

错误消息

javafx.fxml.LoadException: Error resolving onAction='#initialize', either the event handler is not in the Namespace or there is an error in the script.
/home/xyz/workspace/AxisExample/bin/application/AxisFxml.fxml:9

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2597)
at javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$Element.processEventHandlerAttributes(FXMLLoader.java:610)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:770)
at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2823)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2532)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at application.AxisMain.start(AxisMain.java:16)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
at java.lang.Thread.run(Thread.java:745)

2 个答案:

答案 0 :(得分:1)

你在这里有一些误解。

将您设置为“事件处理程序属性”值的名称的方法(如AcceptsReturn="True")是在这些事件发生时将调用的方法。它们应该只包含您想要执行的代码,在这种情况下,单击鼠标。您不应该在这些方法中注册事件处理程序。 (这意味着:“单击锚点窗格时,为单击的锚点窗格注册事件处理程序”,这显然不是您想要的。)

因此,在FXML中注册为事件处理程序方法的方法应该采用正确事件类型的单个参数。 (如果您不需要事件对象,也可以不带参数 - 这是一种常见的情况。)

您得到的错误是因为您声明为事件处理程序(onMouseClicked,其角色完全不同)的方法具有错误的签名:它采用错误的数字(和类型)参数。

其次,在加载FXML的过程中调用initialize()方法,该方法可以不带参数声明,也可以使用initialize()URL类型的参数声明。 。在注入了所有ResourceBundle - 注释字段之后,但在从调用@FXML的调用返回UI的根之前,会发生这种情况。因此,在此处访问FXMLLoader.load() - 带注释的字段是安全的:它们将被正确初始化。

因此注册事件处理程序有两种不同的方式。

<强>要么

在控制器中定义一个方法,并在FXML文件中引用它:

@FXML

然后

<AnchorPane fx:id="anchr" onMouseClicked="#handleClick" ... fx:controller="application.AxisController">
    <!-- TODO Add Nodes -->
</AnchorPane>

从FXML文件中删除public class AxisController implements Initializable{ @FXML private AnchorPane anchr; @Override public void initialize(URL location, ResourceBundle resources) { assert anchr != null : "fx:id=\"anchr\" was not injected: check your FXML file 'AxisFxml.fxml'."; } @FXML private void handleClick(MouseEvent event) { System.out.println(event.getX()); System.out.println(event.getY()); } } 属性,并在onMouseClicked方法中注册事件处理程序。 (所以控制器就像你拥有它一样。)

答案 1 :(得分:0)

我认为问题在于您的FXML上的anchorPane,您是否已为FXP上的clickPane分配了一个函数?如果你有,你可以通过像初始化变量那样设置该事件的功能,例如:

@FXML
private void restartExited() {
    exitedTransition(0, "circle", null, buttonCirc);
}

你可以告诉FXML中的anchorPane在单击它时执行此功能或者例如mouseOver,你不需要在控制器和FXML中设置它。

或者在你的情况下:

@FXML
private void initialize() {
    anchr.setOnMouseReleased(new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {
            System.out.println(event.getX());
            System.out.println(event.getY());
        }
    });
}

或者您可以删除FXML中AnchorPane上onClick的引用并使用您当前的代码。

修改

我可以问你在哪里定义舞台和FXML加载到舞台,这是你的应用程序的舞台初始化程序还是FXML的控制器?