Demo i18n mit branch
Internationalisierung mit Branch
Internationalisierung (i18n)
- Internationalisierung ist der Prozess, eine Software so zu gestalten, dass sie in verschiedenen Sprachen und Regionen funktioniert.
-
Internationalisierung wird oft als
i18n
abgekürzt, da es 18 Buchstaben zwischeni
undn
gibt. - Internationalisierung beinhaltet die Übersetzung von Texten und die Anpassung von Formaten für verschiedene Sprachen und Regionen.
Demo Projekt
Das Demo-Projekt wird eine einfache Java-Applikation sein, die eine grafische Benutzeroberfläche (GUI) hat. Die Applikation wird einen Text und einen Button anzeigen. Der Text soll internationalisiert werden, um in verschiedenen Sprachen angezeigt zu werden, basierend auf der Nutzerauswahl.
Projektstruktur
src/main/java/
└── com
└── example
└── App.java
App.java
package com.example;
import javax.swing.*;
public class App {
public static void main(String[] args) {
JFrame frame = new JFrame("Demo App");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(e -> System.exit(0));
fileMenu.add(exitItem);
menuBar.add(fileMenu);
frame.setJMenuBar(menuBar);
JButton button = new JButton("Click Me");
frame.getContentPane().add(button);
frame.setVisible(true);
}
}
Schritt 1: Branch erstellen
git checkout -b i18n
Schritt 2: Internationalisierung hinzufügen
src/main/resources/
├── messages.properties
├── messages_de_DE.properties
└── messages_en_US.properties
messages_de_DE.properties
app.title=Demo-Anwendung
menu.file=Datei
menu.exit=Beenden
menu.settings=Einstellungen
button.clickMe=Klick Mich
messages_en_US.properties
app.title=Demo App
menu.file=File
menu.exit=Exit
menu.settings=Settings
button.clickMe=Click Me
App.java
package com.example;
import javax.swing.*;
import java.util.Locale;
import java.util.ResourceBundle;
public class App {
private static JFrame frame;
private static ResourceBundle messages = ResourceBundle
.getBundle("messages", Locale.forLanguageTag("en"));
public static void main(String[] args) {
frame = new JFrame(messages.getString("app.title"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu(messages.getString("menu.file"));
JMenuItem exitItem = new JMenuItem(messages.getString("menu.exit"));
exitItem.addActionListener(e -> System.exit(0));
fileMenu.add(exitItem);
JMenu settingsMenu = new JMenu(messages.getString("menu.settings"));
JMenuItem langEn = new JMenuItem("English");
JMenuItem langDe = new JMenuItem("Deutsch");
langEn.addActionListener(e -> switchLanguage("en-US"));
langDe.addActionListener(e -> switchLanguage("de-DE"));
settingsMenu.add(langEn);
settingsMenu.add(langDe);
App.java
menuBar.add(fileMenu);
menuBar.add(settingsMenu);
frame.setJMenuBar(menuBar);
JButton button = new JButton(messages.getString("button.clickMe"));
frame.getContentPane().add(button);
frame.setVisible(true);
}
private static void switchLanguage(String langTag) {
Locale locale = Locale.forLanguageTag(langTag);
messages = ResourceBundle.getBundle("messages", locale);
updateTexts();
}
private static void updateTexts() {
frame.setTitle(messages.getString("app.title"));
JMenuBar menuBar = frame.getJMenuBar();
menuBar.getMenu(0).setText(messages.getString("menu.file"));
menuBar.getMenu(0).getItem(0).setText(messages.getString("menu.exit"));
menuBar.getMenu(1).setText(messages.getString("menu.settings"));
JButton button = (JButton) frame.getContentPane().getComponent(0);
button.setText(messages.getString("button.clickMe"));
}
}
App.java
package com.example;
import javax.swing.*;
import java.util.Locale;
import java.util.ResourceBundle;
public class App {
private static JFrame frame;
private static ResourceBundle messages = ResourceBundle
.getBundle("messages", Locale.forLanguageTag("en"));
public static void main(String[] args) {
frame = new JFrame(messages.getString("app.title"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu(messages.getString("menu.file"));
JMenuItem exitItem = new JMenuItem(messages.getString("menu.exit"));
exitItem.addActionListener(e -> System.exit(0));
fileMenu.add(exitItem);
JMenu settingsMenu = new JMenu(messages.getString("menu.settings"));
JMenuItem langEn = new JMenuItem("English");
JMenuItem langDe = new JMenuItem("Deutsch");
langEn.addActionListener(e -> switchLanguage("en-US"));
langDe.addActionListener(e -> switchLanguage("de-DE"));
settingsMenu.add(langEn);
settingsMenu.add(langDe);
menuBar.add(fileMenu);
menuBar.add(settingsMenu);
frame.setJMenuBar(menuBar);
JButton button = new JButton(messages.getString("button.clickMe"));
frame.getContentPane().add(button);
frame.setVisible(true);
}
private static void switchLanguage(String langTag) {
Locale locale = Locale.forLanguageTag(langTag);
messages = ResourceBundle.getBundle("messages", locale);
updateTexts();
}
private static void updateTexts() {
frame.setTitle(messages.getString("app.title"));
JMenuBar menuBar = frame.getJMenuBar();
menuBar.getMenu(0).setText(messages.getString("menu.file"));
menuBar.getMenu(0).getItem(0).setText(messages.getString("menu.exit"));
menuBar.getMenu(1).setText(messages.getString("menu.settings"));
JButton button = (JButton) frame.getContentPane().getComponent(0);
button.setText(messages.getString("button.clickMe"));
}
}
Schritt 3: Testen
Die Funktionalität sollte nun getestet werden, um sicherzustellen, dass die Internationalisierung korrekt funktioniert.
Schritt 4: Änderungen überprüfen
git diff
Schritt 5: Änderungen zusammenführen
git checkout main
git merge i18n
Projektstruktur gesamt (maven)
MyProject/
│
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/
│ │ │ └── App.java
│ │ ├── resources/
│ │ │ └── messages_en_US.properties
│ │ │ └── messages_de_DE.properties
│ │ └── ...
│ └── test/
│ └── ...
├── pom.xml
└── ...
Fazit
- Branches sind ideal für die Entwicklung neuer Features, wie die Internationalisierung.
- Für die Internationalisierung (i18n) müssen für jeder Sprache eigene
messages.properties
-Dateien erstellt werden. -
ResourceBundle
wird verwendet, um die Texte in der richtigen Sprache zu laden. -
Locale
wird verwendet, um die Sprache zu definieren, z.B.en-US
oderde-DE
-
switchLanguage()
wird verwendet, um die Sprache zu wechseln. -
updateTexts()
wird verwendet, um die GUI-Elemente mit den neuen Texten zu aktualisieren. - Nicht behandelt: Rechts-nach-links-Sprachen, Pluralisierung, Datums- und Zeitformate.
Datums- und Zeitformate
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
public class DateFormatExample {
public static void main(String[] args) {
DateFormat dateFormat = DateFormat
.getDateInstance(DateFormat.LONG, Locale.GERMANY);
System.out.println("Datum in Deutschland: " +
dateFormat.format(new Date()));
DateFormat timeFormat = DateFormat
.getTimeInstance(DateFormat.SHORT, Locale.UK);
System.out.println("Uhrzeit im Vereinigten Königreich: " +
timeFormat.format(new Date()));
}
}
Datum in Deutschland: Freitag, 12. Mai 2024
Uhrzeit im Vereinigten Königreich: 15:30:00 PM
Zahlenformate
import java.text.NumberFormat;
import java.util.Locale;
public class NumberFormatExample {
public static void main(String[] args) {
NumberFormat numberFormat = NumberFormat
.getNumberInstance(Locale.FRANCE);
System.out.println("Zahl in Frankreich: " +
numberFormat.format(1234567.89));
NumberFormat percentFormat = NumberFormat
.getPercentInstance(Locale.US);
System.out.println("Prozentsatz in den USA: " +
percentFormat.format(0.75));
}
}
Zahl in Frankreich: 1 234 567,89
Prozentsatz in den USA: 75.00%
Währungsformate
import java.text.NumberFormat;
import java.util.Locale;
public class CurrencyFormatExample {
public static void main(String[] args) {
NumberFormat currencyFormat = NumberFormat
.getCurrencyInstance(Locale.JAPAN);
System.out.println("Preis in Japan: " +
currencyFormat.format(5000));
}
}
Preis in Japan: ¥5,000
Demo i18n mit branch
By Harald Haberstroh
Demo i18n mit branch
- 100