簡體   English   中英

如何在 tornadofx 中使用國際化

[英]How to use Internationalization in tornadofx

我正在嘗試使用 tornadofx 框架在 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 應用程序(還有 TornadoFX)中,您應該使用 StringBindings( https://docs.oracle.com/javase/8/javafx/api/javafx/beans/binding/StringBinding.html )例如將標簽文本屬性綁定到您的翻譯的字符串。 為此,我們將實現一個特殊的方法:

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"))

這是一個可運行的示例:

MyLang.kt

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
}

如果您需要任何解釋或不清楚。 只要問! 它只是寫下來,也許我忘了解釋什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM