gpt4 book ai didi

internationalization - 在 JavaFX 中更改语言时如何重新加载屏幕?

转载 作者:行者123 更新时间:2023-12-04 23:51:50 26 4
gpt4 key购买 nike

好吧,我是 java 和 fxml 的初学者。

我创建了一个应用程序,需要更改屏幕语言。我有带有国际化键的文件,但我不知道用更改后的语言重新加载屏幕。
该应用程序有一个菜单,其中有可用的语言。我只想在用户更改语言时刷新屏幕。

更改仍然是手动的,正如您在代码中看到的:(Main.java):

public class Main extends Application {

private Locale locale = new Locale("en", "US");
private Image icon = new Image("picture.jpg");

@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Home.fxml"), ResourceBundle.getBundle("label", locale));
Scene scene = new Scene(root);
stage.setTitle("GUI");
stage.getIcons().add(icon);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}

更改语言时,此代码位于 Controller 上:
    @FXML
private void btnMenuLanguageEnglishAction(ActionEvent event) {
this.locale = new Locale("en", "US");
}

@FXML
private void btnMenuLanguagePortuguesAction(ActionEvent event) {
this.locale = new Locale("pt", "BR");
}

如何将此区域设置发送到 main 并刷新屏幕?
我使用的方法会怎样?我试过一些我在网站上看到的,但没有人回答我的问题。

最佳答案

这是我的实现:

import javafx.fxml.FXMLLoader;
import javafx.geometry.NodeOrientation;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

/**
* Created by Fouad on 3/20/2015.
*/
public abstract class I18NController
{
private Stage primaryStage;

public void setPrimaryStage(Stage primaryStage){this.primaryStage = primaryStage;}
public Stage getPrimaryStage(){return primaryStage;}

public final void changeLanguage(I18NLanguage language) throws IOException
{
StateBundle stateBundle = new StateBundle();
onSaveState(stateBundle);

Locale locale = language.getLocale();
Locale.setDefault(locale);

ResourceBundle resourceBundle = getResourceBundle(locale);
URL fxml = getFXMLResource();
FXMLLoader loader = new FXMLLoader(fxml, resourceBundle);
Parent root = loader.load();

NodeOrientation nodeOrientation = language.getNodeOrientation();
root.setNodeOrientation(nodeOrientation);

primaryStage.setScene(new Scene(root));
primaryStage.sizeToScene();

I18NController newController = loader.getController();
newController.setPrimaryStage(primaryStage);

onLoadState(newController, language, resourceBundle, stateBundle);
}

protected abstract ResourceBundle getResourceBundle(Locale locale);
protected abstract URL getFXMLResource();
protected abstract void onSaveState(StateBundle stateBundle);
protected abstract void onLoadState(I18NController newController, I18NLanguage newLanguage, ResourceBundle resourceBundle, StateBundle stateBundle);

public static interface I18NLanguage
{
Locale getLocale();
NodeOrientation getNodeOrientation();
}

public static class StateBundle
{
private Map<String, Object> sMap = new HashMap<>();

StateBundle(){}

public void putData(String key, Object value)
{
sMap.put(key, value);
}

public <T> T getDate(String key, Class<T> type)
{
return type.cast(sMap.get(key));
}
}
}

您可以使用此类作为 Controller 的基类,如下所示:

JavaFXController.java:
public class JavaFXController extends I18NController implements Initializable
{
@FXML private DatePicker dpDate;
@FXML private RadioButton rdoArabic;
@FXML private RadioButton rdoEnglish;

// ...

@Override
public void initialize(URL location, ResourceBundle resources)
{
// ...

rdoEnglish.setOnAction(e ->
{
try
{
changeLanguage(AppSettings.Language.ENGLISH);
}
catch(IOException e1)
{
e1.printStackTrace();
}
});

rdoArabic.setOnAction(e ->
{
try
{
changeLanguage(AppSettings.Language.ARABIC);
}
catch(IOException e1)
{
e1.printStackTrace();
}
});
}

// ...

@Override
protected ResourceBundle getResourceBundle(Locale locale)
{
return ResourceBundle.getBundle("com/stackoverflow/gui/resources/JavaFXResourceBundle", locale, new UTF8Control());
}

@Override
protected URL getFXMLResource()
{
return getClass().getResource("resources/JavaFXDocument.fxml");
}

@Override
protected void onSaveState(StateBundle stateBundle)
{
LocalDate localDate = dpDate.getValue();
boolean isRdoArabicSelected = rdoArabic.isSelected();
boolean isRdoEnglishSelected = rdoEnglish.isSelected();

stateBundle.putData("localDate", localDate);
stateBundle.putData("isRdoArabicSelected", isRdoArabicSelected);
stateBundle.putData("isRdoEnglishSelected", isRdoEnglishSelected);
}

@Override
protected void onLoadState(I18NController newController, I18NLanguage newLanguage, ResourceBundle resourceBundle, StateBundle stateBundle)
{
JavaFXController controller = (JavaFXController) newController;
controller.getPrimaryStage().setTitle(resourceBundle.getString("window.title"));
NodeOrientation nodeOrientation = newLanguage.getNodeOrientation();

LocalDate localDate = stateBundle.getDate("localDate", LocalDate.class);
boolean isRdoArabicSelected = stateBundle.getDate("isRdoArabicSelected", Boolean.class);
boolean isRdoEnglishSelected = stateBundle.getDate("isRdoEnglishSelected", Boolean.class);

controller.dpDate.setValue(localDate);
controller.rdoArabic.setSelected(isRdoArabicSelected);
controller.rdoEnglish.setSelected(isRdoEnglishSelected);
}
}

AppSettings.java:
import com.parmajeyat.autobooking.gui.I18NController;
import javafx.geometry.NodeOrientation;

import java.util.Locale;

/**
* Created by Fouad on 2/7/2015.
*/
public final class AppSettings
{
private static final class Locales
{
public static final Locale SAUDI_AR_LOCALE = new Locale.Builder().setLanguageTag("ar-SA-u-nu-arab").build(); // nu is for numbers
public static final Locale SAUDI_EN_LOCALE = new Locale("en", "SA");
}

public static enum Language implements I18NController.I18NLanguage
{
ARABIC(Locales.SAUDI_AR_LOCALE, NodeOrientation.RIGHT_TO_LEFT),
ENGLISH(Locales.SAUDI_EN_LOCALE, NodeOrientation.LEFT_TO_RIGHT);

private Locale locale;
private NodeOrientation nodeOrientation;

Language(Locale locale, NodeOrientation nodeOrientation)
{
this.locale = locale;
this.nodeOrientation = nodeOrientation;
}

public Locale getLocale(){return locale;}
public NodeOrientation getNodeOrientation(){return nodeOrientation;}
}
}

UTF8Control.java:
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

/**
* Created by Fouad on 2/1/2015.
*/
public class UTF8Control extends ResourceBundle.Control
{
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException
{
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;

if(reload)
{
URL url = loader.getResource(resourceName);
if(url != null)
{
URLConnection connection = url.openConnection();
if(connection != null)
{
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
}
else
{
stream = loader.getResourceAsStream(resourceName);
}

if(stream != null)
{
try
{
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
}
finally
{
stream.close();
}
}

return bundle;
}
}

关于internationalization - 在 JavaFX 中更改语言时如何重新加载屏幕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21171249/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com