Reputation: 1
I would like to change the language of my App from english to dutch when I refresh my screen (java and javaFX). Does anyone know where to start or wether there is a function to change the language within an app?
Upvotes: 0
Views: 517
Reputation: 209388
You should put all the strings in properties files, using the naming mechanism described in the ResourceBundle
documentation.
You can then create an ObjectProperty<Locale>
to represent the current locale (i.e. language), and bind all the strings in your UI to the appropriate value based on this locale. You probably want a separate class to handle this: here's a simple example.
import java.util.Locale;
import java.util.ResourceBundle;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
public class LocalizedBinding {
// property representing the current locale:
private final ObjectProperty<Locale> locale ;
// private property to hold the resource bundle:
private final ObjectProperty<ResourceBundle> bundle ;
public LocalizedBinding(String bundleName, Locale locale) {
this.locale = new SimpleObjectProperty<>(locale);
this.bundle = new SimpleObjectProperty<>();
// update resource bundle whenever locale changes:
bundle.bind(Bindings.createObjectBinding(() -> {
Locale l = this.locale.get();
if (l == null) {
return null ;
} else {
ResourceBundle resources = ResourceBundle.getBundle(bundleName, l);
return resources;
}
},
this.locale));
}
// creates a StringBinding whose value is obtained from the current
// resource bundle using the provided key. The binding will automatically
// update if the locale changes:
public StringBinding createStringBinding(String key) {
return new StringBinding() {
{
bind(bundle);
}
@Override
protected String computeValue() {
ResourceBundle resources = bundle.get();
if (resources == null) {
return key ;
} else {
return resources.getString(key);
}
}
};
}
// Property accessors for locale:
public final ObjectProperty<Locale> localeProperty() {
return this.locale;
}
public final java.util.Locale getLocale() {
return this.localeProperty().get();
}
public final void setLocale(final java.util.Locale locale) {
this.localeProperty().set(locale);
}
}
Here's a quick example using this:
import java.util.Locale;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class SwitchableLanguageTest extends Application {
@Override
public void start(Stage primaryStage) {
// Combo box for language selection:
ComboBox<Locale> combo = new ComboBox<>();
combo.getItems().addAll(Locale.getDefault(), new Locale("nl"));
// display each language in the actual language:
combo.setCellFactory(lv -> createListCell());
combo.setButtonCell(createListCell());
Label greetingLabel = new Label();
// Create a localizedBinding object for the bundle resources/greetings
LocalizedBinding localizedBinding = new LocalizedBinding(
"resources/greetings", Locale.getDefault());
// update the localizedBinding's locale when the combo box value changes:
localizedBinding.localeProperty().bind(combo.valueProperty());
// bind the label's text:
greetingLabel.textProperty().bind(
localizedBinding.createStringBinding("greeting"));
combo.getSelectionModel().select(Locale.getDefault());
BorderPane root = new BorderPane(greetingLabel, combo, null, null, null);
BorderPane.setAlignment(combo, Pos.CENTER);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private ListCell<Locale> createListCell() {
return new ListCell<Locale>() {
@Override
public void updateItem(Locale locale, boolean empty) {
super.updateItem(locale, empty);
if (empty) {
setText("");
} else {
setText(locale.getDisplayLanguage(locale));
}
}
};
}
public static void main(String[] args) {
launch(args);
}
}
The two properties files (in the resources directory) are
greetings.properties:
greeting=Hello
and greetings_nl.properties:
greeting=Hallo
Upvotes: 1