I develop applications using JavaFX and Scenebuilder to create the user interface. I am in the need of using Unicode characters on the GUI but I am not able to add them directly from Scenebuilder, which wold be more convenient. Indeed Unicode characters can be inserted programmatically quite easily
myLabel.setText("\u03B1")
but, since the strings are totally static, I would like to add the text in Scenebuilder and avoid injecting the label object in the java code and have to deal with it only to change the text.
Inserting the Unicode string directly in the FXML file did not work
<Label fx:id="myLabel" text="\u03B1"/>
The only relevant post I found is Using Unicode characters with JavaFX but it does not solve my problem.
Is there a way to add an Unicode character directly in Scenebuilder or shall I give up on this?
As noted in the comments, and the related question:
Options for this are:
Edit the FXML manually (outside of SceneBuilder) and write the text using XML character references:
<Label fx:id="myLabel" text="α"/>
OR
Put "α" character as the text instead of using an escape sequence.
<Label fx:id="myLabel" text="α"/>
OR
\u
unicode code sequence.OR
This can be accomplished using a resource file as documented in the Oracle Scene Builder User Guide: Internationalizing Your FXML Layout.
Even though the Internationalization feature is targeted at internationalizing applications, it can also be used to help display Unicode characters that would otherwise be hard to type directly into SceneBuilder.
1. Internationalize the text in SceneBuilder
Select the node containing the text to customize and choose "Replace with Internationalized String".
Enter the resource key that you wish to use, for this example, I used the text "alpha".
2. Save the FXML
For the saved FXML1, SceneBuilder will create a file like this where the resource key is encoded as %alpha
. The %
character indicates that it is a resource key.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Font?>
<StackPane prefHeight="50.0" prefWidth="100.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="%alpha">
<font>
<Font size="26.0" />
</font></Label>
</children>
</StackPane>
3. Create a properties file containing the internationalized string
src/main/resources/org/example/resourcefx/resources.properties
alpha=\u03B1
If you need other languages and locales you can add additional files for them. However, if you don't, then just the default file with no _en_US
(or other) language and locale suffix suffices.
4. Test the resource via preview
Preview | Internationalization | Set Resource...
SceneBuilder will now display the Unicode text.
5. Use the FXML and resource in an Application
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.ResourceBundle;
public class ResourceApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(
ResourceApplication.class.getResource(
"resource-view.fxml"
)
);
fxmlLoader.setResources(
ResourceBundle.getBundle(
"org.example.resourcefx.resources"
)
);
stage.setScene(new Scene(fxmlLoader.load()));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Where to put the files
Following the Maven standard directory layout:
.
├── pom.xml
└── src
└── main
├── java
│ ├── module-info.java
│ └── org
│ └── example
│ └── resourcefx
│ └── ResourceApplication.java
└── resources
└── org
└── example
└── resourcefx
├── resource-view.fxml
└── resources.properties
You can place resources.properties
in any package you want (or use the unnamed package). Here I have used the same package for the resources that I used for the application. Doing so may also help avoid any potential resource resolution issues in modular applications.