JavaFX:FXML 中导入的 class 的 ClassNotFoundException
JavaFX: ClassNotFoundException for imported class in FXML
我正在尝试创建一个标题嵌入字段边框的文本字段,例如:
按照 here 发布的解决方案,我在 src>main>java
目录中创建了一个名为 TitledBorder.java
的 .java 文件。我的 FXML 在 src>main>resources
目录中,我添加了:
<?import TitledBorder?>
在顶部,它没有显示如下错误:
然后我将此代码添加到 FXML
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TitledBorder title="Email" >
<TextField fx:id="emailField" prefHeight="44.0" prefWidth="143.0" />
</TitledBorder>
</children>
</HBox>
也没有显示错误。然后我启动我的主要方法,它也在 src>main>java 中的 class 中,但它在 .fxml 中出现错误,说 javafx.fxml.LoadException:
/C:/Users/ME/Documents/Automation/target/classes/demofxml.fxml
和
Caused by: java.lang.ClassNotFoundException
at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2899)
我不确定为什么它引用“/target/classes/...”而不是“/src/main/java/...”。
这是我找到的唯一一个 FXML 示例,所以我很困惑为什么我在编译时遇到错误,但之前没有显示任何错误?删除对 TitledBorder
的所有引用允许我的所有代码正确地 function/compile。由于它在 src 包中,我在 FXML 中使用此代码来连接控制器 fx:controller="loadController">
。 CSS 也添加正确。
想法?
行
<?import TitledBorder?>
意味着您将 TitledBorder.java
文件放入默认包(即该文件的源代码中没有包声明)。但是 FXMLLoader
的源代码检查 FXML 文件中的导入,并在下面的 loadType(...)
中拆分包路径名和 class 名称,以便稍后加载导入的 class 和 [=16] =]:
private Class<?> loadType(String name, boolean cache) throws ClassNotFoundException {
int i = name.indexOf('.');
int n = name.length();
while (i != -1
&& i < n
&& Character.isLowerCase(name.charAt(i + 1))) {
i = name.indexOf('.', i + 1);
}
if (i == -1 || i == n) {
throw new ClassNotFoundException();
}
String packageName = name.substring(0, i);
String className = name.substring(i + 1);
Class<?> type = loadTypeForPackage(packageName, className);
if (cache) {
classes.put(className, type);
}
return type;
}
// TODO Rename to loadType() when deprecated static version is removed
private Class<?> loadTypeForPackage(String packageName, String className) throws ClassNotFoundException {
return getClassLoader().loadClass(packageName + "." + className.replace('.', '$'));
}
导入的class名字是"TitledBorder"所以loadType
方法中第1行的变量i
将被计算为name.indexOf('.') = -1
,并且将在下一行代码中抛出 ClassNotFoundException
。
通常使用默认包是不好的做法。将 TitledBorder.java 放入某个包中并将其导入为
<?import my.some.package.TitledBorder?>
我正在尝试创建一个标题嵌入字段边框的文本字段,例如:
按照 here 发布的解决方案,我在 src>main>java
目录中创建了一个名为 TitledBorder.java
的 .java 文件。我的 FXML 在 src>main>resources
目录中,我添加了:
<?import TitledBorder?>
在顶部,它没有显示如下错误:
然后我将此代码添加到 FXML
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TitledBorder title="Email" >
<TextField fx:id="emailField" prefHeight="44.0" prefWidth="143.0" />
</TitledBorder>
</children>
</HBox>
也没有显示错误。然后我启动我的主要方法,它也在 src>main>java 中的 class 中,但它在 .fxml 中出现错误,说 javafx.fxml.LoadException:
/C:/Users/ME/Documents/Automation/target/classes/demofxml.fxml
和
Caused by: java.lang.ClassNotFoundException
at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2899)
我不确定为什么它引用“/target/classes/...”而不是“/src/main/java/...”。
这是我找到的唯一一个 FXML 示例,所以我很困惑为什么我在编译时遇到错误,但之前没有显示任何错误?删除对 TitledBorder
的所有引用允许我的所有代码正确地 function/compile。由于它在 src 包中,我在 FXML 中使用此代码来连接控制器 fx:controller="loadController">
。 CSS 也添加正确。
想法?
行
<?import TitledBorder?>
意味着您将 TitledBorder.java
文件放入默认包(即该文件的源代码中没有包声明)。但是 FXMLLoader
的源代码检查 FXML 文件中的导入,并在下面的 loadType(...)
中拆分包路径名和 class 名称,以便稍后加载导入的 class 和 [=16] =]:
private Class<?> loadType(String name, boolean cache) throws ClassNotFoundException {
int i = name.indexOf('.');
int n = name.length();
while (i != -1
&& i < n
&& Character.isLowerCase(name.charAt(i + 1))) {
i = name.indexOf('.', i + 1);
}
if (i == -1 || i == n) {
throw new ClassNotFoundException();
}
String packageName = name.substring(0, i);
String className = name.substring(i + 1);
Class<?> type = loadTypeForPackage(packageName, className);
if (cache) {
classes.put(className, type);
}
return type;
}
// TODO Rename to loadType() when deprecated static version is removed
private Class<?> loadTypeForPackage(String packageName, String className) throws ClassNotFoundException {
return getClassLoader().loadClass(packageName + "." + className.replace('.', '$'));
}
导入的class名字是"TitledBorder"所以loadType
方法中第1行的变量i
将被计算为name.indexOf('.') = -1
,并且将在下一行代码中抛出 ClassNotFoundException
。
通常使用默认包是不好的做法。将 TitledBorder.java 放入某个包中并将其导入为
<?import my.some.package.TitledBorder?>