Skip to content

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

I’m new to javaFX. I created a customized Search box (extends TextField) in java, check image:

enter image description here

I tested it with a test class and it’s working.

I want to know now if it’s possible to create its FXML file than add this component to scene builder ? how to do it ? Thanks in advance.

Answer

How to Import a Component from a JAR into SceneBuilder

You can put your component in a Jar and import it into SceneBuilder. You don’t need to create an FXML file for your component to add it to SceneBuilder Library Panel.

See the Adding Custom Components to the Library section of the JavaFX user guide.

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

Note, SceneBuilder also supports importing of FXML based components rather than just straight code components. This answer only discusses importing of code only components which do not contain FXML.

Sample Imported Component Usage

Here is a custom search field component that I imported into SceneBuilder using the method outlined above.

search sample

The top search panel is in the Scene Builder design pane, the bottom search panel is the result of using the Scene Builder preview function and searching for happiness.

Sample SceneBuilder Generated Code

The fxml file which was generated by SceneBuilder based on the design is included here. Note, this was just a test scene I created with SceneBuilder to test the already imported component – it was not part of the component import process itself.

<?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>

Sample (importable) Component Code

The code for the search box which was imported is:

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
        );
    }
}

Component Pre-requisites

In order for the process to work, there are a few things you need to ensure:

  1. Your component class extends Node.
  2. Your component class has a no argument constructor.
  3. Your component class and no argument constructor are public.
  4. Your component class is in a package (e.g. org.jewelsea) – it can’t have no package set.
  5. Your component class is packaged in a JAR file which has been imported into SceneBuilder as described above.

Troubleshooting

If you are having issues importing the JAR, after you have attempted a JAR import, you can use the JAR analysis function documented below to help troubleshoot (which might help or might just provide some cryptic information to confuse you more).

jar file analysis

Also, from this answer:

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.