import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
* kleine hilfsklasse könnte man auch wegoptimieren
* aaaaber pro ResourceBundle kann man verschiedene
* LocalizableComponent anmelden das müsste man sonst
* mit maps mit sets oder maps von listen lösen...
*
* ##OBSERVER-PATTERN## - BeobachtbaresObjekt
*/
class HelpBundle {
private ResourceBundle rBundle;
private Set<LocalizableComponent> lComponents;
public HelpBundle(ResourceBundle rBundle) {
this.rBundle = rBundle;
this.lComponents = new HashSet<LocalizableComponent>();
}
public void addLocalizableComponent(LocalizableComponent lComponent) {
lComponents.add(lComponent);
}
ResourceBundle getResourceBundle() {
return rBundle;
}
/**
* bescheid geben an alle angemeldeten beobachter
* ##OBSERVER-PATTERN## - Benachrichtigungen Abfeuern
*/
void notifyComponents(ResourceBundleHelper rbHelper) {
for (LocalizableComponent component : lComponents)
component.localeChanged(rbHelper, rBundle);
}
void setResourceBundle(ResourceBundle rBundle) {
this.rBundle = rBundle;
}
}
/**
* Beobachter Interface
*
* ##OBSERVER-PATTERN## - Beobachter
*/
interface LocalizableComponent {
/**
* wird aufgerufen wenn sprache sich ändert
* ##OBSERVER-PATTERN## - Benachrichtigungs Methode
*/
public void localeChanged(ResourceBundleHelper rbHelper,
ResourceBundle rBundle);
}
/**
* kontroller klasse bei der mehrere ResourceBundles auf einmal geändert werden
* können.
*
* ##OBSERVER-PATTERN## - Beobachtbares Objekt
*
*/
class ResourceBundleHelper {
private static Locale defaultLocale = Locale.getDefault();
private Map<String, HelpBundle> bundles;
private Locale locale;
private static final ResourceBundleHelper instance;
static {
instance = new ResourceBundleHelper(defaultLocale);
}
public static ResourceBundleHelper getInstance() {
return instance;
}
private ResourceBundleHelper(Locale locale) {
bundles = new HashMap<String, HelpBundle>();
this.locale = locale;
}
public void addLocalizableComponent(String bundleName,
LocalizableComponent lComponent) {
if (!bundles.containsKey(bundleName))
addRes(bundleName, getLocale());
HelpBundle hBundle = bundles.get(bundleName);
hBundle.addLocalizableComponent(lComponent);
}
private void addRes(String baseName, Locale locale) {
ResourceBundle rBundle = ResourceBundle.getBundle(baseName, locale);
bundles.put(baseName, new HelpBundle(rBundle));
}
public Locale getLocale() {
return locale;
}
public ResourceBundle getResourceBundle(String bundleName) {
return bundles.get(bundleName).getResourceBundle();
}
private void notifyListeners() {
for (String baseName : bundles.keySet()) {
HelpBundle hBundle = bundles.get(baseName);
hBundle.notifyComponents(this);
}
}
public void setLocale(Locale locale) {
if (!this.locale.equals(locale)) { // just a little performance tweak
this.locale = locale;
for (String bundleName : bundles.keySet()) {
HelpBundle hBundle = bundles.get(bundleName);
ResourceBundle rBundle = ResourceBundle.getBundle(bundleName,
locale);
hBundle.setResourceBundle(rBundle);
}
notifyListeners();
}
}
}
/**
* TEST CLASS
*
* ##OBSERVER-PATTERN## - Konkreter Beobachter
*
*/
public class ResTest extends JFrame
implements LocalizableComponent, ActionListener {
private static final String LOCALIZED_FRAME_TITLE = "Frame.title";
private static final String LOCALIZED_LANG_DE = "lang.de";
private static final String LOCALIZED_LANG_EN = "lang.en";
private static final String RESOURCE_BUNDLE_LANG = "lang";
public static void main(String[] args) {
new ResTest().setVisible(true);
}
private JButton deButton = new JButton();
private JButton enButton = new JButton();
public ResTest() {
super();
setLayout(new GridLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(deButton);
add(enButton);
deButton.addActionListener(this);
enButton.addActionListener(this);
initLocalizedComponents();
}
public void actionPerformed(ActionEvent e) {
ResourceBundleHelper rbh = ResourceBundleHelper.getInstance();
Locale locale = rbh.getLocale();
if (e.getSource().equals(enButton))
locale = Locale.ENGLISH;
if (e.getSource().equals(deButton))
locale = Locale.GERMAN;
rbh.setLocale(locale);
}
private void initLocalizedComponents() {
ResourceBundleHelper rbh = ResourceBundleHelper.getInstance();
/**
* ##OSERVER-PATTERN## - Konkreten Beobachter registrieren
* in diesem Fall das Fenster nur einmal.
* Statt Fenster und je 2 Knöpfe.
*/
rbh.addLocalizableComponent(RESOURCE_BUNDLE_LANG, this);
localeChanged(rbh, rbh.getResourceBundle(RESOURCE_BUNDLE_LANG));
}
/**
* ##OSERVER-PATTERN## - Konkrete Benachrichtigung
*/
public void localeChanged(ResourceBundleHelper rbHelper,
ResourceBundle rBundle) {
setTitle(rBundle.getString(LOCALIZED_FRAME_TITLE));
deButton.setText(rBundle.getString(LOCALIZED_LANG_DE));
enButton.setText(rBundle.getString(LOCALIZED_LANG_EN));
}
}