Ein kleines Beispiel, wie man eine ComboBox mit JavaFX internationalisiert.
Der Code soll dabei möglichst generisch sein, um Wiederverwendbarkeit zu ermöglichen.
D.h., dass sowohl an den Item-Type als auch an die Umsetzung der Internationalisierung innerhalb des Programms keine besonderen Anforderungen gestellt werden.
LocalizedCellFactory
Im Folgenden sieht man die dafür nötige Umsetzung einer CellFactory:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| import java.util.*;
import java.util.function.*;
import javafx.util.*;
import javafx.scene.control.*;
import javafx.beans.property.StringProperty;
public class LocalizedCellFactory<T> implements Callback<ListView<T>, ListCell<T>> {
private final Function<T, StringProperty> localisation;
public LocalizedCellFactory(final Function<T, StringProperty> localisation) {
this.localisation = Objects.requireNonNull(localisation);
}
@Override
public ListCell<T> call(final ListView<T> tListView) {
return new ListCell<>() {
@Override
protected void updateItem(final T item, final boolean empty) {
super.updateItem(item, empty);
if (!empty) {
this.textProperty().bind(localisation.apply(item));
} else {
this.textProperty().unbind();
}
}
};
}
}
|
Der Factory übergibt man zu beginn eine Funktion, die für ein gegebenes Item eine StringProperty zurückgibt.
Diese Property sollte den Text zur Darstellung dieses Items enthalten - eine Property daher,
dass darüber immer der Text in der aktuellen Sprache bereitgestellt wird, auch wenn sich diese ändert, bei einem String wäre der Text fest.
Sobald sich die Item-Auswahl der ComboBox ändert, wird der Text der jeweiligen Cell an den Text für das entsprechende Item gebunden, wenn die Auswahl wieder aufgehoben wird, wird auch das Binding wieder aufgehoben.
Beispiel
Als Beispiel wird hier eine einfache ComboBox gezeigt, welche die Auswahlt zwischen zwei Währungen bietet.
Die Währungen sind dabei entsprechend den Konventionen im UPPERCASE geschrieben, in der UI soll aber nur der erste Buchstabe ein Großbuchstabe sein.
Der LocalizedCellFactory wird dafür eine Funktion übergeben, welche den Item-Namen in entsprechende Schreibweise umwandelt und diesen als StringProperty zurück gibt.
Damit der Text überall entsprechend angezeigt wird, wird dann sowohl die ButtonCell, als auch die CellFactory der ComboBox gesetzt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
public class Controller {
enum Currency {
DOLLAR, EURO;
}
@FXML
private ComboBox<Currency> comboBox;
public void initialize() {
comboBox.getItems().addAll(Currency.values());
LocalizedCellFactory<Currency> cellFactory = new LocalizedCellFactory<>(
item -> new SimpleStringProperty(capitalize(item))
);
comboBox.setButtonCell(cellFactory.call(null));
comboBox.setCellFactory(cellFactory);
}
private String capitalize(Currency currency) {
return currency.name().substring(0, 1).toUpperCase() + currency.name().substring(1).toLowerCase();
}
public void unselect() {
comboBox.setValue(null);
}
}
|