2012-10-31 179 views
11

我嘗試在運行時更改我的swing應用程序中的語言環境。
但我不知道它應該如何工作,或者沒有總體規劃?如何在java swing中運行時更改語言

我只能想到兩個選擇:
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")); 
        // 
       } 
      }); 
     } 
    }
+0

[永遠不需要,但必須有索姆e有關將屬性加載到HashMap或List的示例](http://java2s.com/Tutorial/Java/0220__I18N/Catalog0220__I18N.htm) – mKorbel

回答

2

我曾經做過類似的事情。雖然我的任務更簡單:這是一個系統托盤應用程序,所以我只需更改菜單項文本。

但在你的情況下,我認爲這是可行的。首先,避免GUI層中的硬編碼字符串。創建改變語言環境的類,然後遍歷所有可見框架,並遍歷所有面板和組件,並更改寫入它們的文本。我期望的唯一問題是在畫布上繪製文本。

3

我把ResourceBundle和EventBus實現這一點。

當語言環境發生變化時,EventBus觸發localeChangedEvent。所有有本地化字符串的JFrame窗口都必須訂閱此事件。他們還必須實施在收到事件時執行的changeLocale()方法。

在此方法中,所有字符串將更新爲當前語言環境。

public void changeLocale(ResourceBundle rb) { 
    lblLabel1.setText(rb.getString("text1")); 
    lblLabel2.setText(rb.getString("text2")); 
    ... 
} 
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與組合框允許您更改語言立即: