java 如何在java swing中在运行时更改语言
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13152282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change language at runtime in java swing
提问by volt
I try to change the Locale at runtime in my swing application.
But I can't figure out how it supposed to work, or there are no master plan?
我尝试在我的 Swing 应用程序中在运行时更改区域设置。
但我不知道它应该如何运作,或者没有总体规划?
I can only think of two choices:
1. Restart the application, not the best user experience.
2. Create a localization manager that can register/unregister components, on a change it just iterate all components and change the text.
我只能想到两个选择:
1.重启应用,不是最好的用户体验。
2. 创建一个可以注册/取消注册组件的本地化管理器,在更改时它只是迭代所有组件并更改文本。
Both 1 and 2 feels awkward.
1和2都觉得别扭。
Other info:
For the moment the orientation is not a target.
The application is obfuscated.
其他信息:
目前方向不是目标。
应用程序被混淆。
Example:
例子:
LocRes_en.properties:
LocRes_en.properties:
text1 = English text
LocRes_ja.properties
LocRes_ja.properties
text1 = Japanese text
ChangeLocale.java:
更改Locale.java:
import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Locale; import java.util.ResourceBundle; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class ChangeLocale { private JFrame frame; public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { ChangeLocale window = new ChangeLocale(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public ChangeLocale() { initialize(); } private void initialize() { frame = new JFrame(); frame.setBounds(100, 100, 450, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); FlowLayout flowLayout = new FlowLayout(FlowLayout.CENTER, 5, 5); frame.getContentPane().setLayout(flowLayout); JButton btnChangeLoc = new JButton("Change Locale"); frame.getContentPane().add(btnChangeLoc); final JLabel lblLabel1 = new JLabel("New label"); frame.getContentPane().add(lblLabel1); Locale.setDefault(new Locale("en")); ResourceBundle r = ResourceBundle.getBundle("LocRes"); lblLabel1.setText(r.getString("text1")); btnChangeLoc.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Locale.setDefault(new Locale("ja")); ResourceBundle r = ResourceBundle.getBundle("LocRes"); // Manually iterate through all components :( lblLabel1.setText(r.getString("text1")); // } }); } }
回答by flash
I've implemented this with ResourceBundles and an EventBus.
我已经用 ResourceBundles 和EventBus实现了这一点。
When the locale is changed, the EventBus fires an localeChangedEvent
. All JFrame
windows which have localized strings then have to subscribe to this event. They must also implement a changeLocale()
method which is executed when the event is received.
当语言环境改变时,EventBus 会触发一个localeChangedEvent
. 所有JFrame
具有本地化字符串的窗口都必须订阅此事件。它们还必须实现一个changeLocale()
在接收到事件时执行的方法。
In this method all strings will be updated to the current locale.
在此方法中,所有字符串都将更新为当前语言环境。
public void changeLocale(ResourceBundle rb) {
lblLabel1.setText(rb.getString("text1"));
lblLabel2.setText(rb.getString("text2"));
...
}
回答by Deepu
You can try LocaleChangeListenerinterface -
您可以尝试LocaleChangeListener接口 -
回答by BullyWiiPlaza
Define a GUI
and a combobox with supported languages. Add an ItemListener
so when the combobox is changed, the texts are updated.
GUI
使用支持的语言定义一个和一个组合框。添加一个ItemListener
so 当组合框更改时,文本会更新。
LanguageGUIClient.java:
语言GUIClient.java:
import javax.swing.*;
public class LanguageGUIClient
{
public static void main(String[] arguments) throws Exception
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(() ->
{
LanguageGUI languageGUI = new LanguageGUI();
languageGUI.setVisible(true);
});
}
}
LanguageGUI.java:
语言GUI.java:
import javax.swing.*;
import java.util.Locale;
import java.util.ResourceBundle;
public class LanguageGUI extends JFrame
{
public static ResourceBundle resourceBundle;
private JPanel rootPanel;
private JComboBox<Locale> languageComboBox;
private JLabel languageLabel;
public LanguageGUI()
{
configureFrameProperties();
}
private void configureFrameProperties()
{
add(rootPanel);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
languageComboBox.addItem(Locale.US);
languageComboBox.addItem(Locale.GERMANY);
languageComboBox.addItem(Locale.FRANCE);
setTexts();
languageComboBox.addItemListener(itemEvent -> setTexts());
setSize(300, 100);
}
private void setTexts()
{
Locale locale = languageComboBox.getItemAt(languageComboBox.getSelectedIndex());
resourceBundle = ResourceBundle.getBundle("Bundle", locale);
setTitle(resourceBundle.getString("application.title"));
languageLabel.setText(resourceBundle.getString("language") + ":");
languageComboBox.setToolTipText(resourceBundle.getString("language.tooltip"));
}
}
Note that I'm using IntelliJ's form designer
so the .form
file contents are necessary as well.
请注意,我正在使用,IntelliJ's form designer
因此.form
文件内容也是必需的。
LanguageGUI.form:
语言GUI.form:
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="LanguageGUI">
<grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="eb651" class="javax.swing.JComboBox" binding="languageComboBox">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<toolTipText value=""/>
</properties>
</component>
<vspacer id="977c1">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="e59f" class="javax.swing.JLabel" binding="languageLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
</children>
</grid>
</form>
Furthermore, you need to create the respective resource bundle files in your resources directory:
The result is a GUI
with a combobox allowing you to change language immediately:
回答by AlexR
I have done something similar once. Although my task was simpler: this was a system tray application, so I just had to change the menu items text.
我曾经做过类似的事情。虽然我的任务更简单:这是一个系统托盘应用程序,所以我只需要更改菜单项文本。
But in your case I think this is doable. First, avoid hard-coded strings in your GUI layer. Create class that changes locale and then iterates over all visible frames and goes down to all panels and components and changes the text written on them. The only problem I can expect here is text drawn on canvas.
但在你的情况下,我认为这是可行的。首先,避免在 GUI 层中使用硬编码字符串。创建更改区域设置的类,然后遍历所有可见框架并深入到所有面板和组件并更改写在其上的文本。我能想到的唯一问题是在画布上绘制的文本。