0

I am working currently on internalization functionality in my application.

I created bundle folder with 2 files, 2 languages available:

messages_pl.properties and messages_en.properties.

In my main fxml file (containing menuBar as well) I set internalization resource for each and every controls.

This piece of code works perfectly for me, I can switch from "en" to "pl"

public void start(Stage primaryStage) throws Exception {        
    Locale.setDefault(new Locale("en"));
    Pane borderPane = FxmlUtils.fxmlLoader(BORDER_PANE_MAIN_FXML);
    Scene scene = new Scene(borderPane);
    primaryStage.setScene(scene);
    primaryStage.setTitle(FxmlUtils.getResourceBundle().getString("tittle.application"));
    primaryStage.show();

The problem is that I don't want manipulate the code, switching from en to pl each time I need to change language.

I would like to have it dynamically, based if I choose RadioMenuItem "Polish" or RadioMenutItem "English".

Do you know how to adapt my source code consequently?

Bsquare ℬℬ
  • 4,423
  • 11
  • 24
  • 44

1 Answers1

0

I found a solution, it is not the prettiest but it works:

Controller:

public class Controller implements Initializable {

    @FXML
    private MenuItem en;
    @FXML
    private MenuItem de;

    Runnable changeLanguage; // add setter

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        en.setOnAction(event -> {
            Locale.setDefault(Locale.ENGLISH);
            reload();
        });
        de.setOnAction(event -> {
            Locale.setDefault(Locale.GERMAN);
            reload();
        });
    }
    private void reload() {
        changeLanguage.run();
    }
}

Main:

public class Main extends Application {

    private Stage primary;

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.primary = primaryStage;
        load();
        primaryStage.show();
    }

    private void load() throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
        loader.setResources(ResourceBundle.getBundle("stackoverflow/language/language", Locale.getDefault())); // the main package is stackoverflow which contains language
        primary.setScene(new Scene(loader.load(), 400, 600));
        Controller controller = loader.getController();
        controller.changeLanguage = () -> {
            try {
                load();
            } catch (IOException e) {
                e.printStackTrace();
            }
        };
    }

    public static void main(String[] args) {
        Locale.setDefault(Locale.ENGLISH);
        launch(args);
    }

}

and View.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="stackoverflow.language.Controller">
    <MenuBar>
        <Menu text="%language">
            <MenuItem fx:id="en" text="%en"/>
            <MenuItem fx:id="de" text="%de"/>
        </Menu>
    </MenuBar>
</AnchorPane>

This is how the classes are:

enter image description here

Sunflame
  • 2,993
  • 4
  • 24
  • 48
  • 1
    Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/183518/discussion-on-answer-by-sunflame-java-fx-resource-bundle-and-internalization-i). – Samuel Liew Nov 12 '18 at 23:15