自定义FXML组件(带控制器)未出现在SceneBuilder的“导入jar”对话框

时间:2016-04-05 14:36:12

标签: java javafx custom-controls fxml

我在创建自定义组件并导入它时遵循this。但是,在单击jar文件后进入“导入”对话框时,它不会出现。当我注释掉用于构造函数的教程的代码时,它再次出现。但是,我用于制作自定义子组件的子组件都没有出现。为什么以及如何解决?

此外,我正在使用VBox而不是AnchorPane(如教程中所示)。

教程中的构造函数代码:

public CommodityImageLabel() {
    FXMLLoader fxmlLoader = new FXMLLoader(
            getClass().getResource("/fxml/CommodityImageLabel.fxml"));

    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);

    try {
        fxmlLoader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }

}

我自己的示例构造函数的代码:

public While() {
    FXMLLoader fxmlLoader = new FXMLLoader(
            getClass().getResource("BlocksFXML/While.fxml"));


    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);

    try {
        fxmlLoader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }
}

Edit1:我尝试评论部分代码,当我注释掉try-catch部分时,它会使组件出现在对话框中,但它仍然没有显示子组件。

编辑2:自定义组件基本上是一个包含带有Label和TextField的Hbox的VBox。 Here是它看起来像是什么样的结果,当它成功导入时没有try-catch部分。

1 个答案:

答案 0 :(得分:1)

我使用此处的信息解决了这个问题:

http://www.cuchazinteractive.com/blog/custom-javafx-controls-and-scene-builder

总结:

  1. 创建一个FXML文件和一个扩展根节点的Java类(我赋予它们相同的名称)
  2. 将FXML文件更改为以fx:root为基本节点。 (没有这个就行不通)
  3. 删除fx:controller属性(没有此属性将无效)
  4. 编译并将jar添加到场景构建器
  5. 但是,我发现如果您的自定义控件依赖于其他库中的控件,即使在场景构建器中加载了其他库,它也会失败。

    以下是最低工作示例

    FXML:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.layout.AnchorPane?>
    
    
    <fx:root id="AnchorPane" prefHeight="73.0" prefWidth="112.0" type="AnchorPane" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111">
       <children>
          <Button layoutX="25.0" layoutY="28.0" mnemonicParsing="false" text="Button" />
       </children>
    </fx:root>
    

    爪哇:

    package my.amazing.controls;
    
    import java.io.IOException;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.layout.AnchorPane;
    
    public class TestControl extends AnchorPane {
    
    
        public TestControl() throws IOException {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("TestControl.fxml"));
            loader.setRoot(this);
            loader.setController(this);
            loader.load();
        }
    
        @FXML
        public void initialize() {
        }
    }