Хочу реализовать адекватное переключение языков в приложении, чтобы сразу после нажатие кнопки "сменить язык" все компоненты автоматически поменяли название.
Пока что сделал так:
public void setEnglish(ActionEvent actionEvent) {
Main.locale = new Locale("en");
rb = ResourceBundle.getBundle("ua.javaFX.myprograms.address_book.bundles.Locale", Main.locale);
mainStage.setTitle(rb.getString("key.address_book"));
btnAdd.setText(rb.getString("key.add"));
btnEdit.setText(rb.getString("key.change"));
btnDelete.setText(rb.getString("key.delete"));
btnSearch.setText(rb.getString("key.search"));
btnLanguage.setText(rb.getString("key.language"));
btnEnglish.setText(rb.getString("key.english"));
btnRussian.setText(rb.getString("key.russian"));
}
Суть вопроса: есть какой-то цивилизованный способ для обновления содержания страницы?
Если я не ошибаюсь, в SWING таким является:
SwingUtilities.updateComponentTreeUI(frame);
Ответ
Для того, чтобы вам сделать такое, необходимо использовать bindings
Вам нужна resources factory :
public class ObservableResourceFactory {
private ObjectProperty
public StringBinding getStringBinding(String key) {
return new StringBinding() {
{ bind(resourcesProperty()); }
@Override
public String computeValue() {
return getResources().getString(key);
}
};
}
}
Далее, в своем коде можете написать такое
ObservableResourceFactory resourceFactory = .... ;
resourceBundle.setResources(...);
Label greetingLabel = new Label();
greetingLabel.textProperty().bind(resourceFactory.getStringBinding("greeting"));
И в любой момент, когда вы будет обновлять ресурсы
resourceFactory.setResources(...);
на лейбле текст будет меняться.
Вот пример, как это работает
import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ResourceBundleBindingExample extends Application {
private static final String RESOURCE_NAME = Resources.class.getTypeName() ;
private static final ObservableResourceFactory RESOURCE_FACTORY = new ObservableResourceFactory();
static {
RESOURCE_FACTORY.setResources(ResourceBundle.getBundle(RESOURCE_NAME));
}
@Override
public void start(Stage primaryStage) {
ComboBox
languageSelect.valueProperty().addListener((obs, oldValue, newValue) -> {
if (newValue != null) {
RESOURCE_FACTORY.setResources(ResourceBundle.getBundle(RESOURCE_NAME, newValue));
}
});
Label label = new Label();
label.textProperty().bind(RESOURCE_FACTORY.getStringBinding("greeting"));
BorderPane root = new BorderPane(null, languageSelect, null, label, null);
root.setPadding(new Insets(10));
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class LocaleCell extends ListCell
public static class ObservableResourceFactory {
private ObjectProperty
public StringBinding getStringBinding(String key) {
return new StringBinding() {
{ bind(resourcesProperty()); }
@Override
public String computeValue() {
return getResources().getString(key);
}
};
}
}
public static class Resources extends ListResourceBundle {
@Override
protected Object[][] getContents() {
return new Object[][] {
{"greeting", "Hello"}
};
}
}
public static class Resources_fr extends ListResourceBundle {
@Override
protected Object[][] getContents() {
return new Object[][] {
{"greeting", "Bonjour"}
};
}
}
public static void main(String[] args) {
launch(args);
}
}
P.S. ответ взят с английского SO
Комментариев нет:
Отправить комментарий