2023-02-16 356
好吧,我是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);
}
当更改语言时,该代码在控制器上:
@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));
}
}
}
您可以将此类用作控制器的基类,例如:
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;
}
}
我知道,这是非常古老的问题,但是我在Javafx中是新的,而且我也遇到了同样的问题.
这是我在应用程序中更改语言的最终解决方案.它可能不是理想的,但对我有用.
在控制器中,我有该方法:
@FXML
private BorderPane root; //root pane
@FXML
private void changeLocale(ActionEvent event) throws IOException{
Scene scene = root.getScene();
if(event.getSource().equals(lang_en)){
scene.setRoot(FXMLLoader.load(getClass().getResource("Layout.fxml"),ResourceBundle.getBundle("resources/Bundle", Locale.ENGLISH))); // = new Locale("en")
}else if(event.getSource().equals(lang_cs)){
scene.setRoot(FXMLLoader.load(getClass().getResource("Layout.fxml"),ResourceBundle.getBundle("resources/Bundle", new Locale("cs", "CZ"))));
}else{
}
}
该方法将新的加载程序加载到我的场景中(加载到舞台上也有效).
对于完整的场景…我可以在菜单中使用两个放射线仪更改当前语言,因此在加载新加载器后(在方法”公共void initialize(URL位置,resource -bundle Resources)”中,我会在使用Radiomenuitems中选择使用放射性emenuitems此开关:
switch(resources.getLocale().getLanguage()){
case "en":
lang_en.setSelected(true);
break;
case "cs":
lang_cs.setSelected(true);
break;
default:
break;
}
这很简单,对于其他会有这个问题的人可能很有用.
使用标签(标签,文本,标题pan等)使用绑定.
以上所述是小编给大家介绍的更改语言时如何重新加载屏幕?在JavaFX中?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/33893.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态