2012-10-31 31 views
11

Próbuję zmienić ustawienia regionalne w czasie wykonywania w mojej aplikacji swing.
Ale nie rozumiem, jak to ma działać, czy nie ma planu głównego?Jak zmienić język w czasie wykonywania w java swing

Mogę wymyślić tylko dwie opcje:
1. Zrestartuj aplikację, a nie najlepszą obsługę.
2. Utwórz menedżera lokalizacji, który może rejestrować/wyrejestrowywać komponenty, po zmianie iteracji wszystkich składników i zmiany tekstu.

Zarówno 1, jak i 2 czuje się niezręcznie.

Dodatkowe informacje:
Na razie orientacja nie jest celem.
Aplikacja jest zamaskowana.

przykład:

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

[nigdy nie potrzebował tego, ale musi być som Przykłady ładowania właściwości do HashMap lub listy] (http://java2s.com/Tutorial/Java/0220__I18N/Catalog0220__I18N.htm) – mKorbel

Odpowiedz

2

Zrobiłem kiedyś coś podobnego. Chociaż moje zadanie było prostsze: to była aplikacja na tacę systemową, więc musiałem zmienić tekst pozycji menu.

Ale w twoim przypadku myślę, że jest to wykonalne. Po pierwsze, unikaj zakodowanych na sztywno ciągów w warstwie GUI. Utwórz klasę, która zmienia ustawienia narodowe, a następnie iteruje po wszystkich widocznych ramkach i przechodzi do wszystkich paneli i komponentów oraz zmienia tekst na nich zapisany. Jedyny problem, jakiego mogę się tu spodziewać, to tekst narysowany na płótnie.

3

I zostały wdrożone to z ResourceBundles i EventBus.

Po zmianie lokalizacji, EventBus odpala localeChangedEvent. Wszystkie okna z lokalnymi ciągami muszą mieć subskrypcję tego zdarzenia. Muszą także wdrożyć metodę changeLocale(), która jest wykonywana po odebraniu zdarzenia.

W tej metodzie wszystkie ciągi zostaną zaktualizowane do bieżących ustawień narodowych.

0

Definiowanie GUI i combobox z obsługiwanymi językami. Dodaj ItemListener, więc gdy zmieni się combobox, teksty zostaną zaktualizowane.

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

Zauważ, że używam IntelliJ's form designer więc zawartość pliku .form są niezbędne, jak również.

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> 

Ponadto trzeba utworzyć odpowiednich zasobów wiązki plików w katalogu zasobów:

Rezultatem jest GUI z combobox pozwala na zmianę języka Natychmiast:

Powiązane problemy