Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating Custom Control in Jar for Gluon Scene Builder 11.00

I want to create a custom control in an executable jar file and then use in Gluon Scene Builder 11.00. I need to know how to do this. I tried several forms but my controls not appear when import jar in Scene Builder. I am using IntelliJ Community Edition 2019.2 and Gluon Scene Builder 11.00 and Java 12.0.2. Anyone please that could help me with a little example?

Maven Project.

custom_control.fxml

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.VBox?>

<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="51.0" prefWidth="138.0" type="VBox" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <TextField fx:id="textField" />
      <Button mnemonicParsing="false" onAction="#doSomething" prefHeight="25.0" prefWidth="142.0" text="Clck Me" />
   </children>
</fx:root>

CustomControl.java

package customcontrolexample;

import java.io.IOException;

import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;

public class CustomControl extends VBox {
    @FXML private TextField textField;

    public CustomControl() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
                "custom_control.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

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

    public String getText() {
        return textProperty().get();
    }

    public void setText(String value) {
        textProperty().set(value);
    }

    public StringProperty textProperty() {
        return textField.textProperty();
    }

    @FXML
    protected void doSomething() {
        System.out.println("The button was clicked!");
    }
}

CustomControlExample.java

import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class CustomControlExample extends Application {

    private static Scene scene;

    @Override
    public void start(Stage stage) throws IOException {
        CustomControl customControl = new CustomControl();
        customControl.setText("Hello!");
        stage.setScene(new Scene(customControl));
        stage.setTitle("Custom Control");
        stage.setWidth(300);
        stage.setHeight(200);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>customcontrol</groupId>
    <artifactId>CustomControlExample</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>12.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>12.0.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.3</version>
                <configuration>
                    <mainClass>CustomControlExample</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>CustomControlExample</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
                        <phase>package</phase> <!-- bind to the packaging phase -->
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>
like image 555
Gustavo Gregorio Avatar asked Aug 27 '19 15:08

Gustavo Gregorio


People also ask

How do I add a jar file to Scene Builder?

Create class file with extending combo box, controller and add controller in FXML file (in scene builder). Find "Import from JAR/FXML file" in combo box near to left search box in scene builder and then select the file. Now you have new title pane in left accordion with name Custom. There you can find your components.

Is Scene Builder open source?

Scene Builder is open source, and it is freely licensed under the BSD license. Gluon can provide custom consultancy, training, and open source commercial support.


1 Answers

There are a few things to consider when you want to create a custom control that can be imported with Scene Builder.

What qualifies as custom control

There is no documentation about this, but you can have a look at the current source code in Scene Builder that explores all the classes in a jar, and finds valid classes as custom controls:

  • Classname not starting with java., javax., javafx., com.oracle.javafx.scenebuilder., com.javafx., com.gluonhq.
  • Concrete class (not abstract)
  • Assignable from Node. This is quite important: the class should be a subclass of a JavaFX node, like a container (i.e. extends from VBox) or a built-in node (i.e. extends from Button).

For all the classes found, then an FXML is built with something like:

 <?import your.class.fullname?>
 <your.class.simplename />

If that FXML can be loaded by the FXMLLoader, then it is a custom control. Otherwise it is discarded.

Type of custom control

There are several approaches on how to build a custom control, but if you are going to use FXML this old tutorial gives some important clarification on how to use fx:root and how to define the controller, like:

public class CustomControl extends VBox {

    public CustomControl() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
"custom_control.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

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

Java 11 level

Finally, since Scene Builder 11 runs on Java 11, the jar has to be compiled with support for Java 11.

Using Maven:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
          <source>11</source>
          <target>11</target>
    </configuration>
</plugin>

Before going to Scene Builder, you can try your custom control in a demo project. This will help you find and solve possible issues in advance.

Scene Builder 11

Once you have built the control, you can open Scene Builder 11 and import it following the documentation.

Basically, using the option Add Library/FXML from file system and browsing your file system to locate the jar.

Note: there is a merged PR that will allow using the build/target directory of a project, instead of requiring a jar.

In case of the posted custom control, you should get this:

custom control

If the view doesn't show your control, there is an issue that you have to solve first.

Note: there is a pending PR that will provide more information when the process fail.

like image 94
José Pereda Avatar answered Sep 30 '22 11:09

José Pereda