Multilingual support is integrated in JVx´s core components. Each component allows the translation of text without further effort. All components that display text, such as Button, Menu, MenuItem, or Label, individually handle the translation of the displayed text.

The developer only has to translate user-defined outputs, such as messages, questions, error messages, etc. A single method call, or ideally the translation of the text itself, is sufficient.

The translation mechanism does not require special text keys. We recommend developing the application in one language and creating the translation separately, either in parallel or after completion.

Usage

All of the text in an application we have created is in German. However, we just found out that English also has to be supported. This requirement was not known at the time of development.

The following source code represents a frame with a table, groupbox, and buttons:

DBEditFrame.java
public class DBEditFrame extends UIInternalFrame
{
    ...
    ...
 
    /**
     * Initializes the UI.
     * <p/>
     * @throws Exception if the initialization throws an error
     */
    private void initializeUI() throws Exception
    {
        UIGroupPanel group = new UIGroupPanel();
        group.setText("Alle Kontakte");
        group.setLayout(new UIBorderLayout());
 
        UIGroupPanel groupBut = new UIGroupPanel();
        groupBut.setText("Optionen");
        group.setLayout(new UIFlowLayout());
 
        UITable table = new UITable();
        table.setDataBook(rdbContacts);
 
        UIButton butNew = new UIButton("Neuer Kontakt");
        UIButton butDel = new UIButton("Löschen");
 
        group.add(table);
 
        groupBut.add(butNew);
        groupBut.add(butDel);
 
        //same behaviour as centered component in BorderLayout 
        setLayout(new UIBorderLayout());
        add(group, UIBorderLayout.CENTER);
        add(groupBut, UIBorderLayout.EAST);
 
        setTitle("Kontakte");
        setSize(new UIDimension(600, 500));
    }
 
    ...
    ...
}    // DBEditFrame

The translation can be defined centrally or by component. “By component” means that each component can use different translations for identical texts. A central translation always uses the same translation for identical texts. If a component does not use its own translation, a translation is automatically requested from the parent component.

In this case the translation is defined centrally at the highest (i.e. application) level:

private void loadTranslation()
{
    InputStream isTranslation = null;
 
    try
    {
        //load the locale specific translation
        isTranslation = ResourceUtil.getResourceAsStream
                        ("/apps/firstapp/translation_en.xml");
 
        //load the default translation
        if (isTranslation != null)
        {
            TranslationMap map = new TranslationMap();
 
            Properties properties = new Properties();
 
            properties.loadFromXML(isTranslation);
 
            map.setAsProperties(properties);
 
            getLauncher().setTranslation(map);
        }
    }
    catch (Exception e)
    {
        debug(e);
    }
    finally
    {
        if (isTranslation != null)
        {
            try
            {
                isTranslation.close();
            }
            catch (Exception e)
            {
                //nothing to be done
            }
        }
    }
}

At a minimum, the translation file contains the following:

translation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
 
<properties>
 
  <!-- application translations -->
  <entry key="Alle Kontakte">All contacts</entry>
  <entry key="Optionen">Options</entry>
  <entry key="Neuer Kontakt">New contact</entry>
  <entry key="Löschen">Delete</entry>
  <entry key="Kontakte">Contacts</entry>
 
</properties>


Note

The showcase application allows switching between German and English. A full integration of the translation can be viewed in the source code.

The following translation file is used:

translation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
 
<properties>
 
  <!-- the login translation -->
  <entry key="Showcase application*">Showcase Applikation*</entry>
 
  <entry key="Login">Anmeldung</entry>
  <entry key="Welcome">Willkommen</entry>
  <entry key="Change password">Passwort ändern</entry>
  <entry key="  Checking login credentials ">  Anmeldeinformationen prüfen </entry>
  <entry key="Session expired!">Sitzung ist abgelaufen!</entry>
  <entry key="Password changed successful!">Passwort wurde geändert!</entry>
  <entry key="Please enter and confirm the new password.">Bitte ein neues Password eingeben und bestätigen.</entry>
  <entry key="Please enter your username and passwords.">Bitte Ihren Benutzernamen und Passwörter eingeben.</entry>
  <entry key="Please enter your username and password.">Bitte Ihren Benutzernamen und Passwort eingeben.</entry>
 
  <entry key="Username:">Benutzername:</entry>
  <entry key="Password:">Passwort:</entry>
  <entry key="Password (new):">Passwort (neu):</entry>
  <entry key="Password (confirm):">Passwort (bestätigen):</entry>
 
  <entry key="Logon">Anmelden</entry>
  <entry key="Change">Ändern</entry>
  <entry key="Cancel">Abbruch</entry>
 
  <!-- the menu translation -->
  <entry key="File">Datei</entry>
  <entry key="Login">Anmeldung</entry>
  <entry key="Logout">Abmelden</entry>
  <entry key="Change password">Passwort ändern</entry>
  <entry key="Exit">Beenden</entry>
  <entry key="E">B</entry>
 
  <entry key="Edit">Bearbeiten</entry>
  <entry key="Save">Speichern</entry>
  <entry key="S">S</entry>
  <entry key="Undo">Rückgängig</entry>
  <entry key="Redo">Wiederherstellen</entry>
  <entry key="Reload">Aktualisieren</entry>
 
  <entry key="Window">Fenster</entry>
  <entry key="Tab view">Karteireiter Ansicht</entry>
  <entry key="Frame view">Fenster Ansicht</entry>
  <entry key="Close all windows">Alle Fenster schließen</entry>
 
  <entry key="Help">Hilfe</entry>
  <entry key="Help contents">Inhaltsverzeichnis</entry>
  <entry key="Help about">Hilfe zu...</entry>
  <entry key="About...">Über...</entry>
  <entry key="Create help">Hilfe generieren</entry>
 
  <!-- about window -->
  <entry key="Application information*">Applikationsinformationen*</entry>
  <entry key="Click on the tabs below to get additional information.">Die Karteireiter beinhalten zusätzliche Informationen.</entry>
 
  <entry key="About">Über</entry>
  <entry key="System">System</entry>
  <entry key="Log">Log</entry>
  <entry key="Used logger">Verwendete Logger</entry>
  <entry key="Log level">Log Stufe</entry>
  <entry key="Connection">Verbindung</entry>
 
  <entry key="Parameter">Parameter</entry>
  <entry key="Value">Wert</entry>
 
  <entry key="OK">OK</entry>
 
  <!-- message window -->
  <entry key="Information">Information</entry>
  <entry key="Warning">Warnung</entry>
  <entry key="Error">Fehler</entry>
  <entry key="Question">Frage</entry>
 
  <entry key="OK">OK</entry>
  <entry key="Cancel">Abbruch</entry>
  <entry key="Yes">Ja</entry>
  <entry key="No">Nein</entry>
 
  <!-- error window -->
  <entry key="Cause(s) of failure">Fehlerursache(n)</entry>
 
  <entry key="OK">OK</entry>
  <entry key="Details">Details</entry>
 
  <!-- download -->
  <entry key="Save as...">Speichern unter...</entry>
 
  <!-- upload -->
  <entry key="Open file">Datei öffnen</entry>
  <entry key="Please choose the file:">Bitte wählen Sie die gewünschte Datei:</entry>
  <entry key="Upload">Upload</entry>
 
  <!-- general messages -->
  <entry key="An error occurred during storing the data!*Would you nevertheless like to leave the window?">Beim Speichern der Daten ist ein Fehler aufgetreten! Möchten Sie dennoch das Fenster verlassen?</entry>
 
  <!-- security -->
  <entry key="Invalid password for '*' and application '*'">Ungültiges Passwort für Benutzer '*0'</entry>
  <entry key="User '*' is expired for application '*'">Der Benutzer '*0' ist nicht mehr gültig!</entry>
  <entry key="User '*' is inactive for application '*'">Der Benutzer '*0' wurde deaktiviert!</entry>
  <entry key="User '*' was not found for application '*'">Der Benutzer '*0' ist unbekannt!</entry>
  <entry key="Authentication for user '*' and application '*' is not possible">Das Sicherheitssystem kann keine Anmeldung durchführen!</entry>
  <entry key="Old password of '*' for application '*' is invalid">Das alte Passwort ist ungültig!</entry>
  <entry key="Error while changing password of '*' for application '*'">Das Sicherheitssystem kann die Passwort Änderung nicht durchführen!</entry>
  <entry key="The old and new password are the same">Das neue Passwort muss sich vom alten Passwort unterscheiden!</entry>
  <entry key="Please change your password">Bitte ändern Sie Ihr Passwort!</entry>
  <entry key="The passwords are different!">Die neuen Passwörter sind unterschiedlich!</entry>
  <entry key="The old and new password are empty">Das neue Passwort darf nicht "leer" sein!</entry>
 
  <entry key="Parameter 'driver' is missing for application '*'">Konfigurationsfehler: Fehlende Bezeichnung des Datenbanktreibers!</entry>
  <entry key="Parameter 'url' is missing for application '*'">Konfigurationsfehler: Fehlender Verbindungsdeskriptor!</entry>
  <entry key="Parameter 'username' is missing for application '*'">Konfigurationsfehler: Datenbank Anmeldedaten sind ungültig!</entry>
  <entry key="Parameter 'password' is missing for application '*'">Konfigurationsfehler: Datenbank Anmeldedaten sind ungültig!</entry>
  <entry key="JDBC driver '*' for application '*' was not found!">Konfigurationsfehler: Datenbanktreiber wurde nicht gefunden!</entry>
  <entry key="Can not open database connection with '*' for application '*'">Die Verbindung zur Datenbank kann nicht hergestellt werden!</entry>
 
  <entry key="Error during instantiation of security manager">Der Sicherheitsmanager kann nicht verwendet werden!</entry>
  <entry key="Session expired*">Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an!</entry>
  <entry key="Invalid session id '*'">Ungültige Sitzungskennung! Die Sitzung ist nicht länger gültig!</entry>
 
  <entry key="Unknown method '*'">Die Methode '*' wurde nicht gefunden!</entry>
  <entry key="Unknown object '*'">Das Objekt '*' wurde nicht gefunden!</entry>
  <entry key="Object '*' was not initialized!">Das Objekt '*' wurde nicht initialisiert!</entry>
  <entry key="Missing instance name">Undefinierte Objektbezeichnung!</entry>
 
  <entry key="No session for call '*'">Die Sitzung wurde nicht gefunden!</entry>
  <entry key="Session is already open!">Die Sitzung wurde bereits geöffnet!</entry>
  <entry key="Call back is not allowed!">Ein asynchroner Aufruf ist nicht erlaubt!</entry>
  <entry key="Invalid request parameters!">Die Server Anfrage enthält ungültige Parameter!</entry>
  <entry key="Invalid serializer '*'">Die Serialisierung für die Server Anfragen wurde nicht gefunden!</entry>
  <entry key="Invalid stream identifier '*'">Ungültige Server-Anfragekennung!</entry>
 
  <entry key="Error opening workscreen '">Die Maske '*' wurde nicht gefunden!</entry>
  <entry key="It is not allowed to open the work-screen '*'">Aufgrund von Sicherheitseinstelllug ist es nicht erlaubt die Maske zu öffnen!</entry>
 
  <entry key="Read timed out">Die Kommunikation zum Server wurde unterbrochen!</entry>
 
  <!-- application specific -->
  <entry key="Insert">Einfügen</entry>
  <entry key="Delete">Löschen</entry>
  <entry key="Export">Exportieren</entry>
 
  <entry key="Contact">Kontakt</entry>
  <entry key="Contacts">Kontakte</entry>
  <entry key="Schooling">Ausbildung</entry>
  <entry key="Education">Schulung</entry>
  <entry key="Educations">Schulungen</entry>
  <entry key="Master data">Stammdaten</entry>
 
  <entry key="Search">Suchen</entry>
  <entry key="Salutation">Anrede</entry>
  <entry key="Academic title">Titel</entry>
  <entry key="First name">Vorname</entry>
  <entry key="Last name">Nachname</entry>
  <entry key="Street">Strasse</entry>
  <entry key="Country">Land</entry>
  <entry key="ZIP">PLZ</entry>
  <entry key="Town">Ort</entry>
  <entry key="DoB">Geb.</entry>
  <entry key="Social security nr">SVNr</entry>
  <entry key="Health insurance">Versicherung</entry>
  <entry key="Filename">Dateiname</entry>
  <entry key="Image">Bild</entry>
 
  <entry key="Language">Sprache</entry>
  <entry key="User interface">Benutzeroberfläche</entry>
  <entry key="Tables">Tabellen</entry>
  <entry key="Components">Komponenten</entry>
 
  <entry key="Scrollable">Blättern</entry>
  <entry key="Top*">Oben*</entry>
  <entry key="Left*">Links*</entry>
  <entry key="Right*">Rechts*</entry>
  <entry key="Bottom*">Unten*</entry>
  <entry key="Close me*">Schließen*</entry>
  <entry key="Drag me*">Verschieben*</entry>
  <entry key="Text components">Text Komponenten</entry>
  <entry key="Locked">Gesperrt</entry>
  <entry key="Default">Standard</entry>
  <entry key="Not editable">Nicht änderbar</entry>
  <entry key="Not editable * disabled">Nicht änderbar * Deaktiviert</entry>
  <entry key="Textfield">Textfeld</entry>
  <entry key="Textfield (color)">Textfeld (farbig)</entry>
  <entry key="Password">Passwort</entry>
  <entry key="Combo Base (String)">Auswahl (Text)</entry>
  <entry key="Combo Base (Date)">Auswahl (Datum)</entry>
  <entry key="Textarea">Textbereich</entry>
  <entry key="Tabbed view">Tab Ansicht</entry>
  <entry key="Control frame">Kontroll Fenster</entry>
  <entry key="Closable frame">Schließbares Fenster</entry>
  <entry key="Modal frame">Modales Fenster</entry>
  <entry key="Open MODAL frame">MODALES Fenster öffnen</entry>
  <entry key="Close">Schließen</entry>
  <entry key="Copy">Kopieren</entry>
  <entry key="Enabled">Aktiviert</entry>
  <entry key="Selected">Gewählt</entry>
  <entry key="Selected disabled">Gewählt deaktiviert</entry>
  <entry key="No border">Kein Rahmen</entry>
  <entry key="Toggle Button">Feststell Button</entry>
  <entry key="Messages">Nachrichten</entry>
 
  <entry key="New">Neu</entry>
  <entry key="Sub disabled">Sub deaktiviert</entry>
  <entry key="Simple">Einfach</entry>
  <entry key="Simple">Einfach</entry>
  <entry key="Checkbox disabled">Checkbox deaktiviert</entry>
  <entry key="Disabled">Deaktiviert</entry>
 
  <entry key="New detail">Neuer Detail Datensatz</entry>
 
  <entry key="State">Bundesland</entry>
  <entry key="District">Bezirk</entry>
 
  <entry key="Detail of Master">Detail zum Master</entry>
  <entry key="Detail of Detail">Detail zum Detail</entry>
 
  <entry key="Show info">Information anzeigen</entry>
  <entry key="Show warning">Warnung anzeigen</entry>
  <entry key="Show question">Frage anzeigen</entry>
  <entry key="Show error">Fehlermeldung anzeigen</entry>
  <entry key="Show exception">Ausnahmefall anzeigen</entry>
 
  <entry key=" A simple Info message ! "> Eine einfache Information ! </entry>
  <entry key=" I think it's ok to do... ! "> Es sollte in Ordnung sein ... ! </entry>
  <entry key=" Save all changes ? "> Alle Änderungen speichern ? </entry>
  <entry key=" An error occured ! "> Ein Fehler trat auf ! </entry>
  <entry key="This is an exception!">Ein unerwarteter Fehler!</entry>
 
</properties>

The definition:

<entry key="Invalid password for '*' and application '*'">Ungültiges Passwort für Benutzer '*0'</entry>

demonstrates the wildcard mechanism for translations.

Variable text passages are defined using *. If multiple wildcards are used, text can be accessed via index (beginning with 0).