Для интернационализации вы должны использовать сопутствующий объект, чтобы получить соответствующий перевод в любом месте вашего приложения. Прежде всего, ваш класс перевода должен знать, какой именно язык / язык выбран. Для этого я использую перечисление с возможными локалями для приложения:
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
}
Если вам нужны какие-либо объяснения или это неясно. Просто спроси! Это просто записано, может быть, я забыл кое-что объяснить.