AlmasB / FXGL

Java / JavaFX / Kotlin Game Library (Engine)
http://almasb.github.io/FXGL/
MIT License
4.45k stars 555 forks source link

How to make use of internationalization when using menus #1355

Open hansnf opened 9 months ago

hansnf commented 9 months ago

I have a rather general question about the usage of menu. For illustrating my issue, I will refer to a modified example of the Internationalization example provided by the FXGL repo. The sample makes use of a very simple menu. I have two questions: 1) When I use the code as it is, the key "some.key" is not available within the MainMenu. Where is a good point to initalize the keys 2) I consider creating a menu element to select the language in the MainMenu. When the language changes I can redraw all elements in the main menu. However, other menus such as the in-game menu are not updated automatically. What is the suggested way to do this? I was thinking about working with messages or restart the whole game.

Thank you very much!

public class LocalizationSample extends GameApplication {

    public static class MyMenu extends FXGLMenu {
        public MyMenu() {
            super(MenuType.MAIN_MENU);
            getContentRoot().getChildren().addAll(new Button(localize("some.key")));
        }
    };

    @Override
    protected void initSettings(GameSettings settings) {
        settings.setWidth(650);
        settings.setHeight(357);
        settings.setMainMenuEnabled(true);
        settings.setSceneFactory(new SceneFactory() {
            @Override
            public FXGLMenu newMainMenu() {
                return new MyMenu();
            }
        });
    }

    private int i = 0;

    @Override
    protected void initGame() {
        getGameScene().setBackgroundColor(new LinearGradient(
                0.5, 0, 0.5, 1, true, CycleMethod.NO_CYCLE,
                new Stop(0.0, Color.BLACK),
                new Stop(1.0, Color.AQUA)
        ));
        var languages = new ArrayList<>(getSettings().getSupportedLanguages());
        languages.add(new Language("KOREAN"));
        languages.add(new Language("CHINESE"));

    @Override
    protected void onPreInit() {
        getLocalizationService().addLanguageData(Language.ENGLISH, ResourceBundle.getBundle("assets.texts.texts", Locale.ENGLISH));
        getLocalizationService().addLanguageData(Language.FRENCH, ResourceBundle.getBundle("assets.texts.texts", Locale.FRENCH));
        getSettings().getLanguage().setValue(Language.ENGLISH);
        getLocalizationService().addLanguageData(Language.ENGLISH, Map.of("some.key", "Hello World"));
    }

    public static void main(String[] args) {
        launch(args);
    }
}
AlmasB commented 9 months ago

This might help:

  1. Create a target_language_name.lang file in /assets/languages/. See example

  2. Add the target language as a supported language:

    settings.getSupportedLanguages().add(...);
  3. Use bindings where localization is needed:

FXGL.localizedStringProperty("some.key")

returns a StringBinding which you can use with most JavaFX UI objects to bind their text property, so that when you change the language via getSettings(), all bound properties will be updated to display the localized text.