Fix calculation of project size.
[jSite.git] / src / de / todesbaum / jsite / gui / NodeManagerPage.java
index 1309fbf..8e44129 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * jSite-0.7 - 
- * Copyright (C) 2006 David Roden
+ * jSite - NodeManagerPage.java - Copyright © 2006–2012 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
@@ -55,51 +54,113 @@ import javax.swing.text.Document;
 
 import de.todesbaum.jsite.application.Node;
 import de.todesbaum.jsite.i18n.I18n;
+import de.todesbaum.jsite.i18n.I18nContainer;
 import de.todesbaum.util.swing.TLabel;
 import de.todesbaum.util.swing.TWizard;
 import de.todesbaum.util.swing.TWizardPage;
 
 /**
- * @author David Roden <droden@gmail.com>
- * @version $Id: NodeManagerPage.java 418 2006-03-29 17:49:16Z bombe $
+ * Wizard page that lets the user edit his nodes.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
  */
 public class NodeManagerPage extends TWizardPage implements ListSelectionListener, DocumentListener, ChangeListener {
 
+       /** List of node manager listeners. */
        private List<NodeManagerListener> nodeManagerListeners = new ArrayList<NodeManagerListener>();
-       private TWizard wizard;
 
-       private Action addNodeAction;
-       private Action deleteNodeAction;
+       /** The “add node” action. */
+       protected Action addNodeAction;
+
+       /** The “delete node” action. */
+       protected Action deleteNodeAction;
+
+       /** The node list model. */
        private DefaultListModel nodeListModel;
+
+       /** The node list. */
        private JList nodeList;
+
+       /** The node name textfield. */
        private JTextField nodeNameTextField;
+
+       /** The node hostname textfield. */
        private JTextField nodeHostnameTextField;
+
+       /** The spinner for the node port. */
        private JSpinner nodePortSpinner;
 
-       public NodeManagerPage() {
-               super();
+       /**
+        * Creates a new node manager wizard page.
+        *
+        * @param wizard
+        *            The wizard this page belongs to
+        */
+       public NodeManagerPage(final TWizard wizard) {
+               super(wizard);
                pageInit();
                setHeading(I18n.getMessage("jsite.node-manager.heading"));
                setDescription(I18n.getMessage("jsite.node-manager.description"));
+               I18nContainer.getInstance().registerRunnable(new Runnable() {
+
+                       public void run() {
+                               setHeading(I18n.getMessage("jsite.node-manager.heading"));
+                               setDescription(I18n.getMessage("jsite.node-manager.description"));
+                       }
+               });
        }
-       
+
+       /**
+        * Adds a listener for node manager events.
+        *
+        * @param nodeManagerListener
+        *            The listener to add
+        */
        public void addNodeManagerListener(NodeManagerListener nodeManagerListener) {
                nodeManagerListeners.add(nodeManagerListener);
        }
-       
+
+       /**
+        * Removes a listener for node manager events.
+        *
+        * @param nodeManagerListener
+        *            The listener to remove
+        */
        public void removeNodeManagerListener(NodeManagerListener nodeManagerListener) {
                nodeManagerListeners.remove(nodeManagerListener);
        }
-       
+
+       /**
+        * Notifies all listeners that the node configuration has changed.
+        *
+        * @param nodes
+        *            The new list of nodes
+        */
        protected void fireNodesUpdated(Node[] nodes) {
-               for (NodeManagerListener nodeManagerListener: nodeManagerListeners) {
+               for (NodeManagerListener nodeManagerListener : nodeManagerListeners) {
                        nodeManagerListener.nodesUpdated(nodes);
                }
        }
 
+       /**
+        * Notifies all listeners that a new node was selected.
+        *
+        * @param node
+        *            The newly selected node
+        */
+       protected void fireNodeSelected(Node node) {
+               for (NodeManagerListener nodeManagerListener : nodeManagerListeners) {
+                       nodeManagerListener.nodeSelected(node);
+               }
+       }
+
+       /**
+        * Creates all actions.
+        */
        private void createActions() {
                addNodeAction = new AbstractAction(I18n.getMessage("jsite.node-manager.add-node")) {
 
+                       @SuppressWarnings("synthetic-access")
                        public void actionPerformed(ActionEvent actionEvent) {
                                addNode();
                        }
@@ -107,13 +168,25 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
 
                deleteNodeAction = new AbstractAction(I18n.getMessage("jsite.node-manager.delete-node")) {
 
+                       @SuppressWarnings("synthetic-access")
                        public void actionPerformed(ActionEvent actionEvent) {
                                deleteNode();
                        }
                };
                deleteNodeAction.setEnabled(false);
+
+               I18nContainer.getInstance().registerRunnable(new Runnable() {
+
+                       public void run() {
+                               addNodeAction.putValue(Action.NAME, I18n.getMessage("jsite.node-manager.add-node"));
+                               deleteNodeAction.putValue(Action.NAME, I18n.getMessage("jsite.node-manager.delete-node"));
+                       }
+               });
        }
 
+       /**
+        * Initializes the page and all components in it.
+        */
        private void pageInit() {
                createActions();
                nodeListModel = new DefaultListModel();
@@ -127,7 +200,7 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
                nodeNameTextField.getDocument().putProperty("Name", "node-name");
                nodeNameTextField.getDocument().addDocumentListener(this);
                nodeNameTextField.setEnabled(false);
-               
+
                nodeHostnameTextField = new JTextField("localhost");
                nodeHostnameTextField.getDocument().putProperty("Name", "node-hostname");
                nodeHostnameTextField.getDocument().addDocumentListener(this);
@@ -147,37 +220,64 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
                JPanel nodeInformationPanel = new JPanel(new GridBagLayout());
                centerPanel.add(nodeInformationPanel, BorderLayout.PAGE_START);
                nodeInformationPanel.add(buttonPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
-               nodeInformationPanel.add(new JLabel("<html><b>" + I18n.getMessage("jsite.node-manager.node-information") + "</b></html>"), new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(6, 0, 0, 0), 0, 0));
-               nodeInformationPanel.add(new TLabel(I18n.getMessage("jsite.node-manager.name"), KeyEvent.VK_N, nodeNameTextField), new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 18, 0, 0), 0, 0));
+               final JLabel nodeInformationLabel = new JLabel("<html><b>" + I18n.getMessage("jsite.node-manager.node-information") + "</b></html>");
+               nodeInformationPanel.add(nodeInformationLabel, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(6, 0, 0, 0), 0, 0));
+               final TLabel nodeNameLabel = new TLabel(I18n.getMessage("jsite.node-manager.name") + ":", KeyEvent.VK_N, nodeNameTextField);
+               nodeInformationPanel.add(nodeNameLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 18, 0, 0), 0, 0));
                nodeInformationPanel.add(nodeNameTextField, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(6, 6, 0, 0), 0, 0));
-               nodeInformationPanel.add(new TLabel(I18n.getMessage("jsite.node-manager.hostname"), KeyEvent.VK_H, nodeHostnameTextField), new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 18, 0, 0), 0, 0));
+               final TLabel nodeHostnameLabel = new TLabel(I18n.getMessage("jsite.node-manager.hostname") + ":", KeyEvent.VK_H, nodeHostnameTextField);
+               nodeInformationPanel.add(nodeHostnameLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 18, 0, 0), 0, 0));
                nodeInformationPanel.add(nodeHostnameTextField, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(6, 6, 0, 0), 0, 0));
-               nodeInformationPanel.add(new TLabel(I18n.getMessage("jsite.node-manager.port"), KeyEvent.VK_P, nodePortSpinner), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 18, 0, 0), 0, 0));
+               final TLabel nodePortLabel = new TLabel(I18n.getMessage("jsite.node-manager.port") + ":", KeyEvent.VK_P, nodePortSpinner);
+               nodeInformationPanel.add(nodePortLabel, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 18, 0, 0), 0, 0));
                nodeInformationPanel.add(nodePortSpinner, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 6, 0, 0), 0, 0));
 
                setLayout(new BorderLayout(12, 12));
                add(new JScrollPane(nodeList), BorderLayout.LINE_START);
                add(centerPanel, BorderLayout.CENTER);
+
+               I18nContainer.getInstance().registerRunnable(new Runnable() {
+
+                       public void run() {
+                               nodeInformationLabel.setText("<html><b>" + I18n.getMessage("jsite.node-manager.node-information") + "</b></html>");
+                               nodeNameLabel.setText(I18n.getMessage("jsite.node-manager.name") + ":");
+                               nodeHostnameLabel.setText(I18n.getMessage("jsite.node-manager.hostname") + ":");
+                               nodePortLabel.setText(I18n.getMessage("jsite.node-manager.port") + ":");
+                       }
+               });
        }
-       
+
        /**
         * {@inheritDoc}
         */
        @Override
        public void pageAdded(TWizard wizard) {
-               this.wizard = wizard;
-               wizard.setNextEnabled(nodeListModel.getSize() > 0);
+               this.wizard.setNextEnabled(nodeListModel.getSize() > 0);
+               this.wizard.setPreviousName(I18n.getMessage("jsite.wizard.previous"));
+               this.wizard.setNextName(I18n.getMessage("jsite.wizard.next"));
+               this.wizard.setQuitName(I18n.getMessage("jsite.wizard.quit"));
        }
 
+       /**
+        * Sets the node list.
+        *
+        * @param nodes
+        *            The list of nodes
+        */
        public void setNodes(Node[] nodes) {
                nodeListModel.clear();
-               for (Node node: nodes) {
+               for (Node node : nodes) {
                        nodeListModel.addElement(node);
                }
                nodeList.repaint();
                fireNodesUpdated(nodes);
        }
 
+       /**
+        * Returns the node list.
+        *
+        * @return The list of nodes
+        */
        public Node[] getNodes() {
                Node[] returnNodes = new Node[nodeListModel.getSize()];
                for (int nodeIndex = 0, nodeCount = nodeListModel.getSize(); nodeIndex < nodeCount; nodeIndex++) {
@@ -186,10 +286,25 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
                return returnNodes;
        }
 
+       /**
+        * Returns the currently selected node.
+        *
+        * @return The selected node, or <code>null</code> if no node is selected
+        */
        private Node getSelectedNode() {
                return (Node) nodeList.getSelectedValue();
        }
-       
+
+       /**
+        * Updates node name or hostname when the user types into the textfields.
+        *
+        * @see #insertUpdate(DocumentEvent)
+        * @see #removeUpdate(DocumentEvent)
+        * @see #changedUpdate(DocumentEvent)
+        * @see DocumentListener
+        * @param documentEvent
+        *            The document event
+        */
        private void updateTextField(DocumentEvent documentEvent) {
                Node node = getSelectedNode();
                if (node == null) {
@@ -200,6 +315,7 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
                try {
                        documentText = document.getText(0, document.getLength());
                } catch (BadLocationException ble1) {
+                       /* ignore. */
                }
                if (documentText == null) {
                        return;
@@ -220,14 +336,21 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
        // ACTIONS
        //
 
-       protected void addNode() {
+       /**
+        * Adds a new node to the list of nodes.
+        */
+       private void addNode() {
                Node node = new Node("localhost", 9481, I18n.getMessage("jsite.node-manager.new-node"));
                nodeListModel.addElement(node);
+               deleteNodeAction.setEnabled(nodeListModel.size() > 1);
                wizard.setNextEnabled(true);
                fireNodesUpdated(getNodes());
        }
 
-       protected void deleteNode() {
+       /**
+        * Deletes the currently selected node from the list of nodes.
+        */
+       private void deleteNode() {
                Node node = getSelectedNode();
                if (node == null) {
                        return;
@@ -235,9 +358,12 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
                if (JOptionPane.showConfirmDialog(wizard, I18n.getMessage("jsite.node-manager.delete-node.warning"), null, JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.CANCEL_OPTION) {
                        return;
                }
+               int nodeIndex = nodeListModel.indexOf(node);
                nodeListModel.removeElement(node);
                nodeList.repaint();
+               fireNodeSelected((Node) nodeListModel.get(Math.min(nodeIndex, nodeListModel.size() - 1)));
                fireNodesUpdated(getNodes());
+               deleteNodeAction.setEnabled(nodeListModel.size() > 1);
                wizard.setNextEnabled(nodeListModel.size() > 0);
        }
 
@@ -248,6 +374,7 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
        /**
         * {@inheritDoc}
         */
+       @SuppressWarnings("null")
        public void valueChanged(ListSelectionEvent e) {
                Object source = e.getSource();
                if (source instanceof JList) {
@@ -258,7 +385,7 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
                                nodeNameTextField.setEnabled(enabled);
                                nodeHostnameTextField.setEnabled(enabled);
                                nodePortSpinner.setEnabled(enabled);
-                               deleteNodeAction.setEnabled(enabled);
+                               deleteNodeAction.setEnabled(enabled && (nodeListModel.size() > 1));
                                if (enabled) {
                                        nodeNameTextField.setText(node.getName());
                                        nodeHostnameTextField.setText(node.getHostname());
@@ -314,6 +441,7 @@ public class NodeManagerPage extends TWizardPage implements ListSelectionListene
                        JSpinner sourceSpinner = (JSpinner) source;
                        if ("node-port".equals(sourceSpinner.getName())) {
                                selectedNode.setPort((Integer) sourceSpinner.getValue());
+                               fireNodeSelected(selectedNode);
                                nodeList.repaint();
                        }
                }