package org.limewire.ui.swing.util;
import java.awt.Font;
import java.util.Locale;
import java.util.Map;
import javax.swing.UIManager;
import org.limewire.core.settings.ApplicationSettings;
import org.limewire.util.OSUtils;
import org.limewire.util.StringUtils;
public class LocaleUtils {
private LocaleUtils() {}
/** Returns the current locale in use. */
public static Locale getCurrentLocale() {
return new Locale(ApplicationSettings.LANGUAGE.get(),
ApplicationSettings.COUNTRY.get(),
ApplicationSettings.LOCALE_VARIANT.get());
}
/** Sets the locale based on whats in the preferences. */
public static void setLocaleFromPreferences() {
if (ApplicationSettings.LANGUAGE.get().equals("")) {
ApplicationSettings.LANGUAGE.set("en");
}
Locale locale = new Locale(ApplicationSettings.LANGUAGE.get(),
ApplicationSettings.COUNTRY.get(),
ApplicationSettings.LOCALE_VARIANT.get());
Locale.setDefault(locale);
StringUtils.setLocale(locale);
GuiUtils.setLocale(locale);
I18n.setLocale(locale);
}
/**
* Validates the locale, determining if the current locale's resources can
* be displayed using the current fonts. If not, then the locale is reset to
* English.
*
* This prevents the UI from appearing as all boxes.
*/
public static void validateLocaleAndFonts() {
// OSX can always display everything, and if it can't,
// we have no way of correcting things 'cause canDisplayUpTo
// is broken on it.
if (OSUtils.isMacOSX()) {
return;
}
String s = getCurrentLocale().getDisplayName();
if (!checkUIFonts("dialog", s)) {
// if it couldn't display, revert the locale to english.
ApplicationSettings.LANGUAGE.set("en");
ApplicationSettings.COUNTRY.set("");
ApplicationSettings.LOCALE_VARIANT.set("");
setLocaleFromPreferences();
}
}
/**
* Alters all Fonts in UIManager to use Dialog, to correctly display foreign
* strings.
*/
private static boolean checkUIFonts(String newFont, String testString) {
String[] comps = new String[] { "TextField.font", "PasswordField.font",
"TextArea.font", "TextPane.font", "EditorPane.font",
"FormattedTextField.font", "Button.font", "CheckBox.font",
"RadioButton.font", "ToggleButton.font", "ProgressBar.font",
"ComboBox.font", "InternalFrame.titleFont", "DesktopIcon.font",
"TitledBorder.font", "Label.font", "List.font",
"TabbedPane.font", "Table.font", "TableHeader.font",
"MenuBar.font", "Menu.font", "Menu.acceleratorFont",
"MenuItem.font", "MenuItem.acceleratorFont", "PopupMenu.font",
"CheckBoxMenuItem.font", "CheckBoxMenuItem.acceleratorFont",
"RadioButtonMenuItem.font",
"RadioButtonMenuItem.acceleratorFont", "Spinner.font",
"Tree.font", "ToolBar.font", "OptionPane.messageFont",
"OptionPane.buttonFont", "ToolTip.font", };
boolean displayable = false;
for (int i = 0; i < comps.length; i++)
displayable |= checkFont(comps[i], newFont, testString, false);
// Then do it the automagic way.
// note that this could work all the time (without requiring the above)
// if Java 1.4 didn't introduce Locales, and it could even still work
// if they offered a way to get all the keys of possible resources.
for (Map.Entry<Object, Object> next : UIManager.getDefaults().entrySet()) {
if (next.getValue() instanceof Font) {
Font f = (Font) next.getValue();
if (f != null && !newFont.equalsIgnoreCase(f.getName())) {
if (!FontUtils.canDisplay(f, testString)) {
f = new Font(newFont, f.getStyle(), f.getSize());
if (FontUtils.canDisplay(f, testString)) {
next.setValue(f);
displayable = true;
}
}
}
}
}
return displayable;
}
/** Updates the font of a given fontName to be newName. */
private static boolean checkFont(String fontName, String newName,
String testString, boolean force) {
boolean displayable = true;
Font f = UIManager.getFont(fontName);
if (f != null && !newName.equalsIgnoreCase(f.getName())) {
if (!FontUtils.canDisplay(f, testString) || force) {
f = new Font(newName, f.getStyle(), f.getSize());
if (FontUtils.canDisplay(f, testString))
UIManager.put(fontName, f);
else
displayable = false;
}
} else if (f != null) {
displayable = FontUtils.canDisplay(f, testString);
} else {
displayable = false;
}
return displayable;
}
}