In our project we want to create custom components which we want to use in the JavaFX Scenebuilder.
Anything you need could be found on my gibthub : Scavenger156-Gibthub
At first we think that the current importing of a „.jar“ file is more than enough.
There are some problems:
- every developer must import the jar every time it was changed
- a developer could forget to add the file
- every time he opens a „.fxml“ with custom components he must add the „.jar“
- if you import the „jar“ you also need all referenced library’s to let it work
- no live development on the custom components
But after all these problems we need a change and this was where i come in to the game.
My goal was to create a extension of the existing scenebuilder.
Part 1: Own Project
1. Create a new Java-Project
2. Download & install the latest version of the JavaFX-Scenebuilder
3. Copy the following files.
3.1 your final structure could be
4. Add the „SceneBuilderApp.jar“ and „SceneBuilderKit.jar“ to the classpath
5. Create a custom „Main“-class
[codesyntax lang=“java“]
package eu.thecreator.scenebuilder;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import com.oracle.javafx.scenebuilder.app.SceneBuilderApp;
import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
import com.oracle.javafx.scenebuilder.kit.library.LibraryItem;
import eu.thecreator.components.MyComponent;
/**
* Overriding the existing Scenebuilder
*
* @author andre
*
*/
public class Main extends SceneBuilderApp {
/**
* Main
*
* @param args
*/
public static void main(String[] args) {
launch(args);
}
}
[/codesyntax]
Part 2: The custom component
1. We create a custom component in a second project with a custom component
2. Add the new project to the buildpath
Part 3: Adding the custom component into the scenebuilder
After part 2 we can use the project in our scenebuilder without adding the „.jar“ every time and we need no path to the „.jar“ in the „fxml“-files.
1. How to add the new component?
This was the main question because there was no sourcecode or any tutorial to add a custom block to the library.
So i used a decompiler and a little magic 😉 to do this:
[codesyntax lang=“java“]
ObservableList<LibraryItem> items = SceneBuilderApp.getSingleton().getUserLibrary().getItems();
Class<?> componentClass = MyComponent.class;
LibraryItem item = new LibraryItem(componentClass.getSimpleName(),
CUSTOMLIB_NAME,
"" // The parameter could not be "null" otherwise
// drag and drop would not work
, null, SceneBuilderApp.getSingleton().getUserLibrary()) {
@Override
public FXOMDocument instantiate() {
FXOMDocument document = new FXOMDocument();
FXOMInstance in = new FXOMInstance(document, componentClass);
document.setFxomRoot(in);
return document;
}
};
[/codesyntax]
2. Creating the final version
[codesyntax lang=“java“]
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import com.oracle.javafx.scenebuilder.app.SceneBuilderApp;
import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
import com.oracle.javafx.scenebuilder.kit.library.LibraryItem;
import eu.thecreator.components.MyComponent;
/**
* Overriding the existing Scenebuilder
*
* @author andre
*
*/
public class Main extends SceneBuilderApp {
private static final String CUSTOMLIB_NAME = "Customlib";
/**
* Main
*
* @param args
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage arg0) throws Exception {
super.start(arg0);
postLoad();
}
/**
* Adding our own code
*/
private void postLoad() {
// These are the current items of the library
ObservableList<LibraryItem> items = SceneBuilderApp.getSingleton()
.getUserLibrary().getItems();
if (items.isEmpty()) {
// The items are not loaded so we try again later
javafx.application.Platform.runLater(new Runnable() {
@Override
public void run() {
postLoad();
}
});
return;
}
// adding our Components
items.add(addComponent(MyComponent.class));
}
private static LibraryItem addComponent(final Class<?> componentClass) {
LibraryItem item = new LibraryItem(componentClass.getSimpleName(),
CUSTOMLIB_NAME,
//
"" // The parameter could not be "null" otherwise
// drag and drop would not work
, null, SceneBuilderApp.getSingleton().getUserLibrary()) {
@Override
public FXOMDocument instantiate() {
FXOMDocument document = new FXOMDocument();
FXOMInstance in = new FXOMInstance(document, componentClass);
document.setFxomRoot(in);
return document;
}
};
return item;
}
}
[/codesyntax]
3. Now start the new „main“ and see the new what we could do:
The scenebuilder also finds the property’s in our new component 🙂
4. Save your file and be happy.
[codesyntax lang=“xml“]
<?import eu.thecreator.components.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<MyComponent diameter="30.0" height="127.0" layoutX="131.0" layoutY="110.0" width="322.0" x="10.0" y="10.0" />
</children>
</AnchorPane>
[/codesyntax]
Anything you need could be found on my gibthub : Scavenger156-Gibthub






