I thought about the best way to implement localisation with runtime in Swing.
I currently solve the problem like that:
JMenu menuData = new JMenu("Data");
menuData.setName("mainframe.menu.data"); // property key
localeChangedListener.add(menuData);
The LocaleChangedListener
:
public class SwingLocaleChangedListener implements LocaleChangedListener {
private ArrayList<AbstractButton> abstractButtons;
@Override
public void localeChanged(ResourceBundle rb) {
logger.info("Locale changed to '" + rb.getLocale() + "'");
for (AbstractButton b : abstractButtons) {
b.setText(rb.getString(b.getName()));
b.setComponentOrientation(ComponentOrientation.getOrientation(rb.getLocale())); //EDIT: Line added
}
}
public boolean add(AbstractButton b) {
initAbstractButtons();
return abstractButtons.add(b);
}
private void initAbstractButtons() {
if (abstractButtons == null) {
this.abstractButtons = new ArrayList<AbstractButton>();
}
}
}
And the registration of the Listener
:
public class GuiBundleManager {
private String filePrefix = "language.lang";
private ResourceBundle rb = null;
private LocaleChangedListener listener = null;
private static GuiBundleManager instance = null;
private GuiBundleManager() {
setLocale(Locale.getDefault());
}
public String getString(String key) {
return rb.getString(key);
}
public String[] getStringArray(String key) {
return rb.getStringArray(key);
}
public Locale getLocale() {
return rb.getLocale();
}
public void setLocale(Locale l) {
rb = ResourceBundle.getBundle(filePrefix, l);
if (listener != null) {
listener.localeChanged(rb);
}
}
public LocaleChangedListener getLocaleChangedListener() {
return listener;
}
public void setLocaleChangedListener(LocaleChangedListener listener) {
this.listener = listener;
if (listener != null) {
listener.localeChanged(rb);
}
}
public static GuiBundleManager get() {
if (instance == null) {
instance = new GuiBundleManager();
}
return instance;
}
}
Another way I'm thinking of is using Component.setLocale()
combined with an PropertyChangedListener
:
public abstract class GUIComponentFactory {
public JLabel createLocalisedJLabel(final String key) {
final JLabel label = new JLabel(GuiBundleManager.get().getString(key));
label.addPropertyChangeListener("locale", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
label.setText(GuiBundleManager.get().getString(key));
label.setComponentOrientation(ComponentOrientation.getOrientation(e.getNewValue())); //Edit: Line added
for(Component c : getComponents()){
c.setLocale(e.getNewValue());
}
}
});
return label;
}
.
.
.
}