如何为 java 中已创建的新组件创建 FXML 文件而不是将其添加到场景构建器?

How to create an FXML file for an already created new component in java than add it to scene builder?

我是 javaFX 的新手。我在 java 中创建了一个自定义搜索框(扩展了 TextField),检查图像:

我用测试 class 测试了它,它工作正常。

我现在想知道是否可以创建其 FXML 文件而不是将此组件添加到场景生成器?怎么做 ?提前致谢。

如何将组件从 JAR 导入到 SceneBuilder

您可以将组件放入 Jar 中,然后将其导入到 SceneBuilder 中。您无需为组件创建 FXML 文件即可将其添加到 SceneBuilder 库面板。

请参阅 JavaFX 用户指南的 Adding Custom Components to the Library 部分。

To import custom GUI components from a JAR or FXML file:

  1. Select Import JAR/FXML file command from the Library panel's menu, or drag the JAR or FXML file directly from your system's native file manager (Explorer or Finder) and drop it into the Library panel

  2. In the Open dialog window, navigate to the location of the JAR or FXML file that you want to import. The Import Dialog, similar to what is shown in Figure 8-4, is displayed. The JAR file's contents are inspected and all the Java classes that are determined as being suitable custom components are displayed in the dialog window. The FXML file's contents are parsed to make sure that the component being added is valid and self-contained.

  3. From the Import dialog window, select or unselect items from the list of items that you are able to import.

  4. Click Import Components. Imported items are added to the Custom section of the Library panel. They can be used immediately and they persist in the Library even after Scene Builder is restarted

请注意,SceneBuilder 还支持导入基于 FXML 的组件,而不仅仅是直接代码组件。此答案仅讨论导入不包含 FXML 的纯代码组件。

导入组件使用示例

这是我使用上述方法导入到 SceneBuilder 中的自定义搜索字段组件。

顶部的搜索面板是在Scene Builder设计面板中,底部的搜索面板是使用Scene Builder预览功能搜索快乐的结果。

示例 SceneBuilder 生成的代码

这里包含了SceneBuilder根据设计生成的fxml文件。请注意,这只是我使用 SceneBuilder 创建的测试场景,用于测试已导入的组件 - 它不是组件导入过程本身的一部分。

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

<?import javafx.scene.text.*?>
<?import org.jewelsea.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>


<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label text="Search Field Import Test">
         <font>
            <Font size="16.0" />
         </font>
      </Label>
      <SearchField />
   </children>
   <padding>
      <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
   </padding>
</VBox>

示例(可导入)组件代码

导入的搜索框代码为:

package org.jewelsea;

import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;

public class SearchField extends StackPane {
    private final TextField textField;
    private final Button searchButton;
    private final Label searchResults;

    public SearchField() {
        textField = new TextField();
        textField.setPromptText(
                "Search Text"
        );

        searchButton = new Button("Search");

        searchResults = new Label();

        VBox layout = new VBox(
                20,
                new HBox(
                        10,
                        textField,
                        searchButton
                ),
                searchResults
        );
        layout.setPadding(new Insets(10));

        searchButton.setOnAction(event ->
                searchResults.setText(
                        "Search result for " + textField.getText()
                )
        );

        getChildren().setAll(
                layout
        );
    }
}

组件先决条件

为了使流程正常运行,您需要确保以下几点:

  1. 您的组件 class 扩展了 Node.
  2. 您的组件 class 有一个无参数构造函数。
  3. 您的组件 class 且无参数构造函数是 public.
  4. 您的组件 class 在一个包中(例如 org.jewelsea)- 它不能没有包集。
  5. 您的组件 class 打包在一个 JAR 文件中,该文件已如上所述导入到 SceneBuilder 中。

疑难解答

如果您在导入 JAR 时遇到问题,在您尝试导入 JAR 之后,您可以使用下面记录的 JAR 分析功能来帮助解决问题(这可能会有所帮助,或者可能只是提供一些神秘信息让您更加困惑) .

此外,来自这个答案:

Try to launch Scene Builder from command line, you should see the output of the library imports, including possible exceptions from your custom control when you add it.