2 * jSite2 - ManageNodeDialog.java -
3 * Copyright © 2008 David Roden
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 package net.pterodactylus.jsite.gui;
22 import java.awt.BorderLayout;
23 import java.awt.FlowLayout;
24 import java.awt.event.ActionEvent;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Iterator;
28 import java.util.List;
30 import javax.swing.AbstractListModel;
31 import javax.swing.BorderFactory;
32 import javax.swing.JButton;
33 import javax.swing.JDialog;
34 import javax.swing.JList;
35 import javax.swing.JOptionPane;
36 import javax.swing.JPanel;
37 import javax.swing.JScrollPane;
38 import javax.swing.border.EtchedBorder;
39 import javax.swing.event.ListSelectionEvent;
40 import javax.swing.event.ListSelectionListener;
42 import net.pterodactylus.jsite.core.Core;
43 import net.pterodactylus.jsite.core.Node;
44 import net.pterodactylus.jsite.i18n.I18n;
45 import net.pterodactylus.jsite.i18n.I18nable;
46 import net.pterodactylus.jsite.i18n.gui.I18nAction;
47 import net.pterodactylus.jsite.main.Version;
48 import net.pterodactylus.util.swing.SwingUtils;
51 * Dialog that lets the user manage her nodes.
53 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
56 public class ManageNodesDialog extends JDialog implements ListSelectionListener, I18nable {
59 private final Core core;
61 /** The original list of nodes. */
62 private List<Node> originalNodeList;
64 /** The “add node” action. */
65 private I18nAction addNodeAction;
67 /** The “edit node” action. */
68 private I18nAction editNodeAction;
70 /** The “delete node” action. */
71 private I18nAction deleteNodeAction;
73 /** The “okay” action. */
74 private I18nAction okayAction;
76 /** The “cancel” action. */
77 private I18nAction cancelAction;
79 /** The “edit node” dialog. */
80 private EditNodeDialog editNodeDialog;
83 private JList nodeList;
85 /** The mode for the node list. */
86 private NodeListModel nodeListModel = new NodeListModel();
89 * Creates a new node manager dialog.
91 * @param swingInterface
94 public ManageNodesDialog(SwingInterface swingInterface) {
95 super(swingInterface.getMainWindow(), I18n.get("manageNodesDialog.title") + " – jSite " + Version.getVersion(), true);
96 this.core = swingInterface.getCore();
101 I18n.registerI18nable(this);
102 SwingUtils.center(this);
110 * Returns the list of nodes.
112 * @return The list of nodes
114 public List<Node> getNodeList() {
115 return originalNodeList;
119 * Sets the list of nodes.
124 public void setNodeList(List<Node> nodeList) {
125 originalNodeList = nodeList;
126 nodeListModel.clear();
127 for (Node node: nodeList) {
128 nodeListModel.addNode(node);
137 * Initializes all actions.
139 private void initActions() {
140 okayAction = new I18nAction("general.button.okay") {
145 @SuppressWarnings("synthetic-access")
146 public void actionPerformed(ActionEvent e) {
150 cancelAction = new I18nAction("general.button.cancel") {
155 @SuppressWarnings("synthetic-access")
156 public void actionPerformed(ActionEvent e) {
160 addNodeAction = new I18nAction("manageNodesDialog.button.addNode") {
165 @SuppressWarnings("synthetic-access")
166 public void actionPerformed(ActionEvent e) {
170 editNodeAction = new I18nAction("manageNodesDialog.button.editNode", false) {
175 @SuppressWarnings("synthetic-access")
176 public void actionPerformed(ActionEvent e) {
180 deleteNodeAction = new I18nAction("manageNodesDialog.button.deleteNode", false) {
185 @SuppressWarnings("synthetic-access")
186 public void actionPerformed(ActionEvent e) {
193 * Initializes all components.
195 private void initComponents() {
196 JPanel rootPanel = new JPanel(new BorderLayout(12, 12));
197 rootPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
199 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 12, 12));
200 rootPanel.add(buttonPanel, BorderLayout.PAGE_END);
201 buttonPanel.setBorder(BorderFactory.createEmptyBorder(-12, -12, -12, -12));
203 buttonPanel.add(new JButton(cancelAction));
204 JButton okayButton = new JButton(okayAction);
205 getRootPane().setDefaultButton(okayButton);
206 buttonPanel.add(okayButton);
208 JPanel contentPanel = new JPanel(new BorderLayout(12, 12));
209 rootPanel.add(contentPanel, BorderLayout.CENTER);
210 contentPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(12, 12, 12, 12)));
212 JPanel listButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 12, 12));
213 contentPanel.add(listButtonPanel, BorderLayout.PAGE_END);
214 listButtonPanel.setBorder(BorderFactory.createEmptyBorder(-12, -12, -12, -12));
215 listButtonPanel.add(new JButton(addNodeAction));
216 listButtonPanel.add(new JButton(editNodeAction));
217 listButtonPanel.add(new JButton(deleteNodeAction));
219 nodeList = new JList(nodeListModel);
220 nodeList.addListSelectionListener(this);
221 contentPanel.add(new JScrollPane(nodeList), BorderLayout.CENTER);
223 setContentPane(rootPanel);
227 * Initializes all child dialogs.
229 private void initDialogs() {
230 editNodeDialog = new EditNodeDialog(this);
238 * Adds a new node via {@link #editNodeDialog}.
240 private void addNode() {
241 editNodeDialog.setNodeName("New Node");
242 editNodeDialog.setNodeHostname("localhost");
243 editNodeDialog.setNodePort(9481);
244 editNodeDialog.setNodeOnSameMachine(true);
245 editNodeDialog.setVisible(true);
246 if (!editNodeDialog.wasCancelled()) {
247 Node newNode = new Node();
248 newNode.setName(editNodeDialog.getNodeName());
249 newNode.setHostname(editNodeDialog.getNodeHostname());
250 newNode.setPort(editNodeDialog.getNodePort());
251 nodeListModel.addNode(newNode);
256 * Edits a node via {@link #editNodeDialog}.
258 private void editNode() {
259 Node selectedNode = (Node) nodeList.getSelectedValue();
260 editNodeDialog.setNodeName(selectedNode.getName());
261 editNodeDialog.setNodeHostname(selectedNode.getHostname());
262 editNodeDialog.setNodePort(selectedNode.getPort());
263 editNodeDialog.setNodeOnSameMachine(selectedNode.isSameMachine());
264 editNodeDialog.setVisible(true);
265 if (!editNodeDialog.wasCancelled()) {
266 selectedNode.setName(editNodeDialog.getNodeName());
267 selectedNode.setHostname(editNodeDialog.getNodeHostname());
268 selectedNode.setPort(editNodeDialog.getNodePort());
269 selectedNode.setSameMachine(editNodeDialog.isNodeOnSameMachine());
275 * Deletes the selected node.
277 private void deleteNodes() {
278 Object[] selectedNodes = nodeList.getSelectedValues();
279 for (Object node: selectedNodes) {
280 Node selectedNode = (Node) node;
281 if (core.isNodeConnected(selectedNode)) {
282 int response = JOptionPane.showConfirmDialog(this, I18n.get("manageNodesDialog.error.nodeConnected.message", selectedNode.getName()), I18n.get("manageNodesDialog.error.nodeConnected.title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
283 if (response == JOptionPane.CANCEL_OPTION) {
285 } else if (response == JOptionPane.NO_OPTION) {
289 nodeListModel.removeNode(selectedNode);
291 nodeList.clearSelection();
295 * Checks whether the list of nodes is not empty.
297 * @return <code>true</code> if there is at least one node defined,
298 * <code>false</code> otherwise
300 private boolean verifyNodesExist() {
301 return nodeListModel.getSize() > 0;
305 * This method is called when the “okay” button is pressed. The nodes from
306 * the list are read and the {@link #originalNodeList} member is set so that
307 * the calling code can use {@link #getNodeList()} to get the changed
310 private void confirm() {
311 if (!verifyNodesExist()) {
312 JOptionPane.showMessageDialog(this, I18n.get("manageNodesDialog.error.nodeListEmpty.message"), I18n.get("manageNodesDialog.error.nodeListEmpty.title"), JOptionPane.ERROR_MESSAGE);
315 originalNodeList.clear();
316 for (Node node: nodeListModel) {
317 originalNodeList.add(node);
323 * Cancels the dialog.
325 private void cancel() {
330 // INTERFACE ListSelectionListener
336 public void valueChanged(ListSelectionEvent listSelectionEvent) {
337 JList list = (JList) listSelectionEvent.getSource();
338 int selectCount = list.getSelectedIndices().length;
339 editNodeAction.setEnabled(selectCount == 1);
340 deleteNodeAction.setEnabled(selectCount >= 1);
344 // INTERFACE I18nable
350 public void updateI18n() {
351 okayAction.updateI18n();
352 cancelAction.updateI18n();
353 addNodeAction.updateI18n();
354 editNodeAction.updateI18n();
355 deleteNodeAction.updateI18n();
356 setTitle(I18n.get("manageNodesDialog.title") + " – jSite " + Version.getVersion());
357 SwingUtils.repackCentered(this);
361 * List model for the {@link ManageNodesDialog#nodeList}. TODO
363 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
366 private class NodeListModel extends AbstractListModel implements Iterable<Node> {
368 /** The list of nodes. */
369 @SuppressWarnings("hiding")
370 private final List<Node> nodeList = new ArrayList<Node>();
373 * Creates a new node list model.
375 public NodeListModel() {
379 * Adds the given node to the list model.
381 * @see Collection#add(Object)
385 public void addNode(Node node) {
387 fireIntervalAdded(this, nodeList.size() - 1, nodeList.size() - 1);
391 * Removes the given node from the list model.
393 * @see Collection#remove(Object)
397 public void removeNode(Node node) {
398 int nodeIndex = nodeList.indexOf(node);
399 nodeList.remove(node);
400 fireIntervalRemoved(this, nodeIndex, nodeIndex);
404 * Removes all nodes from the list model.
406 * @see Collection#clear()
408 public void clear() {
409 int nodeCount = nodeList.size();
412 fireIntervalRemoved(this, 0, nodeCount - 1);
419 public Iterator<Node> iterator() {
420 return nodeList.iterator();
426 @SuppressWarnings("synthetic-access")
427 public Object getElementAt(int index) {
428 return nodeList.get(index);
434 public int getSize() {
435 return nodeList.size();