Kotlin 如何在FX中使用国际化
我正在尝试使用TornadFX框架在Kotlin应用程序中使用国际化Kotlin 如何在FX中使用国际化,kotlin,internationalization,tornadofx,Kotlin,Internationalization,Tornadofx,我正在尝试使用TornadFX框架在Kotlin应用程序中使用国际化 我已经创建了一个属性文件,并根据所选语言加载了正确的文件。但是,当我想要更改正在运行的应用程序中的语言时,UI不会相应地更新。对于国际化,您应该使用伴生对象来获取应用程序中任何位置的相关翻译。 首先,您的翻译类应该知道实际选择的语言/区域设置。为此,我将枚举与应用程序的可能区域设置一起使用: fun setLocale(locale: SupportedLocale) { if (SupportedLocale.suppo
我已经创建了一个属性文件,并根据所选语言加载了正确的文件。但是,当我想要更改正在运行的应用程序中的语言时,UI不会相应地更新。对于国际化,您应该使用伴生对象来获取应用程序中任何位置的相关翻译。 首先,您的翻译类应该知道实际选择的语言/区域设置。为此,我将枚举与应用程序的可能区域设置一起使用:
fun setLocale(locale: SupportedLocale) {
if (SupportedLocale.supportedLocals.contains(locale)) {
Locale.setDefault(locale.local)
actualLocal = locale.local
//Good practice would be to store it in a properties file to have the information after restart
} else {
//Throw a warning or sth with your preferred logger
}
}
然后,我们需要一个从资源包中获取特定字符串值的方法,如:
operator fun get(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String, vararg args: Any): String {
val bundle = ResourceBundle.getBundle(BUNDLE_NAME, actualLocal)
return MessageFormat.format(bundle.getString(key), *args)
}
在JavaFx应用程序(也叫TornadFX)中,您应该使用StringBindings()将标签文本属性绑定到翻译后的字符串。为此,我们将实施一种特殊方法:
fun createStringBinding(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String, vararg args: Any): StringBinding {
return Bindings.createStringBinding(Callable { get(key, *args) }, Settings.languageProperty())
}
现在,您可以像这样使用对象:
textProperty().bind(MyLang.createStringBinding("MyApp.MyTranslation"))
下面是一个可运行的示例:
迈朗
enum class SupportedLocale(val local:Locale) {
ENGLISH(Locale.ENGLISH),
GERMAN(Locale.GERMAN);
companion object {
val supportedLocals: List<SupportedLocale>
get() = SupportedLocale.values().toList()
}
}
class MyLang {
companion object {
private const val BUNDLE_NAME = "Language" //prefix of your resource bundle
private var actualLocal = Locale.getDefault()
fun setLocale(locale: SupportedLocale) {
if (SupportedLocale.supportedLocals.contains(locale)) {
Locale.setDefault(locale.local)
actualLocal = locale.local
//Good practice would be to store it in a properties file to have the information after restart
} else {
//Throw a warning or sth with your preferred logger
}
}
operator fun get(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String, vararg args: Any): String {
val bundle = ResourceBundle.getBundle(BUNDLE_NAME, actualLocal)
return MessageFormat.format(bundle.getString(key), *args)
}
fun createStringBinding(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String, vararg args: Any): StringBinding {
return Bindings.createStringBinding(Callable { get(key, *args) }, Settings.languageProperty())
}
}
}
fun main() {
println("My translation: " + MyLang.createStringBinding("MyApp.MyTranslation").get())
//The get() here is only to get the string for assign a property its not needed like in the example
}
enum类支持的语言环境(val local:Locale){
英语(Locale.ENGLISH),
德语(Locale.德语);
伴星{
val supportedLocals:列表
get()=SupportedLocale.values().toList()
}
}
迈朗班{
伴星{
private const val BUNDLE_NAME=“Language”//资源包的前缀
private var actualloc=Locale.getDefault()
fun setLocale(区域设置:SupportedLocale){
if(SupportedLocale.supportedLocals.contains(locale)){
Locale.setDefault(Locale.local)
actualLocal=locale.local
//好的做法是将其存储在属性文件中,以便在重新启动后获得信息
}否则{
//向你的首选记录器发出警告或其他信息
}
}
运算符fun get(@PropertyKey(resourceBundle=BUNDLE\u NAME)键:String,vararg args:Any):String{
val bundle=ResourceBundle.getBundle(bundle\u名称,实际本地)
return MessageFormat.format(bundle.getString(键),*args)
}
趣味createStringBinding(@PropertyKey(resourceBundle=BUNDLE\u NAME)键:String,vararg args:Any):StringBinding{
返回Bindings.createStringBinding(可调用{get(key,*args)},Settings.languageProperty())
}
}
}
主要内容(){
println(“我的翻译:+MyLang.createStringBinding(“MyApp.MyTranslation”).get())
//此处的get()仅用于获取字符串,以分配一个不需要的属性,如示例中所示
}
如果您需要任何解释或不清楚。问吧!只是写了下来,也许我忘了解释什么。非常感谢您的回答,很抱歉回复太晚。它帮助了我很多,并且在我现有的UI中也能正常工作。但我不知道如何更改running应用程序中的语言。例如,默认设置为SupportedLocale.ENGLISH,然后在我的应用程序中,我有一个按钮,可以使用MyLang.setLocale(SupportedLocale.GERMAN)将语言更改为德语,但是标签仍然以英语显示。您能在这里帮助我吗?另一点我不清楚的是
Settings.languageProperty()
在createStringBinding
函数中的用法。在我的代码中,我删除了它,它工作了,否则我会得到一个错误,languageProperty
是未知的。请确认您设置的局部函数是正确的。您是否将createStringBinding
绑定到textProperty?e、 g.对于视图中的菜单项menubutton{textProperty().bind(MyLang.createStringBinding(“MyApp.MyTranslation”))}
?当我在标签上使用textProperty().bind(MyLang.createStringBinding(“MyApp.MyTranslation”)}
时,它不会更新。我还创建了一个itemViewModel并在那里使用了绑定,但当我触发onRefresh()
函数时,它只是在更新(我使用的是tornadofx的workspace类)