Skip to content

Commit e0991b9

Browse files
committed
chore: update translations
1 parent 29e23aa commit e0991b9

File tree

6 files changed

+1105
-0
lines changed

6 files changed

+1105
-0
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
sidebar_position: 11
3+
title: Localization
4+
sidebar_class_name: new-content
5+
_i18n_hash: 91f5af285113e5e76d50a201a2fbf88f
6+
---
7+
# Lokalisierung <DocChip chip='since' label='25.10' />
8+
9+
Komponenten, die das `LocaleObserver`-Interface implementieren, erhalten automatische Benachrichtigungen, wenn sich die Locale ändert. Dies ermöglicht es UI-Elementen, ihren Text, ihre Formatierung und andere locale-spezifische Inhalte ohne manuelle Koordination zu aktualisieren.
10+
11+
## Das `LocaleObserver`-Interface {#the-localeobserver-interface}
12+
13+
```java title="LocaleObserver.java"
14+
@FunctionalInterface
15+
public interface LocaleObserver extends Serializable {
16+
void onLocaleChange(LocaleEvent event);
17+
}
18+
```
19+
20+
Wenn eine Komponente dieses Interface implementiert, registriert webforJ automatisch:
21+
- Registriert die Komponente bei der Erstellung, um Ereignisse zur Änderung der Locale zu empfangen
22+
- Stornieren die Registrierung der Komponente beim Zerstören
23+
- Ruft `onLocaleChange()` auf, wann immer sich die Locale ändert
24+
25+
Diese Registrierung erfolgt über den Lebenszyklus der Komponente.
26+
27+
## Übersetzungen Handhaben {#handling-translations}
28+
29+
Wenn `onLocaleChange()` aufgerufen wird, erhalten Komponenten die neue Locale. Wie sie Übersetzungen laden und anwenden, liegt beim Entwickler. Häufige Ansätze sind:
30+
31+
- Java `ResourceBundle` mit Eigenschaftsdateien
32+
- Datenbankabfragen für Übersetzungen
33+
- Benutzerdefinierte Übersetzungsanbieter
34+
- Hardcodierte Maps für einfache Fälle
35+
36+
Dieses Beispiel verwendet `ResourceBundle`, das Übersetzungen in Eigenschaftsdateien speichert:
37+
38+
```
39+
messages.properties # Fallback/Standard
40+
messages_en.properties # Englisch
41+
messages_de.properties # Deutsch
42+
```
43+
44+
Eigenschaftsdateien enthalten Schlüssel-Wert-Paare:
45+
46+
```properties title="messages_en.properties"
47+
app.title=Mailbox
48+
menu.inbox=Inbox
49+
```
50+
51+
```properties title="messages_de.properties"
52+
app.title=Postfach
53+
menu.inbox=Posteingang
54+
```
55+
## Ändern der Locale {#changing-the-locale}
56+
57+
Verwenden Sie `App.setLocale()`, um die Locale der App zu ändern. Dies löst Benachrichtigungen an alle registrierten Beobachter aus:
58+
59+
```java
60+
App.setLocale(Locale.GERMAN);
61+
App.setLocale(Locale.forLanguageTag("fr"));
62+
```
63+
64+
Eine typische Implementierung könnte ein Dropdown oder eine Auswahlkomponente verwenden:
65+
66+
```java
67+
ChoiceBox languageSelector = new ChoiceBox();
68+
languageSelector.add("en", "Englisch");
69+
languageSelector.add("de", "Deutsch");
70+
languageSelector.add("fr", "Französisch");
71+
72+
languageSelector.onSelect(e -> {
73+
String lang = (String) e.getSelectedItem().getKey();
74+
Locale newLocale = Locale.forLanguageTag(lang);
75+
76+
App.setLocale(newLocale);
77+
});
78+
```
79+
80+
Wenn der Benutzer eine Sprache auswählt, wird `App.setLocale()` ausgelöst, und alle Komponenten, die `LocaleObserver` implementieren, erhalten die Aktualisierung.
81+
82+
## Implementieren von Beobachtern {#implementing-observers}
83+
84+
Wenn eine Komponente `LocaleObserver` implementiert, muss sie zwei Szenarien handhaben: die erste Anzeige mit der aktuellen Locale und die Aktualisierung, wenn sich die Locale ändert. Das folgende Beispiel demonstriert dieses Muster mit einer Komponente, die lokalisierten Text und Links anzeigt.
85+
86+
Die Komponente speichert Referenzen zu Elementen, die Übersetzungen benötigen. Bei der Konstruktion lädt sie die Übersetzungen der aktuellen Locale. Wenn sich die Locale ändert, wird `onLocaleChange()` ausgelöst, was die Komponente ermöglicht, Übersetzungen neu zu laden und ihren angezeigten Text zu aktualisieren.
87+
88+
```java title="TranslationService.java"
89+
import com.webforj.App;
90+
import org.springframework.context.MessageSource;
91+
import org.springframework.stereotype.Service;
92+
93+
@Service
94+
public class TranslationService {
95+
private final MessageSource messageSource;
96+
97+
public TranslationService(MessageSource messageSource) {
98+
this.messageSource = messageSource;
99+
}
100+
101+
public String get(String key) {
102+
return messageSource.getMessage(key, null, App.getLocale());
103+
}
104+
}
105+
```
106+
107+
```java title="Explore.java"
108+
public class Explore extends Composite<FlexLayout> implements LocaleObserver {
109+
private final TranslationService i18n;
110+
private FlexLayout self = getBoundComponent();
111+
private H3 titleElement;
112+
private Anchor anchor;
113+
private String titleKey;
114+
115+
public Explore(TranslationService i18n, String titleKey) {
116+
this.i18n = i18n;
117+
this.titleKey = titleKey;
118+
119+
self.addClassName("explore-component");
120+
self.setStyle("margin", "1em auto");
121+
self.setDirection(FlexDirection.COLUMN);
122+
self.setAlignment(FlexAlignment.CENTER);
123+
self.setMaxWidth(300);
124+
self.setSpacing(".3em");
125+
126+
Img img = new Img(String.format("ws://explore/%s.svg", titleKey), "mailbox");
127+
img.setMaxWidth(250);
128+
129+
String translatedTitle = i18n.get("menu." + titleKey.toLowerCase());
130+
titleElement = new H3(translatedTitle);
131+
132+
anchor = new Anchor("https://docs.webforj.com/docs/components/overview", i18n.get("explore.link"));
133+
anchor.setTarget("_blank");
134+
135+
self.add(img, titleElement, anchor);
136+
}
137+
138+
@Override
139+
public void onLocaleChange(LocaleEvent event) {
140+
titleElement.setText(i18n.get("menu." + titleKey.toLowerCase()));
141+
anchor.setText(i18n.get("explore.link"));
142+
}
143+
}
144+
```
145+
146+
Die Komponente speichert Referenzen zu Elementen, die übersetzten Inhalt anzeigen (`titleElement` und `anchor`). Übersetzungen werden im Konstruktor unter Verwendung der aktuellen Locale geladen. Wenn sich die Locale ändert, aktualisiert `onLocaleChange()` nur den Text, der übersetzt werden muss.
147+
148+
## Lebenszyklusverwaltung {#lifecycle-management}
149+
150+
Das Framework behandelt die Registrierung von Beobachtern automatisch über die Lebenszyklus-Hooks der Komponente:
151+
152+
- **Bei Erstellung**: Komponenten, die `LocaleObserver` implementieren, werden im `LocaleObserverRegistry` registriert
153+
- **Bei Zerstörung**: Komponenten werden abgemeldet, um Speicherlecks zu verhindern
154+
155+
Jede App-Instanz verwaltet ihr eigenes Beobachter-Register. Diese automatische Verwaltung bedeutet:
156+
157+
- Keine manuellen Registrierungs-/Abmeldungsaufrufe
158+
- Keine Speicherlecks durch zerstörte Komponenten
159+
- Thread-sichere gleichzeitige Benachrichtigungen
160+
161+
:::info Pro-App-Registry
162+
Jede App-Instanz verwaltet ihr eigenes Beobachter-Register. Beobachter, die in einer App registriert sind, erhalten keine Benachrichtigungen von anderen Apps, die im selben JVM laufen.
163+
:::
164+
165+
## `LocaleEvent` {#localeevent}
166+
167+
Das `LocaleEvent`, das an `onLocaleChange()` übergeben wird, bietet:
168+
169+
| Methode | Gibt zurück | Beschreibung |
170+
|---------|-------------|--------------|
171+
| `getLocale()` | `Locale` | Die neue Locale, die eingestellt wurde |
172+
| `getSource()` | `Object` | Die Komponente, die das Ereignis erhalten hat |
173+
174+
```java
175+
@Override
176+
public void onLocaleChange(LocaleEvent event) {
177+
Locale newLocale = event.getLocale();
178+
Object source = event.getSource();
179+
180+
// Komponente mit neuer Locale aktualisieren
181+
ResourceBundle bundle = ResourceBundle.getBundle("messages", newLocale);
182+
updateUI(bundle);
183+
}
184+
```
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
sidebar_position: 11
3+
title: Localization
4+
sidebar_class_name: new-content
5+
_i18n_hash: 91f5af285113e5e76d50a201a2fbf88f
6+
---
7+
# Localización <DocChip chip='since' label='25.10' />
8+
9+
Los componentes que implementan la interfaz `LocaleObserver` reciben notificaciones automáticas cuando el locale cambia. Esto permite que los elementos de la interfaz de usuario actualicen su texto, formato y otros contenidos específicos del locale sin necesidad de coordinación manual.
10+
11+
## La interfaz `LocaleObserver` {#the-localeobserver-interface}
12+
13+
```java title="LocaleObserver.java"
14+
@FunctionalInterface
15+
public interface LocaleObserver extends Serializable {
16+
void onLocaleChange(LocaleEvent event);
17+
}
18+
```
19+
20+
Cuando un componente implementa esta interfaz, webforJ registra automáticamente:
21+
- El componente al ser creado para recibir eventos de cambio de locale
22+
- El componente al ser destruido
23+
- Llama a `onLocaleChange()` cada vez que el locale cambia
24+
25+
Este registro ocurre a través del ciclo de vida del componente.
26+
27+
## Manejo de traducciones {#handling-translations}
28+
29+
Cuando se llama a `onLocaleChange()`, los componentes reciben el nuevo locale. Cómo cargan y aplican las traducciones depende del desarrollador. Los enfoques comunes incluyen:
30+
31+
- `ResourceBundle` de Java con archivos de propiedades
32+
- Consultas a bases de datos para traducciones
33+
- Proveedores de traducción personalizados
34+
- Mapas codificados para casos simples
35+
36+
Este ejemplo utiliza `ResourceBundle`, que almacena traducciones en archivos de propiedades:
37+
38+
```
39+
messages.properties # Predeterminado
40+
messages_en.properties # Inglés
41+
messages_de.properties # Alemán
42+
```
43+
44+
Los archivos de propiedades contienen pares clave-valor:
45+
46+
```properties title="messages_en.properties"
47+
app.title=Mailbox
48+
menu.inbox=Inbox
49+
```
50+
51+
```properties title="messages_de.properties"
52+
app.title=Postfach
53+
menu.inbox=Posteingang
54+
```
55+
## Cambiando el locale {#changing-the-locale}
56+
57+
Utiliza `App.setLocale()` para cambiar el locale de la aplicación. Esto desencadena notificaciones a todos los observadores registrados:
58+
59+
```java
60+
App.setLocale(Locale.GERMAN);
61+
App.setLocale(Locale.forLanguageTag("fr"));
62+
```
63+
64+
Una implementación típica podría utilizar un componente de lista desplegable o de selección:
65+
66+
```java
67+
ChoiceBox languageSelector = new ChoiceBox();
68+
languageSelector.add("en", "English");
69+
languageSelector.add("de", "Deutsch");
70+
languageSelector.add("fr", "Français");
71+
72+
languageSelector.onSelect(e -> {
73+
String lang = (String) e.getSelectedItem().getKey();
74+
Locale newLocale = Locale.forLanguageTag(lang);
75+
76+
App.setLocale(newLocale);
77+
});
78+
```
79+
80+
Cuando el usuario selecciona un idioma, se ejecuta `App.setLocale()`, y todos los componentes que implementan `LocaleObserver` reciben la actualización.
81+
82+
## Implementando observadores {#implementing-observers}
83+
84+
Cuando un componente implementa `LocaleObserver`, necesita manejar dos escenarios: la representación inicial con el locale actual y la actualización cuando el locale cambia. El siguiente ejemplo demuestra este patrón con un componente que muestra texto y enlaces localizados.
85+
86+
El componente almacena referencias a elementos que necesitan actualizaciones de traducción. Al ser construido, carga las traducciones del locale actual. Cuando el locale cambia, se dispara `onLocaleChange()`, lo que permite al componente recargar las traducciones y actualizar su texto mostrado.
87+
88+
```java title="TranslationService.java"
89+
import com.webforj.App;
90+
import org.springframework.context.MessageSource;
91+
import org.springframework.stereotype.Service;
92+
93+
@Service
94+
public class TranslationService {
95+
private final MessageSource messageSource;
96+
97+
public TranslationService(MessageSource messageSource) {
98+
this.messageSource = messageSource;
99+
}
100+
101+
public String get(String key) {
102+
return messageSource.getMessage(key, null, App.getLocale());
103+
}
104+
}
105+
```
106+
107+
```java title="Explore.java"
108+
public class Explore extends Composite<FlexLayout> implements LocaleObserver {
109+
private final TranslationService i18n;
110+
private FlexLayout self = getBoundComponent();
111+
private H3 titleElement;
112+
private Anchor anchor;
113+
private String titleKey;
114+
115+
public Explore(TranslationService i18n, String titleKey) {
116+
this.i18n = i18n;
117+
this.titleKey = titleKey;
118+
119+
self.addClassName("explore-component");
120+
self.setStyle("margin", "1em auto");
121+
self.setDirection(FlexDirection.COLUMN);
122+
self.setAlignment(FlexAlignment.CENTER);
123+
self.setMaxWidth(300);
124+
self.setSpacing(".3em");
125+
126+
Img img = new Img(String.format("ws://explore/%s.svg", titleKey), "mailbox");
127+
img.setMaxWidth(250);
128+
129+
String translatedTitle = i18n.get("menu." + titleKey.toLowerCase());
130+
titleElement = new H3(translatedTitle);
131+
132+
anchor = new Anchor("https://docs.webforj.com/docs/components/overview", i18n.get("explore.link"));
133+
anchor.setTarget("_blank");
134+
135+
self.add(img, titleElement, anchor);
136+
}
137+
138+
@Override
139+
public void onLocaleChange(LocaleEvent event) {
140+
titleElement.setText(i18n.get("menu." + titleKey.toLowerCase()));
141+
anchor.setText(i18n.get("explore.link"));
142+
}
143+
}
144+
```
145+
146+
El componente almacena referencias a elementos que muestran contenido traducido (`titleElement` y `anchor`). Las traducciones se cargan en el constructor utilizando el locale actual. Cuando el locale cambia, `onLocaleChange()` actualiza solo el texto que necesita traducción.
147+
148+
## Gestión del ciclo de vida {#lifecycle-management}
149+
150+
El marco maneja la registración de observadores automáticamente a través de los ganchos del ciclo de vida del componente:
151+
152+
- **Al crear**: Los componentes que implementan `LocaleObserver` se registran en `LocaleObserverRegistry`
153+
- **Al destruir**: Los componentes se desregistran para evitar fugas de memoria
154+
155+
Cada instancia de aplicación mantiene su propio registro de observadores. Esta gestión automática significa:
156+
157+
- No hay llamadas manuales de registro/desregistro
158+
- Sin fugas de memoria por componentes destruidos
159+
- Notificaciones concurrentes seguras para hilos
160+
161+
:::info Registro por aplicación
162+
Cada instancia de aplicación mantiene su propio registro de observadores. Los observadores registrados en una aplicación no reciben notificaciones de otras aplicaciones que se ejecutan en la misma JVM.
163+
:::
164+
165+
## `LocaleEvent` {#localeevent}
166+
167+
El `LocaleEvent` que se pasa a `onLocaleChange()` proporciona:
168+
169+
| Método | Devuelve | Descripción |
170+
|--------|---------|-------------|
171+
| `getLocale()` | `Locale` | El nuevo locale que se estableció |
172+
| `getSource()` | `Object` | El componente que recibió el evento |
173+
174+
```java
175+
@Override
176+
public void onLocaleChange(LocaleEvent event) {
177+
Locale newLocale = event.getLocale();
178+
Object source = event.getSource();
179+
180+
// Actualizar componente usando el nuevo locale
181+
ResourceBundle bundle = ResourceBundle.getBundle("messages", newLocale);
182+
updateUI(bundle);
183+
}
184+
```

0 commit comments

Comments
 (0)