Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

i18n in JavaFX and IntelliJ IDEA

DZone's Guide to

i18n in JavaFX and IntelliJ IDEA

Internalization can be pretty important in JavaFX. Here's a look at using i18n in IntelliJ IDEA and JavaFX.

· Java Zone
Free Resource

Just released, a free O’Reilly book on Reactive Microsystems: The Evolution of Microservices at Scale. Brought to you in partnership with Lightbend.

Recently 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.

Strategies and techniques for building scalable and resilient microservices to refactor a monolithic application step-by-step, a free O'Reilly book. Brought to you in partnership with Lightbend.

Topics:
javafx 8

Published at DZone with permission of Steven Schwenke. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}