优化语言设置 (#4362)
This commit is contained in:
@@ -38,6 +38,7 @@ import org.jackhuang.hmcl.ui.construct.ComponentList;
|
||||
import org.jackhuang.hmcl.ui.construct.ComponentSublist;
|
||||
import org.jackhuang.hmcl.ui.construct.MultiFileItem;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.i18n.Locales;
|
||||
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -177,8 +178,15 @@ public abstract class SettingsView extends StackPane {
|
||||
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
|
||||
languagePane.setLeft(left);
|
||||
|
||||
SupportedLocale currentLocale = I18n.getLocale();
|
||||
cboLanguage = new JFXComboBox<>();
|
||||
cboLanguage.setConverter(stringConverter(I18n::getName));
|
||||
cboLanguage.setConverter(stringConverter(locale -> {
|
||||
if (locale.isSameLanguage(currentLocale) || locale == Locales.DEFAULT)
|
||||
return locale.getDisplayName(currentLocale);
|
||||
else
|
||||
return locale.getDisplayName(currentLocale) + " - " + locale.getDisplayName(locale);
|
||||
}));
|
||||
|
||||
FXUtils.setLimitWidth(cboLanguage, 300);
|
||||
languagePane.setRight(cboLanguage);
|
||||
|
||||
|
||||
@@ -38,18 +38,18 @@ public final class I18n {
|
||||
resourceBundle = locale.getResourceBundle();
|
||||
}
|
||||
|
||||
public static SupportedLocale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public static boolean isUseChinese() {
|
||||
return locale.getLocale() == Locale.CHINA;
|
||||
return locale.getLocale().getLanguage().equals("zh");
|
||||
}
|
||||
|
||||
public static ResourceBundle getResourceBundle() {
|
||||
return resourceBundle;
|
||||
}
|
||||
|
||||
public static String getName(SupportedLocale locale) {
|
||||
return locale == Locales.DEFAULT ? resourceBundle.getString("lang.default") : locale.getResourceBundle().getString("lang");
|
||||
}
|
||||
|
||||
public static String i18n(String key, Object... formatArgs) {
|
||||
try {
|
||||
return String.format(getResourceBundle().getString(key), formatArgs);
|
||||
|
||||
@@ -32,46 +32,70 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class Locales {
|
||||
private Locales() {
|
||||
}
|
||||
|
||||
public static final SupportedLocale DEFAULT = new SupportedLocale(Locale.getDefault());
|
||||
public static final SupportedLocale DEFAULT = new SupportedLocale("def", Locale.getDefault()) {
|
||||
@Override
|
||||
public String getDisplayName(SupportedLocale inLocale) {
|
||||
try {
|
||||
return inLocale.getResourceBundle().getString("lang.default");
|
||||
} catch (Throwable e) {
|
||||
LOG.warning("Failed to get localized name for default locale", e);
|
||||
return "Default";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* English
|
||||
*/
|
||||
public static final SupportedLocale EN = new SupportedLocale(Locale.ROOT);
|
||||
public static final SupportedLocale EN = new SupportedLocale("en", Locale.ENGLISH);
|
||||
|
||||
/**
|
||||
* Spanish
|
||||
*/
|
||||
public static final SupportedLocale ES = new SupportedLocale(Locale.forLanguageTag("es"));
|
||||
public static final SupportedLocale ES = new SupportedLocale("es", Locale.forLanguageTag("es"));
|
||||
|
||||
/**
|
||||
* Russian
|
||||
*/
|
||||
public static final SupportedLocale RU = new SupportedLocale(Locale.forLanguageTag("ru"));
|
||||
public static final SupportedLocale RU = new SupportedLocale("ru", Locale.forLanguageTag("ru"));
|
||||
|
||||
/**
|
||||
* Japanese
|
||||
*/
|
||||
public static final SupportedLocale JA = new SupportedLocale(Locale.JAPANESE);
|
||||
public static final SupportedLocale JA = new SupportedLocale("ja", Locale.JAPANESE);
|
||||
|
||||
/**
|
||||
* Traditional Chinese
|
||||
*/
|
||||
public static final SupportedLocale ZH = new SupportedLocale(Locale.TRADITIONAL_CHINESE);
|
||||
public static final SupportedLocale ZH_HANT = new SupportedLocale("zh", Locale.forLanguageTag("zh-Hant"));
|
||||
|
||||
/**
|
||||
* Simplified Chinese
|
||||
*/
|
||||
public static final SupportedLocale ZH_CN = new SupportedLocale(Locale.SIMPLIFIED_CHINESE);
|
||||
public static final SupportedLocale ZH_HANS = new SupportedLocale("zh_CN", Locale.forLanguageTag("zh-Hans"));
|
||||
|
||||
/**
|
||||
* Wenyan (Classical Chinese)
|
||||
*/
|
||||
public static final SupportedLocale WENYAN = new SupportedLocale(Locale.forLanguageTag("lzh")) {
|
||||
public static final SupportedLocale WENYAN = new SupportedLocale("lzh", Locale.forLanguageTag("lzh")) {
|
||||
|
||||
@Override
|
||||
public String getDisplayName(SupportedLocale inLocale) {
|
||||
if (isChinese(inLocale.locale))
|
||||
return "文言";
|
||||
|
||||
String name = super.getDisplayName(inLocale);
|
||||
return name.equals("lzh") || name.equals("Literary Chinese")
|
||||
? "Classical Chinese"
|
||||
: name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatDateTime(TemporalAccessor time) {
|
||||
return WenyanUtils.formatDateTime(time);
|
||||
@@ -86,96 +110,94 @@ public final class Locales {
|
||||
}
|
||||
};
|
||||
|
||||
public static final List<SupportedLocale> LOCALES = List.of(DEFAULT, EN, ES, JA, RU, ZH_CN, ZH, WENYAN);
|
||||
public static final List<SupportedLocale> LOCALES = List.of(DEFAULT, EN, ES, JA, RU, ZH_HANS, ZH_HANT, WENYAN);
|
||||
|
||||
public static SupportedLocale getLocaleByName(String name) {
|
||||
if (name == null) return DEFAULT;
|
||||
switch (name.toLowerCase(Locale.ROOT)) {
|
||||
case "en":
|
||||
return EN;
|
||||
case "es":
|
||||
return ES;
|
||||
case "ja":
|
||||
return JA;
|
||||
case "ru":
|
||||
return RU;
|
||||
case "zh":
|
||||
return ZH;
|
||||
case "zh_cn":
|
||||
return ZH_CN;
|
||||
case "lzh":
|
||||
return WENYAN;
|
||||
default:
|
||||
return DEFAULT;
|
||||
|
||||
for (SupportedLocale locale : LOCALES) {
|
||||
if (locale.getName().equalsIgnoreCase(name))
|
||||
return locale;
|
||||
}
|
||||
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
public static String getNameByLocale(SupportedLocale locale) {
|
||||
if (locale == EN) return "en";
|
||||
else if (locale == ES) return "es";
|
||||
else if (locale == RU) return "ru";
|
||||
else if (locale == JA) return "ja";
|
||||
else if (locale == ZH) return "zh";
|
||||
else if (locale == ZH_CN) return "zh_CN";
|
||||
else if (locale == WENYAN) return "lzh";
|
||||
else if (locale == DEFAULT) return "def";
|
||||
else throw new IllegalArgumentException("Unknown locale: " + locale);
|
||||
public static boolean isEnglish(Locale locale) {
|
||||
return locale.getLanguage().equals("en") || locale.getLanguage().isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isChinese(Locale locale) {
|
||||
return locale.getLanguage().equals("zh") || locale.getLanguage().equals("lzh");
|
||||
}
|
||||
|
||||
@JsonAdapter(SupportedLocale.TypeAdapter.class)
|
||||
public static class SupportedLocale {
|
||||
private final String name;
|
||||
private final Locale locale;
|
||||
private ResourceBundle resourceBundle;
|
||||
private DateTimeFormatter dateTimeFormatter;
|
||||
|
||||
SupportedLocale(Locale locale) {
|
||||
SupportedLocale(String name, Locale locale) {
|
||||
this.name = name;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public String getDisplayName(SupportedLocale inLocale) {
|
||||
if (inLocale.locale.getLanguage().equals("lzh"))
|
||||
inLocale = ZH_HANT;
|
||||
return locale.getDisplayName(inLocale.getLocale());
|
||||
}
|
||||
|
||||
public ResourceBundle getResourceBundle() {
|
||||
ResourceBundle bundle = resourceBundle;
|
||||
|
||||
if (resourceBundle == null) {
|
||||
if (this != DEFAULT && this.locale == DEFAULT.locale) {
|
||||
bundle = DEFAULT.getResourceBundle();
|
||||
} else {
|
||||
bundle = ResourceBundle.getBundle("assets.lang.I18N", locale, new ResourceBundle.Control() {
|
||||
@Override
|
||||
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
|
||||
if (locale.getLanguage().equals("zh")) {
|
||||
boolean simplified;
|
||||
bundle = ResourceBundle.getBundle("assets.lang.I18N", locale, new ResourceBundle.Control() {
|
||||
@Override
|
||||
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
|
||||
if (locale.getLanguage().equals("zh")) {
|
||||
boolean simplified;
|
||||
|
||||
String script = locale.getScript();
|
||||
String region = locale.getCountry();
|
||||
if (script.isEmpty())
|
||||
simplified = region.equals("CN") || region.equals("SG");
|
||||
else
|
||||
simplified = script.equals("Hans");
|
||||
String script = locale.getScript();
|
||||
String region = locale.getCountry();
|
||||
if (script.isEmpty())
|
||||
simplified = region.equals("CN") || region.equals("SG");
|
||||
else
|
||||
simplified = script.equals("Hans");
|
||||
|
||||
if (simplified) {
|
||||
return List.of(
|
||||
Locale.SIMPLIFIED_CHINESE,
|
||||
Locale.CHINESE,
|
||||
Locale.ROOT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (locale.getLanguage().equals("lzh")) {
|
||||
if (simplified) {
|
||||
return List.of(
|
||||
locale,
|
||||
Locale.SIMPLIFIED_CHINESE,
|
||||
Locale.CHINESE,
|
||||
Locale.ROOT
|
||||
);
|
||||
}
|
||||
return super.getCandidateLocales(baseName, locale);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (locale.getLanguage().equals("lzh")) {
|
||||
return List.of(
|
||||
locale,
|
||||
Locale.CHINESE,
|
||||
Locale.ROOT
|
||||
);
|
||||
}
|
||||
|
||||
if (locale.getLanguage().equals("en")) {
|
||||
return List.of(Locale.ROOT);
|
||||
}
|
||||
|
||||
return super.getCandidateLocales(baseName, locale);
|
||||
}
|
||||
});
|
||||
resourceBundle = bundle;
|
||||
}
|
||||
|
||||
@@ -194,10 +216,15 @@ public final class Locales {
|
||||
return version.getSelfVersion();
|
||||
}
|
||||
|
||||
public boolean isSameLanguage(SupportedLocale other) {
|
||||
return this.getLocale().getLanguage().equals(other.getLocale().getLanguage())
|
||||
|| isChinese(this.getLocale()) && isChinese(other.getLocale());
|
||||
}
|
||||
|
||||
public static final class TypeAdapter extends com.google.gson.TypeAdapter<SupportedLocale> {
|
||||
@Override
|
||||
public void write(JsonWriter out, SupportedLocale value) throws IOException {
|
||||
out.value(getNameByLocale(value));
|
||||
out.value(value.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -766,7 +766,6 @@ java.installing=Installing Java
|
||||
java.uninstall=Uninstall Java
|
||||
java.uninstall.confirm=Are you sure you want to uninstall this Java? This action cannot be undone!
|
||||
|
||||
lang=English
|
||||
lang.default=Use System Locales
|
||||
|
||||
launch.advice=%s Do you still want to continue to launch?
|
||||
|
||||
@@ -772,7 +772,6 @@ java.installing=Instalando Java
|
||||
java.uninstall=Desinstalar Java
|
||||
java.uninstall.confirm=¿Está seguro de que desea desinstalar este Java? ¡Esta acción no se puede deshacer!
|
||||
|
||||
lang=Español
|
||||
lang.default=Usar idioma del sistema
|
||||
|
||||
launch.advice=%s ¿Todavía quieres continuar?
|
||||
|
||||
@@ -492,7 +492,6 @@ java.install.warning.invalid_character=名前に不正な文字が含まれて
|
||||
java.uninstall=このJavaをアンインストールする
|
||||
java.uninstall.confirm=本当にこのJavaをアンインストールしますか?この操作は元に戻せません!
|
||||
|
||||
lang=日本語
|
||||
lang.default=システム言語を使用する
|
||||
|
||||
launch.advice.java.auto=現在選択されているJavaVMは、ゲームの要件を満たしていません。適切なJavaVMを選択することを許可しますか?または、ゲーム設定で適切なJavaVMを選択することもできます。
|
||||
|
||||
@@ -510,7 +510,6 @@ java.installing=置爪哇
|
||||
java.uninstall=移除此爪哇
|
||||
java.uninstall.confirm=君真欲移除此爪哇乎?此舉不可復!
|
||||
|
||||
lang=文言
|
||||
lang.default=依械綱預定
|
||||
|
||||
launch.advice=%s 誠欲續啟?
|
||||
|
||||
@@ -768,7 +768,6 @@ java.installing=Установка Java
|
||||
java.uninstall=Удалить Java
|
||||
java.uninstall.confirm=Вы уверены, что хотите удалить эту Java? Это действие нельзя отменить!
|
||||
|
||||
lang=Русский
|
||||
lang.default=Использовать язык системы
|
||||
|
||||
launch.advice=%s Вы все еще хотите продолжить запуск?
|
||||
|
||||
@@ -575,7 +575,6 @@ java.installing=安裝 Java
|
||||
java.uninstall=移除此 Java
|
||||
java.uninstall.confirm=你確定要移除此 Java 嗎?此操作無法復原!
|
||||
|
||||
lang=繁體中文
|
||||
lang.default=使用系統語言
|
||||
|
||||
launch.advice=%s 是否繼續啟動?
|
||||
|
||||
@@ -585,7 +585,6 @@ java.installing=安装 Java
|
||||
java.uninstall=卸载此 Java
|
||||
java.uninstall.confirm=你确定要卸载此 Java 吗?此操作无法撤销!
|
||||
|
||||
lang=简体中文
|
||||
lang.default=跟随系统语言
|
||||
|
||||
launch.advice=%s 是否继续启动?
|
||||
|
||||
@@ -442,7 +442,7 @@ public class DefaultLauncher extends Launcher {
|
||||
pair("${library_directory}", repository.getLibrariesDirectory(version).getAbsolutePath()),
|
||||
pair("${classpath_separator}", File.pathSeparator),
|
||||
pair("${primary_jar}", repository.getVersionJar(version).getAbsolutePath()),
|
||||
pair("${language}", Locale.getDefault().toString()),
|
||||
pair("${language}", Locale.getDefault().toLanguageTag()),
|
||||
|
||||
// defined by HMCL
|
||||
// libraries_directory stands for historical reasons here. We don't know the official launcher
|
||||
|
||||
Reference in New Issue
Block a user