SceneBuilder 不会加载通过 FXML 引用另一个自定义控件的自定义控件

2024-04-19

我创建了一个基于 FXML 的自定义控件,该控件又引用另一个基于 FXML 的自定义控件。当我在 Eclipse 中加载它们时,它们都工作得很好,但是当我尝试将它们导入到 SceneBuilder 中时,外部控件(包含另一个控件的一个)无法正确导入。

这是一个非常简化的示例:

小部件.java:

package example;

import java.util.logging.Level;
import java.util.logging.Logger;

import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;

public class Widget extends Pane{

    public Widget() {
        
        Logger logger = Logger.getLogger(Widget.class.getName());

        try {
            FXMLLoader loader= new FXMLLoader(Widget.class.getResource("Widget.fxml"));
            Pane pane = loader.load();
            this.getChildren().add(pane);
        }
        catch(Exception e) {
            logger.log(Level.SEVERE, "Failed to load Widget", e);
        }
    }
}

小部件.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.control.Label?>
<?import example.SubWidget?>

<FlowPane  xmlns:fx="http://javafx.com/fxml/1" >
   <children>
       <Label text="Widget"/>
      <SubWidget></SubWidget>
   </children>
</FlowPane>

SubWidget.java:

package example;

import java.util.logging.Level;
import java.util.logging.Logger;

import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;

public class SubWidget extends Pane{

    public SubWidget() {
        
        Logger logger = Logger.getLogger(SubWidget.class.getName());

        try {
            FXMLLoader loader= new FXMLLoader(SubWidget.class.getResource("SubWidget.fxml"));
            Pane pane = loader.load();
       
            this.getChildren().add(pane);
        }
        catch(Exception e) {
            logger.log(Level.SEVERE, "Failed to load SubWidget", e);
        }
    }
}

子Widget.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.control.Label?>

<FlowPane  xmlns:fx="http://javafx.com/fxml/1" >
   <children>
       <Label text="Subwidget"/>
   </children>
</FlowPane>

我将它们导出到 jar 并尝试通过 SceneBuilder 的 jar 导入功能导入它们。当我这样做时,SubWidget被导入并且看起来很好。Widget也会显示为控件,但它会完全是空的。

当我检查日志文件时,我发现这是由于 FXML 加载程序无法找到 SubWidget 类文件:

Oct 29, 2020 4:28:30 PM example.Widget <init>
SEVERE: Failed to load Widget
javafx.fxml.LoadException: 
file:/C:/Users/nate/AppData/Roaming/Scene%20Builder/Library/TestFxControl.jar!/example/Widget.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2848)
    at javafx.fxml.FXMLLoader.processImport(FXMLLoader.java:2692)
    at javafx.fxml.FXMLLoader.processProcessingInstruction(FXMLLoader.java:2661)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2517)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at example.Widget.<init>(Widget.java:27)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at java.lang.Class.newInstance(Unknown Source)
    at sun.reflect.misc.ReflectUtil.newInstance(Unknown Source)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1009)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2425)
    at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.instantiateWithFXMLLoader(JarExplorer.java:110)
    at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.exploreEntry(JarExplorer.java:160)
    at com.oracle.javafx.scenebuilder.kit.library.util.JarExplorer.explore(JarExplorer.java:70)
    at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.exploreAndUpdateLibrary(LibraryFolderWatcher.java:325)
    at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.runDiscovery(LibraryFolderWatcher.java:138)
    at com.oracle.javafx.scenebuilder.kit.library.user.LibraryFolderWatcher.run(LibraryFolderWatcher.java:92)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: example.SubWidget
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2916)
    at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2905)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2846)
    ... 24 more

在我看来,FXML 加载器使用的类加载器不包含其他自定义组件,这很奇怪,因为如果我在Widget类并做到了:

public class Widget extends FlowPane{

    public Widget() {
        
        this.getChildren().addAll(new Label("Widget"), new SubWidget());
    }
}

然后它在 SceneBuilder 中加载得很好。所以看来ClassLoader实际上加载了Widget以及那个FXMLLoader用途不一样。

这可能与这个悬而未决的问题 https://stackoverflow.com/questions/52117662/javafx-scenebuilder-classnotfoundexception-when-loading-custom-control,尽管它们并不完全相同。


我遇到了同样的问题,并创建了一个解决方案,虽然不太漂亮但有效。

创建一个 jar,其中包含无法加载到场景生成器中的控件的空白类,例如:

package com.junglefinance.gui.controls;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
public class CategoryTextField extends TextField {
    @FXML private TextField textField;
    public CategoryTextField() {
    }
 }

确保该包与目标控件的包匹配。

将此 jar 加载到场景生成器中。这将允许场景生成器生成可加载到程序中的 FXML。加载时,它将拾取您的目标控件,而不是导入时的虚拟控件(在本例中)

<?import com.junglefinance.gui.controls.CategoryTextField?>

注意包装。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SceneBuilder 不会加载通过 FXML 引用另一个自定义控件的自定义控件 的相关文章

  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • Java EE:如何获取我的应用程序的 URL?

    在 Java EE 中 如何动态检索应用程序的完整 URL 例如 如果 URL 是 localhost 8080 myapplication 我想要一个可以简单地将其作为字符串或其他形式返回给我的方法 我正在运行 GlassFish 作为应
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s

随机推荐