我希望有人可以向我解释我做错了什么,或者如果这个答案以前答案指向我的答案(我一直在附近寻找2天寻找答案)。为什么我的JavaFX控制器没有加载?
我正在尝试创建一个启动JavaFX GUI的演示应用程序。当我的应用程序已准备好启动GUI(应用程序必须首先照顾的东西在后台),我称之为:
Application.launch(StarFXDemo.class, "");
这里是StarFXDemo.java:
package standalonedemo;
import java.io.IOException;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class StarFXDemo extends Application
{
@Override
public void start(Stage stage) throws Exception
{
Parent root = null;
try
{
root = FXMLLoader.load(getClass().getResource("StarFXDemoDoc.fxml"));
} catch (IOException ioe)
{
ioe.printStackTrace(System.out);
}
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
StarFXDemoDoc.fxml在JAR文件中&与StarFXDemo是相同的包(而不是在另一个包或子包中)。所以
getClass().getResource("/standalonedemo/resources/StarFXDemoDoc.fxml")
回来的URL的文件。
StarFXDemoDoc.fxml是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<?import standalonedemo.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" text="FX Sim Demo"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="standalonedemo.StarFXDemoDocController">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<VBox prefHeight="85.0" prefWidth="322.0" spacing="5.0" style="-fx-background-color: coral;">
<children>
<Label text="Sim Title" />
<TextField fx:id="SimNameField" onMouseDragExited="#setSimulationName" />
</children>
<padding>
<Insets left="25.0" top="15.0" />
</padding>
</VBox>
<Button fx:id="BuildSphereButton" layoutX="14.0" layoutY="100.0" mnemonicParsing="false" onAction="#buildSphereAction" text="Build Sphere" />
</children></AnchorPane>
</content>
</TitledPane>
而且StarFXDemoDocController.java是这样的:
package standalonedemo;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
public class StarFXDemoDocController implements Initializable
{
@FXML
private TextField SimNameField;
@FXML
private Button BuildSphereButton;
/**
* RequiredConstructor
*/
public StarFXDemoDocController() {}
@Override
public void initialize(URL url, ResourceBundle rb)
{
}
@FXML
private void buildSphereAction(ActionEvent event)
{
}
@FXML
private void setSimulationName()
{
}
}
没有什么真正的方法,但因为我只是想获得GUI来出现在这个时候。我有空的构造函数,以及具有fx:id标记(以及它们相应的方法)的GUI元素上的@FXML标记。
当我运行该程序,在点我叫
FXMLLoader.load(getClass().getResource("/standalonedemo/resources/StarFXDemoDoc.fxml"));
它抛出以下异常(此异常不再是相关的,看下面的异常):
我假设我有格式错误的东西,但我不知道它是什么。
任何人都可以帮助我吗?
编辑/ UPDATE:
按James_D的意见(谢谢你,詹姆斯,很明显,我已经在那了这样一直盯着太久......),我在我的控制器固定在明显的错误,并提出SimNameField一个TextField ,而不是标签(并更新了上面的代码块来反映这一点)。我还将异常处理更改为使用printStackTrace。这些变化,现在让我下面的堆栈跟踪:
javafx.fxml.LoadException: file:<properPathTo>/StandAloneDemo/dist/StandAloneDemo.jar!/standalonedemo/resources/StarFXDemoDoc.fxml:11
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:922)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
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 standalonedemo.StarFXDemo.start(StarFXDemo.java:35)
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)
Caused by: java.lang.ClassNotFoundException: standalonedemo.StarFXDemoDocController starting from SystemClassLoader[55 modules] with possible defining loaders null and declared parents [[email protected], [email protected][org.netbeans.api.annotations.common], [email protected][org.openide.awt], [email protected][org.netbeans.api.progress], [email protected][org.netbeans.swing.plaf], [email protected][org.openide.dialogs], [email protected][org.openide.nodes], [email protected][org.openide.windows], [email protected][org.netbeans.swing.tabcontrol], [email protected][org.netbeans.swing.outline], ...40 more]
at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:224)
at org.netbeans.ModuleManager$SystemClassLoader.loadClass(ModuleManager.java:722)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:920)
... 22 more
Caused by: java.lang.ClassNotFoundException: standalonedemo.StarFXDemoDocController
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:222)
... 25 more
所以我看到ClassNotFoundException的,这让我开始寻找我的控制器类多一些,而且我注意到,场景生成器几乎已经决定,我的文本字段没有按不存在作为标记的项目(当我将simNameField的fx:id分配给Scene Builder中的TextField时,我得到“No injectable field ...”警告,并右键单击仅用于控件的fx:id字段显示buildSphereButton标签)。因此,我从控制器类中删除了simNameField,右键单击NetBeans中的FXML文件,并将其告知Make Controller。它使用正确的fx:id和@FXML标签添加了TextField。场景生成器仍然认为这是一个没有可注射字段的fx:id。
所以我明显有一些FXML和控制器之间的断开方式,但我不知道它可能是什么?
UPDATE2:
拿出第一堆栈跟踪,因为它已不再是相关的和更新的几行代码(如添加导入该包到FXML)。
一直在玩它。如果我删除了控制器引用,则GUI将按预期启动(这样我们就知道FXML文件正在加载)。如果我实例化一个Controller对象(在我调用FXMLLoader.load(< ...>)之前),它按预期方式实例化,并且我可以通过NetBeans调试器验证它是否为空,所以我知道该控制器类已编译,并在班级路径上。
那么为什么FXMLLoader不能找到它呢?我应该使用替代方法来加载它吗?我想过只是在代码中创建控制器对象并设置它,但是当涉及到fx:controller语句时,这似乎让NetBeans烦恼(即,如果FXML中的元素需要控制器,那么语句不在那里,NetBeans将其标记为不正确)。
这看起来不像完整的堆栈跟踪。通常在那里有“由...引起”的部分(通常有不同的格式等) –
实际上,你没有发布的“由...引起”的部分应该相当清楚地表明你正试图给一个“TextField”分配一个'Label' ... –
这就是我从IOException获得的所有堆栈跟踪(我将循环添加到catch块以获取完整的堆栈跟踪)。 是否有另一个例外,我应该一直在寻找,会给出更多? – sngillis