make the GUI update its texts when a new language is chosen
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 5 Apr 2008 17:31:05 +0000 (17:31 +0000)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 5 Apr 2008 17:31:05 +0000 (17:31 +0000)
git-svn-id: http://trooper/svn/projects/jSite/trunk@611 c3eda9e8-030b-0410-8277-bc7414b0a119

src/net/pterodactylus/jsite/gui/EditNodeDialog.java
src/net/pterodactylus/jsite/gui/I18nAction.java
src/net/pterodactylus/jsite/gui/I18nLabel.java [new file with mode: 0644]
src/net/pterodactylus/jsite/gui/MainWindow.java
src/net/pterodactylus/jsite/gui/ManageNodesDialog.java
src/net/pterodactylus/jsite/gui/SwingInterface.java
src/net/pterodactylus/jsite/i18n/I18n.java
src/net/pterodactylus/jsite/i18n/I18nable.java [new file with mode: 0644]

index 2ad2b4b..73602fc 100644 (file)
@@ -28,19 +28,17 @@ import java.awt.event.ActionEvent;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
-import javax.swing.Action;
 import javax.swing.BorderFactory;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
-import javax.swing.JComponent;
 import javax.swing.JDialog;
-import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
 import javax.swing.border.EtchedBorder;
 
 import net.pterodactylus.jsite.i18n.I18n;
+import net.pterodactylus.jsite.i18n.I18nable;
 import net.pterodactylus.jsite.main.Version;
 import net.pterodactylus.util.swing.SwingUtils;
 
@@ -50,7 +48,7 @@ import net.pterodactylus.util.swing.SwingUtils;
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
  * @version $Id$
  */
-public class EditNodeDialog extends JDialog {
+public class EditNodeDialog extends JDialog implements I18nable {
 
        /** The user-given name of the node. */
        private String name;
@@ -65,17 +63,26 @@ public class EditNodeDialog extends JDialog {
        private boolean sameMachine;
 
        /** Action of the okay button. */
-       private Action okayAction;
+       private I18nAction okayAction;
 
        /** Action of the cancel button. */
-       private Action cancelAction;
+       private I18nAction cancelAction;
+
+       /** The name label. */
+       private I18nLabel nameLabel;
 
        /** The name textfield. */
        private JTextField nameTextField;
 
+       /** The hostname label. */
+       private I18nLabel hostnameLabel;
+
        /** The hostname textfield. */
        private JTextField hostnameTextField;
 
+       /** The port label. */
+       private I18nLabel portLabel;
+
        /** The port textfield. */
        private JTextField portTextField;
 
@@ -96,6 +103,7 @@ public class EditNodeDialog extends JDialog {
                initActions();
                initComponents();
                pack();
+               I18n.registerI18nable(this);
                SwingUtils.center(this);
        }
 
@@ -246,15 +254,15 @@ public class EditNodeDialog extends JDialog {
                contentPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(12, 12, 12, 12)));
 
                nameTextField = new JTextField();
-               contentPanel.add(createLabel(I18n.get("editNodeDialog.label.name"), nameTextField), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+               contentPanel.add(nameLabel = new I18nLabel("editNodeDialog.label.name", nameTextField), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
                contentPanel.add(nameTextField, new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 12, 0, 0), 0, 0));
 
                hostnameTextField = new JTextField();
-               contentPanel.add(createLabel(I18n.get("editNodeDialog.label.hostname"), hostnameTextField), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
+               contentPanel.add(hostnameLabel = new I18nLabel("editNodeDialog.label.hostname", hostnameTextField), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
                contentPanel.add(hostnameTextField, new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(12, 12, 0, 0), 0, 0));
 
                portTextField = new JTextField();
-               contentPanel.add(createLabel(I18n.get("editNodeDialog.label.port"), portTextField), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
+               contentPanel.add(portLabel = new I18nLabel("editNodeDialog.label.port", portTextField), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
                contentPanel.add(portTextField, new GridBagConstraints(1, 2, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(12, 12, 0, 0), 0, 0));
 
                sameMachineCheckBox = new JCheckBox(new I18nAction("editNodeDialog.checkbox.sameMachine") {
@@ -266,23 +274,6 @@ public class EditNodeDialog extends JDialog {
                contentPanel.add(sameMachineCheckBox, new GridBagConstraints(0, 3, 2, 1, 1, 1, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
        }
 
-       /**
-        * Creates a label whose name and mnemonic are initialized from the given
-        * i18n property.
-        * 
-        * @param i18nBasename
-        *            The i18n property basename of the label
-        * @param labelFor
-        *            The component this label describes
-        * @return The created label
-        */
-       private JLabel createLabel(String i18nBasename, JComponent labelFor) {
-               JLabel label = new JLabel(I18n.get(i18nBasename + ".name"));
-               label.setDisplayedMnemonic(I18n.getKey(i18nBasename + ".mnemonic"));
-               label.setLabelFor(labelFor);
-               return label;
-       }
-
        //
        // PRIVATE ACTIONS
        //
@@ -371,4 +362,21 @@ public class EditNodeDialog extends JDialog {
                setVisible(false);
        }
 
+       //
+       // INTERFACE I18nable
+       //
+
+       /**
+        * {@inheritDoc}
+        */
+       public void updateI18n() {
+               okayAction.updateI18n();
+               cancelAction.updateI18n();
+               nameLabel.updateI18n();
+               hostnameLabel.updateI18n();
+               portLabel.updateI18n();
+               setTitle(I18n.get("editNodeDialog.title") + " – jSite " + Version.getVersion());
+               SwingUtils.repackCentered(this);
+       }
+
 }
index 0d36f01..77733ae 100644 (file)
@@ -5,6 +5,7 @@ import javax.swing.Action;
 import javax.swing.Icon;
 
 import net.pterodactylus.jsite.i18n.I18n;
+import net.pterodactylus.jsite.i18n.I18nable;
 
 /**
  * Helper class that initializes actions with values from {@link I18n}.
@@ -12,7 +13,10 @@ import net.pterodactylus.jsite.i18n.I18n;
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
  * @version $Id$
  */
-public abstract class I18nAction extends AbstractAction {
+public abstract class I18nAction extends AbstractAction implements I18nable {
+
+       /** The I18n basename. */
+       private final String i18nName;
 
        /**
         * Creates a new action that uses the given name as base name to get values
@@ -63,15 +67,23 @@ public abstract class I18nAction extends AbstractAction {
         *            The icon for the action
         */
        public I18nAction(String i18nName, boolean enabled, Icon icon) {
+               this.i18nName = i18nName;
+               if (icon != null) {
+                       putValue(Action.SMALL_ICON, icon);
+               }
+               setEnabled(enabled);
+               updateI18n();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void updateI18n() {
                putValue(Action.NAME, I18n.get(i18nName + ".name"));
                putValue(Action.MNEMONIC_KEY, I18n.getKey(i18nName + ".mnemonic"));
                putValue(Action.ACCELERATOR_KEY, I18n.getKeyStroke(i18nName + ".accelerator"));
                putValue(Action.SHORT_DESCRIPTION, I18n.get(i18nName + ".shortDescription"));
                putValue(Action.LONG_DESCRIPTION, I18n.get(i18nName + ".longDescription"));
-               if (icon != null) {
-                       putValue(Action.SMALL_ICON, icon);
-               }
-               setEnabled(enabled);
        }
 
 }
\ No newline at end of file
diff --git a/src/net/pterodactylus/jsite/gui/I18nLabel.java b/src/net/pterodactylus/jsite/gui/I18nLabel.java
new file mode 100644 (file)
index 0000000..ffcb549
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * jSite2 - I18nLabel.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.jsite.gui;
+
+import java.awt.Component;
+
+import javax.swing.JLabel;
+
+import net.pterodactylus.jsite.i18n.I18n;
+import net.pterodactylus.jsite.i18n.I18nable;
+
+/**
+ * Label that can update itself from {@link I18n}.
+ * 
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ * @version $Id$
+ */
+public class I18nLabel extends JLabel implements I18nable {
+
+       /** The I18n basename of the label. */
+       private final String i18nBasename;
+
+       /**
+        * Creates a new label with the given I18n basename that optionally is a
+        * label for the given component.
+        * 
+        * @param i18nBasename
+        *            The I18n basename of the label
+        * @param component
+        *            The component that is activated by the label, or
+        *            <code>null</code> if this label should not activate a
+        *            component
+        */
+       public I18nLabel(String i18nBasename, Component component) {
+               super();
+               this.i18nBasename = i18nBasename;
+               updateI18n();
+               if (component != null) {
+                       setLabelFor(component);
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void updateI18n() {
+               setText(I18n.get(i18nBasename + ".name"));
+               setDisplayedMnemonic(I18n.getKey(i18nBasename + ".mnemonic"));
+       }
+
+}
index 681cc32..1142818 100644 (file)
@@ -30,6 +30,7 @@ import javax.swing.JPanel;
 import javax.swing.JToolBar;
 
 import net.pterodactylus.jsite.i18n.I18n;
+import net.pterodactylus.jsite.i18n.I18nable;
 import net.pterodactylus.jsite.main.Version;
 import net.pterodactylus.util.swing.StatusBar;
 import net.pterodactylus.util.swing.SwingUtils;
@@ -40,14 +41,14 @@ import net.pterodactylus.util.swing.SwingUtils;
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
  * @version $Id$
  */
-public class MainWindow extends JFrame {
+public class MainWindow extends JFrame implements I18nable {
 
        /** The swing interface that receives all actions. */
        private final SwingInterface swingInterface;
 
        /** The status bar. */
        private StatusBar statusBar = new StatusBar();
-       
+
        /** The content pane. */
        private JPanel contentPane = new JPanel();
 
@@ -65,6 +66,7 @@ public class MainWindow extends JFrame {
                setPreferredSize(new Dimension(480, 280));
                pack();
                SwingUtils.center(this);
+               I18n.registerI18nable(this);
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
 
@@ -120,7 +122,7 @@ public class MainWindow extends JFrame {
        private void initComponents() {
                super.getContentPane().add(statusBar, BorderLayout.PAGE_END);
        }
-       
+
        /**
         * {@inheritDoc}
         */
@@ -129,4 +131,18 @@ public class MainWindow extends JFrame {
                return contentPane;
        }
 
+       //
+       // INTERFACE I18nable
+       //
+
+       /**
+        * {@inheritDoc}
+        */
+       public void updateI18n() {
+               swingInterface.getManageNodesAction().updateI18n();
+               swingInterface.getNodeConnectAction().updateI18n();
+               swingInterface.getNodeDisconnectAction().updateI18n();
+               SwingUtils.repackCentered(this);
+       }
+
 }
index 9d993a0..447618c 100644 (file)
@@ -28,7 +28,6 @@ import java.util.Iterator;
 import java.util.List;
 
 import javax.swing.AbstractListModel;
-import javax.swing.Action;
 import javax.swing.BorderFactory;
 import javax.swing.JButton;
 import javax.swing.JDialog;
@@ -43,6 +42,7 @@ import javax.swing.event.ListSelectionListener;
 import net.pterodactylus.jsite.core.Core;
 import net.pterodactylus.jsite.core.Node;
 import net.pterodactylus.jsite.i18n.I18n;
+import net.pterodactylus.jsite.i18n.I18nable;
 import net.pterodactylus.jsite.main.Version;
 import net.pterodactylus.util.swing.SwingUtils;
 
@@ -52,7 +52,7 @@ import net.pterodactylus.util.swing.SwingUtils;
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
  * @version $Id$
  */
-public class ManageNodesDialog extends JDialog implements ListSelectionListener {
+public class ManageNodesDialog extends JDialog implements ListSelectionListener, I18nable {
 
        /** The core. */
        private final Core core;
@@ -61,19 +61,19 @@ public class ManageNodesDialog extends JDialog implements ListSelectionListener
        private List<Node> originalNodeList;
 
        /** The “add node” action. */
-       private Action addNodeAction;
+       private I18nAction addNodeAction;
 
        /** The “edit node” action. */
-       private Action editNodeAction;
+       private I18nAction editNodeAction;
 
        /** The “delete node” action. */
-       private Action deleteNodeAction;
+       private I18nAction deleteNodeAction;
 
        /** The “okay” action. */
-       private Action okayAction;
+       private I18nAction okayAction;
 
        /** The “cancel” action. */
-       private Action cancelAction;
+       private I18nAction cancelAction;
 
        /** The “edit node” dialog. */
        private EditNodeDialog editNodeDialog;
@@ -97,6 +97,7 @@ public class ManageNodesDialog extends JDialog implements ListSelectionListener
                initComponents();
                initDialogs();
                pack();
+               I18n.registerI18nable(this);
                SwingUtils.center(this);
        }
 
@@ -338,6 +339,23 @@ public class ManageNodesDialog extends JDialog implements ListSelectionListener
                deleteNodeAction.setEnabled(selectCount >= 1);
        }
 
+       //
+       // INTERFACE I18nable
+       //
+
+       /**
+        * {@inheritDoc}
+        */
+       public void updateI18n() {
+               okayAction.updateI18n();
+               cancelAction.updateI18n();
+               addNodeAction.updateI18n();
+               editNodeAction.updateI18n();
+               deleteNodeAction.updateI18n();
+               setTitle(I18n.get("manageNodesDialog.title") + " – jSite " + Version.getVersion());
+               SwingUtils.repackCentered(this);
+       }
+
        /**
         * List model for the {@link ManageNodesDialog#nodeList}. TODO
         * 
index edcc0df..4a0c97f 100644 (file)
@@ -22,8 +22,6 @@ package net.pterodactylus.jsite.gui;
 import java.awt.event.ActionEvent;
 import java.util.List;
 
-import javax.swing.Action;
-
 import net.pterodactylus.jsite.core.Core;
 import net.pterodactylus.jsite.core.CoreListener;
 import net.pterodactylus.jsite.core.Node;
@@ -43,13 +41,13 @@ public class SwingInterface implements CoreListener {
        private MainWindow mainWindow;
 
        /** The “manage nodes” action. */
-       private Action manageNodesAction;
+       private I18nAction manageNodesAction;
 
        /** The “connect to node” action. */
-       private Action nodeConnectAction;
+       private I18nAction nodeConnectAction;
 
        /** The “disconnect from node” action. */
-       private Action nodeDisconnectAction;
+       private I18nAction nodeDisconnectAction;
 
        /** The node manager dialog. */
        private ManageNodesDialog manageNodesDialog;
@@ -96,7 +94,7 @@ public class SwingInterface implements CoreListener {
         * 
         * @return The “manage nodes” action
         */
-       Action getManageNodesAction() {
+       I18nAction getManageNodesAction() {
                return manageNodesAction;
        }
 
@@ -105,7 +103,7 @@ public class SwingInterface implements CoreListener {
         * 
         * @return The “connect to node” action
         */
-       Action getNodeConnectAction() {
+       I18nAction getNodeConnectAction() {
                return nodeConnectAction;
        }
 
@@ -114,7 +112,7 @@ public class SwingInterface implements CoreListener {
         * 
         * @return The “disconnect from node” action
         */
-       Action getNodeDisconnectAction() {
+       I18nAction getNodeDisconnectAction() {
                return nodeDisconnectAction;
        }
 
index db97d0b..0acdced 100644 (file)
@@ -25,6 +25,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 import java.util.MissingResourceException;
 import java.util.Properties;
@@ -65,6 +67,9 @@ public class I18n {
                setLocale(Locale.getDefault());
        }
 
+       /** List of I18nables that are notified when the language changes. */
+       private static final List<I18nable> i18nables = new ArrayList<I18nable>();
+
        /**
         * Returns the translated value for a key. The translated values may contain
         * placeholders that are replaced with the given parameters.
@@ -176,6 +181,7 @@ public class I18n {
                        inputStream = I18n.class.getResourceAsStream("jSite_" + currentLocale.toString() + ".properties");
                        if (inputStream != null) {
                                currentLanguage.load(inputStream);
+                               notifyI18nables();
                        }
                } catch (MissingResourceException mre1) {
                        currentLocale = Locale.ENGLISH;
@@ -185,4 +191,39 @@ public class I18n {
                        Closer.close(inputStream);
                }
        }
+
+       /**
+        * Registers the given I18nable to be updated when the language is changed.
+        * 
+        * @param i18nable
+        *            The i18nable to register
+        */
+       public static void registerI18nable(I18nable i18nable) {
+               i18nables.add(i18nable);
+       }
+
+       /**
+        * Deregisters the given I18nable to be updated when the language is
+        * changed.
+        * 
+        * @param i18nable
+        *            The i18nable to register
+        */
+       public static void deregisterI18nable(I18nable i18nable) {
+               i18nables.remove(i18nable);
+       }
+
+       //
+       // PRIVATE METHODS
+       //
+
+       /**
+        * Notifies all registered {@link I18nable}s that the language was changed.
+        */
+       private static void notifyI18nables() {
+               for (I18nable i18nable: i18nables) {
+                       i18nable.updateI18n();
+               }
+       }
+
 }
diff --git a/src/net/pterodactylus/jsite/i18n/I18nable.java b/src/net/pterodactylus/jsite/i18n/I18nable.java
new file mode 100644 (file)
index 0000000..00e05fe
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * jSite2 - I18nable.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.jsite.i18n;
+
+/**
+ * Interface for objects that want to be notified when the language is changed.
+ * 
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ * @version $Id$
+ */
+public interface I18nable {
+
+       /**
+        * Notifies the object that the language in {@link I18n} was changed.
+        */
+       public void updateI18n();
+
+}