Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX 2 and Internationalization

I've just started writing my first JavaFX 2 application after learning the basics and would like to internationalize it.

I notice that in JavaFX 1.x, the scripting language allowed for very simple internationalization of strings. Are there any similar features in JavaFX 2?

Basically: what is the best practice for internationalizing a JavaFX 2 application?

like image 590
wobblycogs Avatar asked Apr 13 '12 15:04

wobblycogs


People also ask

Is JavaFX deprecated?

Starting with JDK 11, Oracle will remove JavaFX from the JDK, though will continue to provide commercial support for it in Oracle JDK 8 at least until 2022, according to Oracle's blog.

What JavaFX 2?

JavaFX is a set of graphics and media packages that enables developers to design, create, test, debug, and deploy rich client applications that operate consistently across diverse platforms.


1 Answers

The basic steps (among others) of a java app internationalizing, are Localelizing and resource bundling. In JavaFX, you can use FXMLLoader#setResources() for that purposes. Here a SSCCE demo to demonstrate it. The codes are self-descriptive.
Demo package structure:

bundledemo     |------ BundleDemo.java     |------ MyController.java     |------ MyView.fxml   bundles     |------ MyBundle_en.properties     |------ MyBundle_kg.properties 

MyBundle_en.properties

key1=Name Surname key2=How are you? 

MyBundle_kg.properties

key1=Aты Жөнү key2=Кандайсың? 

MyView.fxml

<?xml version="1.0" encoding="UTF-8"?>  <?import javafx.scene.layout.*?> <?import javafx.scene.control.*?> <?import javafx.scene.*?>  <BorderPane fx:controller="bundledemo.MyController" xmlns:fx="http://javafx.com/fxml">     <top>         <!-- This label's text will be set by the controller -->         <Label fx:id="lblTextByController"/>      </top>     <center>         <!-- This label's text will be taken from the bundle automatically -->         <Label text="%key2"/>     </center> </BorderPane> 

MyController.java

package bundledemo;  import java.net.URL; import java.util.ResourceBundle; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label;  public class MyController implements Initializable {      @FXML private Label lblTextByController;     private ResourceBundle bundle;          @Override     public void initialize(URL location, ResourceBundle resources) {         bundle = resources;         lblTextByController.setText(bundle.getString("key1"));     } } 

BundleDemo.java

package bundledemo; // imports are ignored.  public class BundleDemo extends Application {      private Stage stage;      @Override     public void start(Stage primaryStage) {         stage = primaryStage;         Button btnEN = new Button();         btnEN.setText("English");         btnEN.setOnAction(new EventHandler<ActionEvent>() {             @Override public void handle(ActionEvent event) {                 loadView(new Locale("en", "EN"));             }         });          Button btnKG = new Button();         btnKG.setText("Kyrgyz");         btnKG.setOnAction(new EventHandler<ActionEvent>() {             @Override public void handle(ActionEvent event) {                 loadView(new Locale("kg", "KG"));             }         });          VBox root = new VBox(20);         root.getChildren().add(HBoxBuilder.create().spacing(10).style("-fx-background-color: gray").padding(new Insets(5)).children(btnEN, btnKG).build());         root.getChildren().add(new StackPane());         primaryStage.setScene(new Scene(root, 300, 250));         primaryStage.show();     }      private void loadView(Locale locale) {         try {             FXMLLoader fxmlLoader = new FXMLLoader();             fxmlLoader.setResources(ResourceBundle.getBundle("bundles.MyBundle", locale));             Pane pane = (BorderPane) fxmlLoader.load(this.getClass().getResource("MyView.fxml").openStream());             // replace the content             StackPane content = (StackPane) ((VBox) stage.getScene().getRoot()).getChildren().get(1);             content.getChildren().clear();             content.getChildren().add(pane);         } catch (IOException ex) {             ex.printStackTrace();         }     }      public static void main(String[] args) {         launch(args);     } } 

Screenshot:

enter image description here


If your internationalized text needs to be rendered in a font that might be on the user's target system, then you can either:

  1. Embed the font with your application:
  • How to embed .ttf fonts is JavaFx 2.2?

OR

  1. Use web(Google) fonts in JavaFX.

If the required font is not available, then the internationalized text might be displayed as unintelligible gibberish, even though everything else about the setup is fine.

like image 122
Uluk Biy Avatar answered Sep 22 '22 12:09

Uluk Biy