首页 文章

如何在java swing中运行时更改语言

提问于
浏览
11

我尝试在swing应用程序中运行时更改Locale .
但我无法弄清楚它应该如何工作,或者没有总体规划?

我只能想到两个选择:
1.重新启动应用程序,而不是最佳用户体验 .
2.创建一个可以注册/取消注册组件的本地化管理器,在更改时它只是迭代所有组件并更改文本 .

1和2都感觉很尴尬 .

其他信息:
目前,方向不是目标 .
该应用程序是混淆的 .

例:

LocRes_en.properties:

text1 = English text

LocRes_ja.properties

text1 = Japanese text

ChangeLocale.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"));
                    //
                }
            });
        }
    }

4 回答

  • 4

    你可以试试 LocaleChangeListener 界面 -

    Changing locale at runtime in Swing

  • 3

    我曾做过类似的事情 . 虽然我的任务更简单:这是一个系统托盘应用程序,所以我只需要更改菜单项文本 .

    但在你的情况下,我认为这是可行的 . 首先,避免GUI层中的硬编码字符串 . 创建更改区域设置的类,然后遍历所有可见框架并转到所有面板和组件并更改写在其上的文本 . 我能想到的唯一问题是在画布上绘制的文字 .

  • 0

    使用支持的语言定义 GUI 和组合框 . 添加ItemListener,以便在更改组合框时更新文本 .

    LanguageGUIClient.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:

    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"));
        }
    }
    

    请注意,我正在使用 IntelliJ's form designer ,因此 .form 文件内容也是必需的 .

    LanguageGUI.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>
    

    此外,您需要在资源目录中创建相应的资源包文件:

    结果是带有组合框的 GUI ,允许您立即更改语言:

  • 2

    我用ResourceBundles和EventBus实现了这个 .

    更改语言环境后,EventBus将触发 localeChangedEvent . 所有具有本地化字符串的 JFrame 窗口都必须订阅此事件 . 它们还必须实现 changeLocale() 方法,该方法在收到事件时执行 .

    在此方法中,所有字符串都将更新为当前语言环境 .

    public void changeLocale(ResourceBundle rb) {
        lblLabel1.setText(rb.getString("text1"));
        lblLabel2.setText(rb.getString("text2"));
        ...
    }
    

相关问题