All Projects → Naoghuman → Lib I18n

Naoghuman / Lib I18n

Licence: gpl-3.0
The library `Lib-I18N` allows a developer to bind a key-value pair of a `.properties` file to a [StringBinding]. This makes it very easy to change the language during runtime in a [JavaFX] application.

Programming Languages

java
68154 projects - #9 most used programming language
language
365 projects

Projects that are alternatives of or similar to Lib I18n

openjfx-docs
Getting started guide for JavaFX 11
Stars: ✭ 70 (+75%)
Mutual labels:  netbeans, maven, javafx
Samples
JavaFX samples to run with different options and build tools
Stars: ✭ 352 (+780%)
Mutual labels:  javafx, netbeans, maven
lib-preferences
Lib-Preferences is a library for easy storing simple data to a Preferences.properties file in a Java(FX) & Maven desktop application.
Stars: ✭ 12 (-70%)
Mutual labels:  netbeans, maven, javafx
Maven Jpackage Template
Sample project illustrating building nice, small cross-platform JavaFX-based desktop apps with native installers while still using the standard Maven dependency system.
Stars: ✭ 74 (+85%)
Mutual labels:  javafx, maven
Hellojpro
Stars: ✭ 46 (+15%)
Mutual labels:  javafx, maven
Drombler Fx
Drombler FX - the modular application framework for JavaFX.
Stars: ✭ 52 (+30%)
Mutual labels:  javafx, maven
Azkar-App
Desktop Application 💻 for Calculating Muslim prayer times 🕌 , Morning and Nights Azkar 🤲 with notification for random Azkar that pops-up in specific time.
Stars: ✭ 64 (+60%)
Mutual labels:  maven, javafx
jakartaee8-starter-boilerplate
A boilerplate project for starting a Jakarta EE 8 application in seconds
Stars: ✭ 55 (+37.5%)
Mutual labels:  netbeans, maven
VickyWarAnalyzer
Victoria II war analyzer. Java 8 + JavaFX + Maven
Stars: ✭ 43 (+7.5%)
Mutual labels:  maven, javafx
LogoRRR
A log viewer which visualises log events such that it is easy to identify problems or events of interest. This app was implemented using Scala and JavaFX, GluonHQ toolchain and GraalVM as platform.
Stars: ✭ 40 (+0%)
Mutual labels:  maven, javafx
vic2 economy analyzer
Victoria 2 savegame economy analyzer, updated version
Stars: ✭ 44 (+10%)
Mutual labels:  maven, javafx
Javafx Maven Plugin
Maven plugin for JavaFX
Stars: ✭ 764 (+1810%)
Mutual labels:  javafx, maven
Ssm redis template
An template based on Maven, using Spring + Spring MVC + mybatis + spring-data-redis frames. It can be used to construct a new Java Web Appliaction quickly
Stars: ✭ 13 (-67.5%)
Mutual labels:  maven
Web Framework For Java
A seed project with spring boot for AngularJS, AngularJs Material, Thymeleaf, RESTful API, MySQL and admin panel based on AdminLTE.
Stars: ✭ 29 (-27.5%)
Mutual labels:  maven
Img2latex Mathpix
An image to LaTeX tool by MathpixOCR API and JavaFX
Stars: ✭ 872 (+2080%)
Mutual labels:  javafx
Pharmacy Blockchain
Open Hackathon Sep 2018 - Oran.
Stars: ✭ 13 (-67.5%)
Mutual labels:  javafx
Aliyungradleconfig
自用的安卓开源项目工程模板。阿里云远程仓库加速,发布到maven仓库、上传到jcenter,代码混淆、资源混淆,持续集成(CI),多渠道自动打包。在天朝使用jcenter、mavenCentral及google三个远程仓库,Gradle Sync太慢?一招教你配置阿里云镜像源。init.d/init.gradle
Stars: ✭ 37 (-7.5%)
Mutual labels:  maven
Base
Multilingual CMS built with Laravel.
Stars: ✭ 949 (+2272.5%)
Mutual labels:  multilingual
Mvnrunner
IntelliJ plugin for maven, building and run unit testing or main method, by mvn.
Stars: ✭ 7 (-82.5%)
Mutual labels:  maven
Android Cookbook Examples
Contributed code examples from O'Reilly Android Cookbook. See #user-content-table README below!
Stars: ✭ 935 (+2237.5%)
Mutual labels:  maven

Lib-I18n

Build Status license: GPL v3 GitHub release

Intention

The library Lib-I18N allows a developer to bind a key-value pair of a .properties file to a StringBinding. This makes it very easy to change the language during runtime in a JavaFX application.
Lib-I18N is written in JavaFX, Maven and NetBeans.

Image: Demo integration from Lib-I18N
Lib-I18N_Demo_v0.8.0_2019-04-27_16-24.png

The demo shows how easy an application becomes multilingual in four steps 😄 .
Plz see the section Demo for more informations.

Content

Features

Main library features

In this sub-section all main features from the library 'Lib-I18N' are listed:

  1. The library Lib-I18N allows a developer to bind a key with its associated value of a .properties file to a StringBinding.
  2. With the builder I18NResourceBundleBuilder the developer can configure the ResourceBundle which contains the key - value pairs which will then be bind to a actual Locale.
  3. The builder I18NBindingBuilder let the developer create a StringBinding. The StringBinding can created with a function from type Callable<String> or with a .properties key and optional arguments.
  4. To load a .properties key with optional arguments from the initialized ResourceBundle through the I18NResourceBundleBuilder the developer can use the builder I18NMessageBuilder.

General library features

This sub-section list all general features from the library 'Lib-I18N':

  1. The library Lib-I18N is open source and licensed under General Public License 3.0.
  2. The library is written in Java and JavaFX.
  3. The library is programmed with the IDE NetBeans as a Maven library.
  4. The library can easily integrated into a foreign project over Maven Central.
  5. Due to the connection of the project with Travis CI, a build is automatically executed at each commit.
  6. By integrating various "badges" from "img.shield.io", interested readers can easily find out about the "build" state, the current version and the license used for this library.
  7. All functionalities from the classes in the core and internal packages are tested with Unittests.
  8. Every parameter in all functionalities will be verified against minimal conditions with the internal validator DefaultI18NValidator. For example a String can't be NULL or EMPTY.
  9. The documentation from the library is available with an extended ReadMe and well-described JavaDoc comments.

Conventions

In this chapter, the interested developer can find out all about the conventions from the library Lib-I18N:

Convention: 'baseBundleName' from ResourceBundle

If a ResourceBundle with the defined 'baseBundleName' can't be found a spezific MissingResourceException will be thrown.

public final class DefaultI18NResourceBundle implements I18NResourceBundle {
    ...
    private ResourceBundle getResourceBundle() {
        ResourceBundle bundle = null;
        try {
            bundle = ResourceBundle.getBundle(this.getBaseBundleName(), this.getActualLocale());
        } catch (MissingResourceException mre) {
            LoggerFacade.getDefault().error(this.getClass(), 
                    String.format("Can't access the ResourceBundle[path=%s, actual-locale=%s]", 
                            this.getBaseBundleName(), this.getActualLocale().getDisplayLanguage()), 
                    mre);
        }
        
        return bundle;
    }
    ...
}

Convention: 'Key not found' in ResourceBundle

If a key can't be found in the defined ResourceBundle then

  • the String pattern '<key>' will returned and
  • the following 'warning' message will be logged: "Can't find key(%s) in resourcebundle. Return: %s"
2019-04-19 22:36:34,708  WARN  Can't find key(not.existing.key.in.existing.resourcebundle) in resourcebundle. Return: <not.existing.key.in.existing.resourcebundle>     [DefaultI18NResourceBundle]
java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key not.existing.key.in.existing.resourcebundle
	at java.util.ResourceBundle.getObject(ResourceBundle.java:450) ~[?:1.8.0_201]
	at java.util.ResourceBundle.getString(ResourceBundle.java:407) ~[?:1.8.0_201]
	at com.github.naoghuman.lib.i18n.internal.DefaultI18NResourceBundle.getMessage(DefaultI18NResourceBundle.java:96) [classes/:?]
	at com.github.naoghuman.lib.i18n.internal.DefaultI18NResourceBundleTest.getMessageWithResourceBundleThrowsMissingResourceException(DefaultI18NResourceBundleTest.java:110) [test-classes/:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_201]
        ...
public final class DefaultI18NResourceBundle implements I18NResourceBundle {

    private static final String PATTERN_KEY_NAME = "<{0}>"; // NO18N
    ...
    @Override
    public String getMessage(final String key, final Object... arguments) {
        DefaultI18NValidator.requireNonNullAndNotEmpty(key);
        DefaultI18NValidator.requireNonNullAndNotEmpty(arguments);
        DefaultI18NValidator.requireResourceBundleExist(this.getBaseBundleName(), this.getActualLocale());
        
        final ResourceBundle bundle = getResourceBundle();
        String value = MessageFormat.format(PATTERN_KEY_NAME, key);
        
        if (bundle != null) {
            try {
                value = MessageFormat.format(bundle.getString(key), arguments);
            } catch (MissingResourceException mre) {
                LoggerFacade.getDefault().warn(this.getClass(), 
                        String.format("Can't find key(%s) in resourcebundle. Return: %s", key, value), 
                        mre);
            }
        }
        
        return value;
    }
    ...
}

Convention: Defined supported Locales, default and actual Locale

Supported Locales

  • Defines all supported Locales in the momentary session.
  • This array should reflectes all your defined languages .properties files.
public final class I18NResourceBundleBuilder {
    ...
    private static final class I18NResourceBundleBuilderImpl implements
            FirstStep,  ForthStep, LastStep, SecondStep, ThirdStep
    {
        ...
        @Override
        public ThirdStep supportedLocales(final Locale... locales) {
            LoggerFacade.getDefault().debug(this.getClass(), "I18NResourceBundleBuilderImpl.supportedLocales(Locale...)"); // NOI18N
            
            final List<Locale> list = Arrays.asList(locales);
            DefaultI18NValidator.requireNonNullAndNotEmpty(list);
            
            final ObservableList<Locale> observableList = FXCollections.observableArrayList();
            observableList.addAll(list);
            properties.put(ATTR__SUPPORTED_LOCALES, new SimpleObjectProperty(observableList));
            
            return this;
        }

        @Override
        public ThirdStep supportedLocales(final ObservableList<Locale> locales) {
            LoggerFacade.getDefault().debug(this.getClass(), "I18NResourceBundleBuilderImpl.supportedLocales(ObservableList<Locale>)"); // NOI18N
            
            DefaultI18NValidator.requireNonNullAndNotEmpty(locales);
            properties.put(ATTR__SUPPORTED_LOCALES, new SimpleObjectProperty(locales));
            
            return this;
        }
        ...
    }
}
public final class I18NFacade implements I18NBinding, I18NResourceBundle {
    ...
    @Override
    public ObservableList<Locale> getSupportedLocales() {
        return i18NResourceBundle.getSupportedLocales();
    }

    @Override
    public void setSupportedLocales(final ObservableList<Locale> locales) {
        i18NResourceBundle.setSupportedLocales(locales);
    }

    @Override
    public void setSupportedLocales(final Locale... locales) {
        i18NResourceBundle.setSupportedLocales(locales);
    }
    ...
}
public final class DefaultI18NResourceBundle implements I18NResourceBundle {
    ...
    @Override
    public ObservableList<Locale> getSupportedLocales() {
        DefaultI18NValidator.requireNonNull(supportedLocales);
        
        return supportedLocales;
    }

    @Override
    public void setSupportedLocales(final ObservableList<Locale> locales) {
        DefaultI18NValidator.requireNonNullAndNotEmpty(locales);
        
        supportedLocales.clear();
        supportedLocales.addAll(locales);
    }

    @Override
    public void setSupportedLocales(final Locale... locales) {
        final List<Locale> list = Arrays.asList(locales);
        DefaultI18NValidator.requireNonNullAndNotEmpty(list);
        
        supportedLocales.clear();
        supportedLocales.addAll(list);
    }
    ...
}

Default Locale

  • If the supported Locales doesn't contained the default Locale then the Locale#ENGLISH instead will be return.
public final class DefaultI18NResourceBundle implements I18NResourceBundle {
    ...
    @Override
    public void setDefaultLocale(final Locale locale) {
        DefaultI18NValidator.requireNonNull(locale);
        
        defaultLocale = this.getSupportedLocales().contains(locale) ? locale : Locale.ENGLISH;
    }
    ...
}

Actual Locale

  • If the supported Locales doesn't contained the actual Locale then the default Locale instead will be return.
public final class DefaultI18NResourceBundle implements I18NResourceBundle {
    ...
    @Override
    public void setActualLocale(final Locale locale) {
        DefaultI18NValidator.requireNonNull(locale);
        
        actualLocaleProperty.set(this.getSupportedLocales().contains(locale) ? locale : defaultLocale);
    }
    ...
}

Convention: Basic validation

  • Every functionality in the builders and in the default implementations will checked against minimal preconditions with the validator DefaultI18NValidator.
  • Getters and Setters functionalities are only checked if they are initial only instantiate and not declarated.
  • For example a String will be validate if it's not NULL and not EMPTY.
public final class I18NResourceBundleBuilder {
    ...
    private static final class I18NResourceBundleBuilderImpl implements
            FirstStep,  ForthStep, LastStep, SecondStep, ThirdStep
    {
        ...
        @Override
        public SecondStep baseBundleName(final String baseBundleName) {
            LoggerFacade.getDefault().debug(this.getClass(), "I18NResourceBundleBuilderImpl.baseBundleName(String)"); // NOI18N

            DefaultI18NValidator.requireNonNullAndNotEmpty(baseBundleName);
            properties.put(ATTR__BASE_BUNDLE_NAME, new SimpleStringProperty(baseBundleName));

            return this;
        }
        ...
    }
}
public final class DefaultI18NResourceBundle implements I18NResourceBundle {
    ...
    @Override
    public String getBaseBundleName() {
        DefaultI18NValidator.requireNonNullAndNotEmpty(baseBundleName);
        
        return baseBundleName;
    }

    @Override
    public void setBaseBundleName(final String baseBundleName) {
        DefaultI18NValidator.requireNonNullAndNotEmpty(baseBundleName);
        
        this.baseBundleName = baseBundleName;
    }
    ...
}
public final class DefaultI18NBinding implements I18NBinding {
    ...
    @Override
    public StringBinding createStringBinding(final String key, Object... arguments) {
        DefaultI18NValidator.requireNonNullAndNotEmpty(key);
        DefaultI18NValidator.requireNonNullAndNotEmpty(arguments);
        
        return Bindings.createStringBinding(() -> I18NFacade.getDefault().getMessage(key, arguments), I18NFacade.getDefault().actualLocaleProperty());
    }
    ...
}

Examples

How to use the builder I18NResourceBundleBuilder

With the builder I18NResourceBundleBuilder the developer can configure the ResourceBundle which contains the key - value terms which will then be bind to a Locale. That means switching the actual Locale update all binded textes with the specific values from the corresponding language .properties file.

Specification: Usage of I18NResourceBundleBuilder

/**
 * 1) Starts the configuration process.
 * 2) Defines the path and name from the .properties file.
 * 3) Sets all supported Locales with an [].
 * 4) Sets all supported Locales with an ObservableList.
 * 5) Sets the default Locale.
 * 6) Sets the actual Locale.
 * 7) Completes the configuration process.
 */
I18NResourceBundleBuilder.configure() // 1
        .baseBundleName(String)       // 2
        .supportedLocales(Locale...)  // 3
        .supportedLocales(ObservableList<Locale>) // 4
        .defaultLocale(Locale)        // 5
        .actualLocale(Locale)         // 6
        .build();                     // 7

Examples:

@Test
public void lastStepWithSupportedLocalesAsArray() {
    String resourcbundle = "com.github.naoghuman.lib.i18n.internal.resourcebundle";
    I18NResourceBundleBuilder.configure()
            .baseBundleName(resourcbundle)
            .supportedLocales(Locale.ITALIAN, Locale.JAPANESE)
            .defaultLocale(Locale.ITALIAN)
            .actualLocale(Locale.JAPANESE)
            .build();

    assertEquals(resourcbundle,   I18NFacade.getDefault().getBaseBundleName());
    assertEquals(Locale.ITALIAN,  I18NFacade.getDefault().getDefaultLocale());
    assertEquals(Locale.JAPANESE, I18NFacade.getDefault().getActualLocale());
    assertEquals(2,               I18NFacade.getDefault().getSupportedLocales().size());
}

@Test
public void lastStepWithSupportedLocalesAsObservableList() {
    String resourcbundle = "com.github.naoghuman.lib.i18n.internal.resourcebundle";
    final ObservableList<Locale> locales = FXCollections.observableArrayList();
    locales.addAll(Locale.ITALIAN, Locale.JAPANESE, Locale.FRENCH);
    I18NResourceBundleBuilder.configure()
            .baseBundleName(resourcbundle)
            .supportedLocales(locales)
            .defaultLocale(Locale.ITALIAN)
            .actualLocale(Locale.JAPANESE)
            .build();

    assertEquals(resourcbundle,  I18NFacade.getDefault().getBaseBundleName());
    assertEquals(Locale.ITALIAN, I18NFacade.getDefault().getDefaultLocale());
    assertEquals(Locale.JAPANESE,I18NFacade.getDefault().getActualLocale());
    assertEquals(3,              I18NFacade.getDefault().getSupportedLocales().size());
}

How to use the builder I18NBindingBuilder

The builder I18NBindingBuilder let the developer create a StringBinding. The StringBinding can created with a function from type Callable<String> or with a .properties key and optional arguments.

Specification: Usage of I18NBindingBuilder

/**
 * 1) Starts the binding process.
 * 2) Use the given function to create a StringBinding.
 * 3) Completes the binding process and returns the StringBinding.
 */
I18NBindingBuilder.bind()          // 1
       .callable(Callable<String>) // 2
       .build();                   // 3

/**
 * 1) Starts the binding process.
 * 2) Defines the key which value will be bind to the StringBinding.
 * 3) Optional arguments for the value from the given key.
 * 4) Completes the binding process and returns the StringBinding.
 */
I18NBindingBuilder.bind()         // 1
       .key(String)               // 2
       .arguments(Object... args) // 3
       .build();                  // 4

Examples:

@Test
public void lastStepCallable() {
    I18NResourceBundleBuilder.configure()
            .baseBundleName("com.github.naoghuman.lib.i18n.internal.resourcebundle")
            .supportedLocales(Locale.ENGLISH, Locale.GERMAN)
            .defaultLocale(Locale.ENGLISH)
            .actualLocale(Locale.GERMAN)
            .build();

    Optional<StringBinding> result = I18NBindingBuilder.bind()
            .callable(() -> I18NMessageBuilder.message()
                    .key("resourcebundle.title")
                    .build()
            )
            .build();
    assertTrue(result.isPresent());
    assertEquals("RB: Test Titel", result.get().get());

    I18NFacade.getDefault().setActualLocale(Locale.ENGLISH); // Here the magic happen :)
    assertEquals("RB: Test title", result.get().get());
}

@Test
public void lastStepKeyWithoutArguments() {
    I18NResourceBundleBuilder.configure()
            .baseBundleName("com.github.naoghuman.lib.i18n.internal.resourcebundle")
            .supportedLocales(Locale.ENGLISH, Locale.GERMAN)
            .defaultLocale(Locale.ENGLISH)
            .actualLocale(Locale.GERMAN)
            .build();

    Optional<StringBinding> result = I18NBindingBuilder.bind()
            .key("resourcebundle.title")
            .build();
    assertTrue(result.isPresent());
    assertEquals("RB: Test Titel", result.get().get());

    I18NFacade.getDefault().setActualLocale(Locale.ENGLISH); // Here the magic happen :)
    assertEquals("RB: Test title", result.get().get());
}

@Test
public void lastStepKeyWithArguments() {
    I18NResourceBundleBuilder.configure()
            .baseBundleName("com.github.naoghuman.lib.i18n.internal.resourcebundle")
            .supportedLocales(Locale.ENGLISH, Locale.GERMAN)
            .defaultLocale(Locale.ENGLISH)
            .actualLocale(Locale.GERMAN)
            .build();

    Optional<StringBinding> result = I18NBindingBuilder.bind()
            .key("resourcebundle.label.with.parameter")
            .arguments(123)
            .build();
    assertTrue(result.isPresent());
    assertEquals("RB: Text mit Parameter: 123", result.get().get());

    I18NFacade.getDefault().setActualLocale(Locale.ENGLISH); // Here the magic happen :)
    assertEquals("RB: Text with parameter: 123", result.get().get());
}

How to use the builder I18NMessageBuilder

To load a .properties key with optional arguments from the initialized ResourceBundle through the I18NResourceBundleBuilder the developer can use the builder I18NMessageBuilder.

Specification: Usage of I18NMessageBuilder

/**
 * 1) Starts the message process.
 * 2) Defines the key which value will be loaded.
 * 3) Optional arguments for the value from the given key.
 * 4) Completes the message process and returns a String.
 */
I18NMessageBuilder.message()  // 1
        .key(String)          // 2
        .arguments(Object...) // 3
        .build();             // 4

Examples:

@Test
public void lastStepWithoutArguments() {
    I18NResourceBundleBuilder.configure()
            .baseBundleName("com.github.naoghuman.lib.i18n.internal.resourcebundle")
            .supportedLocales(Locale.ENGLISH, Locale.GERMAN)
            .defaultLocale(Locale.ENGLISH)
            .actualLocale(Locale.GERMAN)
            .build();

    String result = I18NMessageBuilder.message()
            .key("resourcebundle.title")
            .build();
    assertEquals("RB: Test Titel", result);

    I18NFacade.getDefault().setActualLocale(Locale.ENGLISH); // Here the magic happen :)
    result = I18NMessageBuilder.message()
            .key("resourcebundle.title")
            .build();
    assertEquals("RB: Test title", result);
}
    
@Test
public void lastStepWithArguments() {
    I18NResourceBundleBuilder.configure()
            .baseBundleName("com.github.naoghuman.lib.i18n.internal.resourcebundle")
            .supportedLocales(Locale.ENGLISH, Locale.GERMAN)
            .defaultLocale(Locale.ENGLISH)
            .actualLocale(Locale.GERMAN)
            .build();

    String result = I18NMessageBuilder.message()
            .key("resourcebundle.label.with.parameter")
            .arguments(2)
            .build();
    assertEquals("RB: Text mit Parameter: 2", result);

    I18NFacade.getDefault().setActualLocale(Locale.ENGLISH); // Here the magic happen :)
    result = I18NMessageBuilder.message()
            .key("resourcebundle.label.with.parameter")
            .arguments(123)
            .build();
    assertEquals("RB: Text with parameter: 123", result);
}

Demo

The demo applications shows how to integrate the library Lib-I18N in four simple steps.

Image: Demo application Lib-I18N_Demo-English_v0.8.0_2019-04-27_16-14.png

Hint:
To run the demo local the library Lib-FMXL v0.3.0-PRERELEASE is needed which isn't momentary available in Maven Central. The library can be downloaded manually here: https://github.com/Naoghuman/lib-fxml

Step one: Prepare your application

First inject the library 'Lib-I18N' into your project.
Then create for every supported language a .properties file.

<dependencies>
    <dependency>
        <groupId>com.github.naoghuman</groupId>
        <artifactId>lib-i18n</artifactId>
        <version>0.8.0</version>
    </dependency>
</dependencies>

Image: Demo .properties files Lib-I18N_Demo-properties-files_v0.8.0_2019-04-27_17-33.png

Step two: Register the ResourceBundle

Next register the ResourceBundle where supportedLocales are corresponding to every existing .properties file and actualLocale is the language which will shown first.

public final class DemoI18NStart extends Application {

    @Override
    public void init() throws Exception {
        I18NResourceBundleBuilder.configure()
                .baseBundleName("com.github.naoghuman.lib.i18n.demo_i18n") // NOI18N
                .supportedLocales(Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN, Locale.ITALIAN)
                .defaultLocale(Locale.ENGLISH)
                .actualLocale(Locale.ENGLISH)
                .build();
    }
}

Step three: Bind the text components

In the third step the text components will be bind to the depending key from the ResourceBundle.

public final class DemoI18NController extends FXMLController implements Initializable {

    @FXML private Button bFrench;
    @FXML private Button bGerman;
    @FXML private Button bItalian;
    @FXML private Button bEnglish;
    @FXML private Label lLanguages;
    @FXML private Text tAbout;
    @FXML private Text tFrom;
    @FXML private Text tHello;
    @FXML private Text tLand;

    @Override
    public void initialize(final URL location, final ResourceBundle resources) {
        // Menu
        this.bind(lLanguages.textProperty(), "demo.i18n.languages");        // NOI18N
        this.bind(bFrench.textProperty(),    "demo.i18n.language.french");  // NOI18N
        this.bind(bGerman.textProperty(),    "demo.i18n.language.german");  // NOI18N
        this.bind(bItalian.textProperty(),   "demo.i18n.language.italian"); // NOI18N
        this.bind(bEnglish.textProperty(),   "demo.i18n.language.english"); // NOI18N
        
        // Message
        this.bind(tHello.textProperty(), "demo.i18n.greetings"); // NOI18N
        this.bind(tFrom.textProperty(),  "demo.i18n.from");      // NOI18N
        this.bind(tLand.textProperty(),  "demo.i18n.land");      // NOI18N
        this.bind(tAbout.textProperty(), "demo.i18n.about");     // NOI18N
    }

    private void bind(final StringProperty stringProperty, final String key) {
        final Optional<StringBinding> optionalStringBinding = I18NBindingBuilder.bind().key(key).build();
        optionalStringBinding.ifPresent(stringBinding -> {
            stringProperty.bind(stringBinding);
        });
    }
}

Step four: Switch the language during runtime

And in the last step the user will change the language in the runing application which leads to a change from the actualLocale which performs then the language update in the gui.

public final class DemoI18NController extends FXMLController implements Initializable {

    public void onActionSwitchToLanguageFrench() {
        if (I18NFacade.getDefault().getActualLocale().equals(Locale.FRENCH)) {
            LoggerFacade.getDefault().debug(this.getClass(), "Shows already the Locale.FRENCH - do nothing."); // NOI18N
            return;
        }
        
        I18NFacade.getDefault().setActualLocale(Locale.FRENCH);
    }
    
    public void onActionSwitchToLanguageGerman() {
        if (I18NFacade.getDefault().getActualLocale().equals(Locale.GERMAN)) {
            LoggerFacade.getDefault().debug(this.getClass(), "Shows already the Locale.GERMAN - do nothing."); // NOI18N
            return;
        }
        
        I18NFacade.getDefault().setActualLocale(Locale.GERMAN);
    }
    
    ...
}

JavaDoc

The JavaDoc from the library Lib-I18N can be explored here: JavaDoc Lib-I18N

Image: JavaDoc Lib-I18N v0.7.2
Lib-I18N_JavaDoc_v0.7.2_2019-04-22_09-39.png

Download

Current version is 0.8.0. Main points in this release are:

  • Implement a demo which shows how easy an application becomes multilingual in four steps 😄 .
  • Extend the ReadMe with a new chapter 'Demo'.
  • Fix some minor bugs (test files are copied into the .jar file).

Maven coordinates
In context from a Maven project you can use following maven coordinates:

<dependencies>
    <dependency>
        <groupId>com.github.naoghuman</groupId>
        <artifactId>lib-i18n</artifactId>
        <version>0.8.0</version>
    </dependency>

    <!-- optional -->
    <dependency>
        <groupId>com.github.naoghuman</groupId>
        <artifactId>lib-logger</artifactId>
        <version>0.6.0</version>
    </dependency>
</dependencies>

Download:

An overview about all existings releases can be found here:

  • Overview from all releases in Lib-I18N.

Requirements

In the library are following libraries registered as dependencies:

Installation

Install the project in your preferred IDE

Contribution

  • If you find a Bug I will be glad if you could report an Issue.
  • If you want to contribute to the project plz fork the project and do a Pull Request.

License

The project Lib-I18n is licensed under General Public License 3.0.

Autor

The project Lib-I18n is maintained by me, Peter Rogge. See Contact.

Contact

You can reach me under [email protected].

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].