Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 如何在FX中使用国际化_Kotlin_Internationalization_Tornadofx - Fatal编程技术网

Kotlin 如何在FX中使用国际化

Kotlin 如何在FX中使用国际化,kotlin,internationalization,tornadofx,Kotlin,Internationalization,Tornadofx,我正在尝试使用TornadFX框架在Kotlin应用程序中使用国际化 我已经创建了一个属性文件,并根据所选语言加载了正确的文件。但是,当我想要更改正在运行的应用程序中的语言时,UI不会相应地更新。对于国际化,您应该使用伴生对象来获取应用程序中任何位置的相关翻译。 首先,您的翻译类应该知道实际选择的语言/区域设置。为此,我将枚举与应用程序的可能区域设置一起使用: fun setLocale(locale: SupportedLocale) { if (SupportedLocale.suppo

我正在尝试使用TornadFX框架在Kotlin应用程序中使用国际化


我已经创建了一个属性文件,并根据所选语言加载了正确的文件。但是,当我想要更改正在运行的应用程序中的语言时,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类)