From 2a6a72b633401f2a8391b604c064e1fb6b561308 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 5 Apr 2008 18:25:37 +0000 Subject: [PATCH] add language menu git-svn-id: http://trooper/svn/projects/jSite/trunk@612 c3eda9e8-030b-0410-8277-bc7414b0a119 --- src/net/pterodactylus/jsite/gui/I18nMenu.java | 61 +++++++++++ src/net/pterodactylus/jsite/gui/MainWindow.java | 20 +++- .../pterodactylus/jsite/gui/SwingInterface.java | 55 ++++++++++ src/net/pterodactylus/jsite/i18n/I18n.java | 61 +++++++++-- src/net/pterodactylus/jsite/i18n/jSite.properties | 11 +- .../pterodactylus/jsite/i18n/jSite_de.properties | 115 +++++++++++++++++++++ 6 files changed, 311 insertions(+), 12 deletions(-) create mode 100644 src/net/pterodactylus/jsite/gui/I18nMenu.java create mode 100644 src/net/pterodactylus/jsite/i18n/jSite_de.properties diff --git a/src/net/pterodactylus/jsite/gui/I18nMenu.java b/src/net/pterodactylus/jsite/gui/I18nMenu.java new file mode 100644 index 0000000..2b64211 --- /dev/null +++ b/src/net/pterodactylus/jsite/gui/I18nMenu.java @@ -0,0 +1,61 @@ +/* + * jSite2 - I18nMenu.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 javax.swing.JMenu; + +import net.pterodactylus.jsite.i18n.I18n; +import net.pterodactylus.jsite.i18n.I18nable; + +/** + * Menu that receives its properties from {@link I18n}. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class I18nMenu extends JMenu implements I18nable { + + /** The {@link I18n} basename. */ + private final String i18nBasename; + + /** + * Creates a new menu with the given {@link I18n} basename. + * + * @param i18nBasename + * The basename of the {@link I18n} properties + */ + public I18nMenu(String i18nBasename) { + this.i18nBasename = i18nBasename; + updateI18n(); + } + + // + // INTERFACE I18nable + // + + /** + * {@inheritDoc} + */ + public void updateI18n() { + setText(I18n.get(i18nBasename + ".name")); + setMnemonic(I18n.getKey(i18nBasename + ".mnemonic")); + } + +} diff --git a/src/net/pterodactylus/jsite/gui/MainWindow.java b/src/net/pterodactylus/jsite/gui/MainWindow.java index 1142818..97b9fe5 100644 --- a/src/net/pterodactylus/jsite/gui/MainWindow.java +++ b/src/net/pterodactylus/jsite/gui/MainWindow.java @@ -24,7 +24,6 @@ import java.awt.Container; import java.awt.Dimension; import javax.swing.JFrame; -import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JPanel; import javax.swing.JToolBar; @@ -52,6 +51,12 @@ public class MainWindow extends JFrame implements I18nable { /** The content pane. */ private JPanel contentPane = new JPanel(); + /** The node menu. */ + private I18nMenu nodeMenu; + + /** The language menu. */ + private I18nMenu languageMenu; + /** * Creates a new main window that redirects all actions to the given swing * interface. @@ -94,15 +99,21 @@ public class MainWindow extends JFrame implements I18nable { private void initWindow() { JMenuBar menuBar = new JMenuBar(); - final JMenu nodeMenu = new JMenu(I18n.get("mainWindow.menu.node.name")); + nodeMenu = new I18nMenu("mainWindow.menu.node"); menuBar.add(nodeMenu); - nodeMenu.setMnemonic(I18n.get("mainWindow.menu.node.mnemonic").charAt(0)); nodeMenu.add(swingInterface.getManageNodesAction()); nodeMenu.addSeparator(); nodeMenu.add(swingInterface.getNodeConnectAction()); nodeMenu.add(swingInterface.getNodeDisconnectAction()); + languageMenu = new I18nMenu("mainWindow.menu.language"); + menuBar.add(languageMenu); + + for (I18nAction languageAction: swingInterface.getLanguageActions()) { + languageMenu.add(languageAction); + } + setJMenuBar(menuBar); JToolBar toolBar = new JToolBar(I18n.get("mainWindow.toolbar.name")); @@ -142,6 +153,9 @@ public class MainWindow extends JFrame implements I18nable { swingInterface.getManageNodesAction().updateI18n(); swingInterface.getNodeConnectAction().updateI18n(); swingInterface.getNodeDisconnectAction().updateI18n(); + nodeMenu.updateI18n(); + languageMenu.updateI18n(); + getJMenuBar().revalidate(); SwingUtils.repackCentered(this); } diff --git a/src/net/pterodactylus/jsite/gui/SwingInterface.java b/src/net/pterodactylus/jsite/gui/SwingInterface.java index 4a0c97f..91e4a58 100644 --- a/src/net/pterodactylus/jsite/gui/SwingInterface.java +++ b/src/net/pterodactylus/jsite/gui/SwingInterface.java @@ -20,11 +20,14 @@ package net.pterodactylus.jsite.gui; import java.awt.event.ActionEvent; +import java.util.ArrayList; import java.util.List; +import java.util.Locale; import net.pterodactylus.jsite.core.Core; import net.pterodactylus.jsite.core.CoreListener; import net.pterodactylus.jsite.core.Node; +import net.pterodactylus.jsite.i18n.I18n; /** * TODO @@ -52,6 +55,9 @@ public class SwingInterface implements CoreListener { /** The node manager dialog. */ private ManageNodesDialog manageNodesDialog; + /** All lanugage menu items. */ + private List languageActions = new ArrayList(); + /** The list of all defined nodes. */ private List nodeList; @@ -63,6 +69,7 @@ public class SwingInterface implements CoreListener { */ public SwingInterface(Core core) { this.core = core; + I18n.setLocale(Locale.ENGLISH); /* TODO - load config */ initActions(); initDialogs(); } @@ -116,6 +123,15 @@ public class SwingInterface implements CoreListener { return nodeDisconnectAction; } + /** + * Returns all language actions. + * + * @return All language actions + */ + List getLanguageActions() { + return languageActions; + } + // // ACTIONS // @@ -167,6 +183,25 @@ public class SwingInterface implements CoreListener { nodeDisconnect(); } }; + List availableLanguages = I18n.findAvailableLanguages(); + for (final Locale locale: availableLanguages) { + System.out.println("adding locale “" + locale.getLanguage() + "”"); + I18nAction languageAction = new I18nAction("general.language." + locale.getLanguage()) { + + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent e) { + System.out.println("changing locale to: " + locale); + changeLanguage(locale, this); + } + + }; + System.out.println("locale: " + locale + ", i18n: " + I18n.getLocale()); + if (I18n.getLocale().getLanguage().equals(locale.getLanguage())) { + languageAction.setEnabled(false); + } + languageActions.add(languageAction); + } + } /** @@ -176,6 +211,10 @@ public class SwingInterface implements CoreListener { manageNodesDialog = new ManageNodesDialog(this); } + // + // PRIVATE ACTIONS + // + /** * Pops up the “manage nodes” dialog. */ @@ -197,6 +236,22 @@ public class SwingInterface implements CoreListener { private void nodeDisconnect() { } + /** + * Changes the language of the interface. This method also disables the + * action for the newly set language and enables all others. + * + * @param newLocale + * The new language + * @param languageAction + * The action that triggered the change + */ + private void changeLanguage(Locale newLocale, I18nAction languageAction) { + for (I18nAction i18nAction: languageActions) { + i18nAction.setEnabled(i18nAction != languageAction); + } + I18n.setLocale(newLocale); + } + // // INTERFACE CoreListener // diff --git a/src/net/pterodactylus/jsite/i18n/I18n.java b/src/net/pterodactylus/jsite/i18n/I18n.java index 0acdced..504dc88 100644 --- a/src/net/pterodactylus/jsite/i18n/I18n.java +++ b/src/net/pterodactylus/jsite/i18n/I18n.java @@ -44,6 +44,9 @@ import net.pterodactylus.util.io.Closer; */ public class I18n { + /** List of I18nables that are notified when the language changes. */ + private static final List i18nables = new ArrayList(); + /** The current locale. */ private static Locale currentLocale; @@ -64,12 +67,9 @@ public class I18n { } catch (IOException e) { /* something is fucked. */ } - setLocale(Locale.getDefault()); + setLocale(Locale.getDefault(), false); } - /** List of I18nables that are notified when the language changes. */ - private static final List i18nables = new ArrayList(); - /** * Returns the translated value for a key. The translated values may contain * placeholders that are replaced with the given parameters. @@ -105,7 +105,10 @@ public class I18n { * @return The keycode */ public static int getKey(String key) { - String value = get(key); + String value = currentLanguage.getProperty(key); + if (value == null) { + return -1; + } if (value.startsWith("VK_")) { try { Field field = KeyEvent.class.getField(value); @@ -132,7 +135,7 @@ public class I18n { * created from the translated value */ public static KeyStroke getKeyStroke(String key) { - String value = get(key); + String value = currentLanguage.getProperty(key); if (value == null) { return null; } @@ -174,14 +177,35 @@ public class I18n { * The new locale to use */ public static void setLocale(Locale newLocale) { + setLocale(newLocale, true); + } + + /** + * Sets the current locale. + * + * @param newLocale + * The new locale to use + * @param notify + * true to notify registered {@link I18nable}s + * after the language was changed + */ + private static void setLocale(Locale newLocale, boolean notify) { currentLocale = newLocale; InputStream inputStream = null; try { currentLanguage = new Properties(defaultLanguage); - inputStream = I18n.class.getResourceAsStream("jSite_" + currentLocale.toString() + ".properties"); + if (newLocale == Locale.ENGLISH) { + if (notify) { + notifyI18nables(); + } + return; + } + inputStream = I18n.class.getResourceAsStream("jSite_" + newLocale.getLanguage() + ".properties"); if (inputStream != null) { currentLanguage.load(inputStream); - notifyI18nables(); + if (notify) { + notifyI18nables(); + } } } catch (MissingResourceException mre1) { currentLocale = Locale.ENGLISH; @@ -193,6 +217,27 @@ public class I18n { } /** + * Returns the current locale. + * + * @return The current locale + */ + public static Locale getLocale() { + return currentLocale; + } + + /** + * Finds all available locales. + * + * @return All available locales + */ + public static List findAvailableLanguages() { + List availableLanguages = new ArrayList(); + availableLanguages.add(Locale.ENGLISH); + availableLanguages.add(Locale.GERMAN); + return availableLanguages; + } + + /** * Registers the given I18nable to be updated when the language is changed. * * @param i18nable diff --git a/src/net/pterodactylus/jsite/i18n/jSite.properties b/src/net/pterodactylus/jsite/i18n/jSite.properties index 2459687..728aeba 100644 --- a/src/net/pterodactylus/jsite/i18n/jSite.properties +++ b/src/net/pterodactylus/jsite/i18n/jSite.properties @@ -18,12 +18,21 @@ general.button.cancel.accelerator: VK_ESCAPE general.button.cancel.shortDescription: Cancel general.button.cancel.longDescription: Don\u2019t Save Node Settings and Close Dialog +general.language.en.name: English +general.language.en.mnemonic: VK_E + +general.language.de.name: German +general.language.de.mnemonic: VK_G + # main window mainWindow.toolbar.name: jSite Toolbar # main menus mainWindow.menu.node.name: Node -mainWindow.menu.node.mnemonic: n +mainWindow.menu.node.mnemonic: VK_N + +mainWindow.menu.language.name: Languages +mainWindow.menu.language.mnemonic: VK_L # # the node menu diff --git a/src/net/pterodactylus/jsite/i18n/jSite_de.properties b/src/net/pterodactylus/jsite/i18n/jSite_de.properties new file mode 100644 index 0000000..9cfac1f --- /dev/null +++ b/src/net/pterodactylus/jsite/i18n/jSite_de.properties @@ -0,0 +1,115 @@ +# jSite i18n data, English +# +# this file should be in US-ASCII format, with unicode characters outside +# US-ASCII range encoded with the java-typical \u notation. + +# use small letters for mnemonics, use large letters for accelerators. + +# general gui components +general.button.okay.name: OK +general.button.okay.mnemonic: VK_O +general.button.okay.accelerator: Ctrl-VK_O +general.button.okay.shortDescription: \u00c4nderungen akzeptieren +general.button.okay.longDescription: Dialog schlie\u00dfen und \u00c4nderungen akzeptieren + +general.button.cancel.name: Abbrechen +general.button.cancel.mnemonic: VK_B +general.button.cancel.accelerator: VK_ESCAPE +general.button.cancel.shortDescription: Abbrechen +general.button.cancel.longDescription: Dialog schlie\u00dfen und \u00c4nderungen verwerfen + +general.language.en.name: Englisch +general.language.en.mnemonic: VK_E + +general.language.de.name: Deutsch +general.language.de.mnemonic: VK_D + +# main window +mainWindow.toolbar.name: jSite Toolbar + +# main menus +mainWindow.menu.node.name: Node +mainWindow.menu.node.mnemonic: VK_N + +mainWindow.menu.languages.name: Sprachen +mainWindow.menu.languages.mnemonic: VK_S + +# +# the node menu +# + +#manage nodes +mainWindow.menu.node.item.manageNodes.name: Nodes verwalten +mainWindow.menu.node.item.manageNodes.mnemonic: VK_N +mainWindow.menu.node.item.manageNodes.accelerator: Ctrl-VK_N +mainWindow.menu.node.item.manageNodes.shortDescription: Nodes verwalten +mainWindow.menu.node.item.manageNodes.longDescription: Nodes verwalten + +# connect to node +mainWindow.menu.node.item.connect.name: Verbinden +mainWindow.menu.node.item.connect.mnemonic: VK_V +mainWindow.menu.node.item.connect.accelerator: Ctrl-VK_V +mainWindow.menu.node.item.connect.shortDescription: Mit Node verbinden +mainWindow.menu.node.item.connect.longDescription: Verbindung zum Node herstellen + +#disconnect from node +mainWindow.menu.node.item.disconnect.name: Verbindung trennen +mainWindow.menu.node.item.disconnect.mnemonic: VK_T +mainWindow.menu.node.item.disconnect.accelerator: Ctrl-VK_T +mainWindow.menu.node.item.disconnect.shortDescription: Von Node trennen +mainWindow.menu.node.item.disconnect.longDescription: Verbindung zum Node trennen + +# +# the "manage nodes" dialog +# + +manageNodesDialog.title: Nodes verwalten + +manageNodesDialog.button.addNode.name: Node hinzuf\u00fcgen +manageNodesDialog.button.addNode.mnemonic: VK_H +manageNodesDialog.button.addNode.accelerator: Ctrl-VK_H +manageNodesDialog.button.addNode.shortDescription: Node hinzuf\u00fcgen +manageNodesDialog.button.addNode.longDescription: Einen Node hinzuf\u00fcgen + +manageNodesDialog.button.editNode.name: Edit Node +manageNodesDialog.button.editNode.mnemonic: e +manageNodesDialog.button.editNode.accelerator: Ctrl-VK_E +manageNodesDialog.button.editNode.shortDescription: Edit Selected Node + +manageNodesDialog.button.deleteNode.name: Delete Node +manageNodesDialog.button.deleteNode.mnemonic: d +manageNodesDialog.button.deleteNode.accelerator: Ctrl-VK_D +manageNodesDialog.button.deleteNode.shortDescription: Delete Selected Node(s) + +manageNodesDialog.error.nodeListEmpty.title: Node List Empty +manageNodesDialog.error.nodeListEmpty.message: The node list is empty. + +manageNodesDialog.error.nodeConnected.title: Node Is Connected +manageNodesDialog.error.nodeConnected.message: The Node \u201c{0}\u201d is still connected. Do you really want to delete it? + +# the "edit node" dialog +editNodeDialog.title: Edit Node + +editNodeDialog.label.name.name: Name +editNodeDialog.label.name.mnemonic: n + +editNodeDialog.label.hostname.name: Hostname +editNodeDialog.label.hostname.mnemonic: h + +editNodeDialog.label.port.name: Port +editNodeDialog.label.port.mnemonic: p + +editNodeDialog.checkbox.sameMachine.name: Node on the same machine +editNodeDialog.checkbox.sameMachine.mnemonic: s +editNodeDialog.checkbox.sameMachine.accelerator: Alt-VK_S +editNodeDialog.checkbox.sameMachine.shortDescription: Node is on the same machine +editNodeDialog.checkbox.sameMachine.longDescription: The node is on the same machine as jSite and some optimizations can be used + +editNodeDialog.error.name.title: Wrong Node Name +editNodeDialog.error.name.message: The name of the node is empty. + +editNodeDialog.error.hostname.title: Wrong Hostname +editNodeDialog.error.hostname.message: The hostname is invalid. + +editNodeDialog.error.port.title: Wrong Port Number +editNodeDialog.error.port.message: The port number is invalid. -- 2.7.4