--- /dev/null
+/*
+ * 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"));
+ }
+
+}
import java.awt.Dimension;
import javax.swing.JFrame;
-import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JToolBar;
/** 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.
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"));
swingInterface.getManageNodesAction().updateI18n();
swingInterface.getNodeConnectAction().updateI18n();
swingInterface.getNodeDisconnectAction().updateI18n();
+ nodeMenu.updateI18n();
+ languageMenu.updateI18n();
+ getJMenuBar().revalidate();
SwingUtils.repackCentered(this);
}
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
/** The node manager dialog. */
private ManageNodesDialog manageNodesDialog;
+ /** All lanugage menu items. */
+ private List<I18nAction> languageActions = new ArrayList<I18nAction>();
+
/** The list of all defined nodes. */
private List<Node> nodeList;
*/
public SwingInterface(Core core) {
this.core = core;
+ I18n.setLocale(Locale.ENGLISH); /* TODO - load config */
initActions();
initDialogs();
}
return nodeDisconnectAction;
}
+ /**
+ * Returns all language actions.
+ *
+ * @return All language actions
+ */
+ List<I18nAction> getLanguageActions() {
+ return languageActions;
+ }
+
//
// ACTIONS
//
nodeDisconnect();
}
};
+ List<Locale> 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);
+ }
+
}
/**
manageNodesDialog = new ManageNodesDialog(this);
}
+ //
+ // PRIVATE ACTIONS
+ //
+
/**
* Pops up the “manage nodes” dialog.
*/
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
//
*/
public class I18n {
+ /** List of I18nables that are notified when the language changes. */
+ private static final List<I18nable> i18nables = new ArrayList<I18nable>();
+
/** The current locale. */
private static Locale currentLocale;
} 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<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.
* @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);
* 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;
}
* 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
+ * <code>true</code> 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;
}
/**
+ * 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<Locale> findAvailableLanguages() {
+ List<Locale> availableLanguages = new ArrayList<Locale>();
+ availableLanguages.add(Locale.ENGLISH);
+ availableLanguages.add(Locale.GERMAN);
+ return availableLanguages;
+ }
+
+ /**
* Registers the given I18nable to be updated when the language is changed.
*
* @param i18nable
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
--- /dev/null
+# 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.