JavaFX:FXML中导入类的ClassNotFoundException

时间:2016-02-06 03:49:01

标签: javafx textfield fxml titled-border

我正在尝试创建一个文字字段,其中标题嵌入字段边框中,如:

enter image description here

根据发布的解决方案here,我在TitledBorder.java目录中创建了一个名为src>main>java的.java文件。我的FXML位于src>main>resources目录中,我已添加:

<?import TitledBorder?>位于顶部,它没有显示如下错误: enter image description here

然后我将此代码添加到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&gt; main&gt; java中的类中启动我的main方法,但它在.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)

我不确定为什么它会引用&#34; / target / classes /..."而不是&#34; / src / main / java /..."。

这是我发现的唯一一个FXML示例,所以我很困惑为什么我在编译时遇到错误,但之前没有显示任何错误?删除对TitledBorder的所有引用都允许我的所有代码正常运行/编译。由于它在src包中,我在FXML中使用此代码连接w / controller fx:controller="loadController">。 CSS也正确添加。

思想?

1 个答案:

答案 0 :(得分:1)

该行

<?import TitledBorder?>

表示您将TitledBorder.java文件放到默认包中(即此文件的源代码中没有包声明)。但是FXMLLoader的源代码会检查FXML文件中的导入并在下面的loadType(...)中拆分包路径名和类名,以便稍后使用loadTypeForPackage()加载导入的类:

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('.', '$'));
}

导入的类名称为“TitledBorder”,因此i方法中第1行的变量loadType将被评估为name.indexOf('.') = -1,并将ClassNotFoundException引入下一行代码。

通常使用默认包是不好的做法。将TitledBorder.java放入某个包并将其导入为

<?import my.some.package.TitledBorder?>