Yesterday I noticed there is an important topic missing in my JavaFX workshop : Internationalization. So here is a SSCCE for that. It’s basically a copy of my recent commit to my JavaFX workshop .
This simple sample consists of two UI parts. In the north, there is a combo box with languages to choose from. In the center, there is a label that gets translated according to the selection in the combo box.
This is the main class that loads the simple UI and implements the language switch:
package de.stevenschwenke.java.javafx.workshop.chapter_3_advanced_basics ;
import java.io.IOException ;
import java.util.Locale ;
import java.util.ResourceBundle ;
import javafx.application.Application ;
import javafx.collections.FXCollections ;
import javafx.collections.ObservableList ;
import javafx.fxml.FXMLLoader ;
import javafx.scene.Scene ;
import javafx.scene.control.ComboBox ;
import javafx.scene.control.ListCell ;
import javafx.scene.layout.BorderPane ;
import javafx.scene.layout.Pane ;
import javafx.stage.Stage ;
import javafx.util.StringConverter ;
/**
* JavaFX offers a simple way to translate UI components. In this example, a simple gui implements
* a language switch. The switch is basically a {@link ComboBox} with two languages to choose. The
* content-part of the UI is loaded from an fxml file. In this file, the label's text is set to
* "%label" which means that the text is going to be translated to whatever the set resource
* bundle provides.
*/
public class E_13_Internationalization extends Application {
BorderPane borderPane = new BorderPane ();
public static void main ( String [] args ) {
launch ( args );
}
@Override
public void start ( Stage stage ) throws Exception {
loadView ( new Locale ( "en" , "EN" ));
borderPane . setTop ( createComboBox ());
stage . setScene ( new Scene ( borderPane ));
stage . setTitle ( "Internationalization" );
stage . show ();
}
private ComboBox < Locale > createComboBox () {
ComboBox < Locale > comboBox = new ComboBox <>();
ObservableList < Locale > options = FXCollections . observableArrayList ( Locale . ENGLISH , Locale . GERMAN );
comboBox . setItems ( options );
comboBox . setConverter ( new StringConverter < Locale >() {
@Override
public String toString ( Locale object ) {
return object . getDisplayLanguage ();
}
@Override
public Locale fromString ( String string ) {
return null ;
}
});
comboBox . setCellFactory ( p -> new LanguageListCell ());
comboBox . getSelectionModel (). selectFirst ();
comboBox . setOnAction ( event -> loadView ( comboBox . getSelectionModel (). getSelectedItem ()));
return comboBox ;
}
private void loadView ( Locale locale ) {
try {
FXMLLoader fxmlLoader = new FXMLLoader ();
// Here, just the resource bundles name is mentioned. You can add support for more languages
// by adding more properties-files with language-specific endings like
// "E_13_Internationalization_fr.properties".
fxmlLoader . setResources ( ResourceBundle . getBundle ( "E_13_Internationalization" , locale ));
Pane pane = ( BorderPane ) fxmlLoader . load ( this . getClass (). getResource ( "/E_13_Internationalization.fxml" ). openStream ());
borderPane . setCenter ( pane );
} catch ( IOException ex ) {
ex . printStackTrace ();
}
}
class LanguageListCell extends ListCell < Locale > {
@Override protected void updateItem ( Locale item , boolean empty ) {
super . updateItem ( item , empty );
if ( item != null ) {
setText ( item . getDisplayLanguage ());
}
}
}
}
This fxml-file is the center part of the UI. It just holds a label that gets translated:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight= "-Infinity" maxWidth= "-Infinity" minHeight= "-Infinity" minWidth= "-Infinity" prefHeight= "400.0" prefWidth= "600.0" xmlns= "http://javafx.com/javafx/8.0.45" xmlns:fx= "http://javafx.com/fxml/1" fx:controller= "de.stevenschwenke.java.javafx.workshop.chapter_3_advanced_basics.E_13_Internationalization" >
<center>
<!-- The "%" in the text-tag means that the text is going to be translated -->
<Label text= "%label" BorderPane.alignment= "CENTER" />
</center>
</BorderPane>
And finally the two properties-files for english and german language support:
label="Hier steht ein Text"
label="This is a text"
Intellij IDEA provides a really nice resource bundle editor for managing your translations. This thing allows you to manage the text of all your languages without having to crawl through your properties-files:
TL;DR
JavaFX provides an easy way to translate your UI texts in different languages. When using the resource bundle editor of IntelliJ IDEA, the management of UI texts is a piece of cake.