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.Collections;
27 import java.util.List;
29 import javax.swing.AbstractListModel;
30 import javax.swing.Action;
31 import javax.swing.BorderFactory;
32 import javax.swing.JButton;
33 import javax.swing.JDialog;
34 import javax.swing.JFrame;
35 import javax.swing.JList;
36 import javax.swing.JPanel;
37 import javax.swing.JScrollPane;
38 import javax.swing.ListCellRenderer;
39 import javax.swing.border.EtchedBorder;
40 import javax.swing.event.ListSelectionEvent;
41 import javax.swing.event.ListSelectionListener;
43 import net.pterodactylus.jsite.core.Node;
44 import net.pterodactylus.jsite.i18n.I18n;
45 import net.pterodactylus.jsite.main.Version;
46 import net.pterodactylus.util.swing.SwingUtils;
49 * Dialog that lets the user manage her nodes.
51 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
54 public class ManageNodesDialog extends JDialog implements ListSelectionListener {
56 /** The current list of nodes. */
57 private List<NodeWrapper> nodes = new ArrayList<NodeWrapper>();
59 /** The current default node. */
60 private Node defaultNode;
62 /** The “add node” action. */
63 private Action addNodeAction;
65 /** The “edit node” action. */
66 private Action editNodeAction;
68 /** The “delete node” action. */
69 private Action deleteNodeAction;
71 /** The “set default node” action. */
72 private Action setDefaultNodeAction;
74 /** The “okay” action. */
75 private Action okayAction;
77 /** The “cancel” action. */
78 private Action cancelAction;
80 /** The “edit node” dialog. */
81 private EditNodeDialog editNodeDialog;
84 private JList nodeList;
86 /** The mode for the node list. */
87 private NodeListModel nodeListModel = new NodeListModel();
90 * Creates a new node manager dialog.
93 * The parent frame of the dialog
95 public ManageNodesDialog(JFrame parentFrame) {
96 super(parentFrame, I18n.get("manageNodesDialog.title") + " – jSite " + Version.getVersion(), true);
101 SwingUtils.center(this);
109 * Returns the default node.
111 * @return The default node, or <code>null</code> if no default node has
114 public Node getDefaultNode() {
119 * Sets the default node.
122 * The default node, or <code>null</code> if no default node
125 public void setDefaultNode(Node defaultNode) {
126 this.defaultNode = defaultNode;
130 * Returns the list of nodes.
132 * @return The list of nodes
134 public List<Node> getNodeList() {
135 List<Node> nodes = new ArrayList<Node>();
136 for (NodeWrapper nodeWrapper: this.nodes) {
137 nodes.add(nodeWrapper.getWrappedNode());
143 * Sets the list of nodes.
148 public void setNodeList(List<Node> nodes) {
150 for (Node node: nodes) {
151 this.nodes.add(new NodeWrapper(node));
153 nodeListModel.setNodeList(this.nodes);
161 * Initializes all actions.
163 private void initActions() {
164 okayAction = new I18nAction("general.button.okay") {
169 @SuppressWarnings("synthetic-access")
170 public void actionPerformed(ActionEvent e) {
174 cancelAction = new I18nAction("general.button.cancel") {
179 @SuppressWarnings("synthetic-access")
180 public void actionPerformed(ActionEvent e) {
184 addNodeAction = new I18nAction("manageNodesDialog.button.addNode") {
189 @SuppressWarnings("synthetic-access")
190 public void actionPerformed(ActionEvent e) {
194 editNodeAction = new I18nAction("manageNodesDialog.button.editNode", false) {
199 @SuppressWarnings("synthetic-access")
200 public void actionPerformed(ActionEvent e) {
204 deleteNodeAction = new I18nAction("manageNodesDialog.button.deleteNode", false) {
209 @SuppressWarnings("synthetic-access")
210 public void actionPerformed(ActionEvent e) {
214 setDefaultNodeAction = new I18nAction("manageNodesDialog.button.setDefaultNode", false) {
219 @SuppressWarnings("synthetic-access")
220 public void actionPerformed(ActionEvent e) {
227 * Initializes all components.
229 private void initComponents() {
230 JPanel rootPanel = new JPanel(new BorderLayout(12, 12));
231 rootPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
233 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 12, 12));
234 rootPanel.add(buttonPanel, BorderLayout.PAGE_END);
235 buttonPanel.setBorder(BorderFactory.createEmptyBorder(-12, -12, -12, -12));
237 buttonPanel.add(new JButton(cancelAction));
238 JButton okayButton = new JButton(okayAction);
239 getRootPane().setDefaultButton(okayButton);
240 buttonPanel.add(okayButton);
242 JPanel contentPanel = new JPanel(new BorderLayout(12, 12));
243 rootPanel.add(contentPanel, BorderLayout.CENTER);
244 contentPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(12, 12, 12, 12)));
246 JPanel listButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 12, 12));
247 contentPanel.add(listButtonPanel, BorderLayout.PAGE_END);
248 listButtonPanel.setBorder(BorderFactory.createEmptyBorder(-12, -12, -12, -12));
249 listButtonPanel.add(new JButton(addNodeAction));
250 listButtonPanel.add(new JButton(editNodeAction));
251 listButtonPanel.add(new JButton(deleteNodeAction));
252 listButtonPanel.add(new JButton(setDefaultNodeAction));
254 nodeList = new JList(nodeListModel);
255 nodeList.addListSelectionListener(this);
256 contentPanel.add(new JScrollPane(nodeList), BorderLayout.CENTER);
258 setContentPane(rootPanel);
262 * Initializes all child dialogs.
264 private void initDialogs() {
265 editNodeDialog = new EditNodeDialog(this);
273 * Adds a new node via {@link #editNodeDialog}.
275 private void addNode() {
276 editNodeDialog.setNodeName("New Node");
277 editNodeDialog.setNodeHostname("localhost");
278 editNodeDialog.setNodePort(9481);
279 editNodeDialog.setNodeOnSameMachine(true);
280 editNodeDialog.setVisible(true);
281 if (!editNodeDialog.wasCancelled()) {
282 Node newNode = new Node();
283 newNode.setName(editNodeDialog.getNodeName());
284 newNode.setHostname(editNodeDialog.getNodeHostname());
285 newNode.setPort(editNodeDialog.getNodePort());
286 NodeWrapper newNodeWrapper = new NodeWrapper(newNode);
287 if (nodes.isEmpty()) {
288 defaultNode = newNode;
289 newNodeWrapper.setDefaultNode(true);
291 nodes.add(new NodeWrapper(newNode));
292 nodeListModel.setNodeList(nodes);
297 * Edits a node via {@link #editNodeDialog}.
299 private void editNode() {
300 NodeWrapper selectedNodeWrapper = (NodeWrapper) nodeList.getSelectedValue();
301 Node selectedNode = selectedNodeWrapper.getWrappedNode();
302 editNodeDialog.setNodeName(selectedNode.getName());
303 editNodeDialog.setNodeHostname(selectedNode.getHostname());
304 editNodeDialog.setNodePort(selectedNode.getPort());
305 editNodeDialog.setNodeOnSameMachine(selectedNode.isSameMachine());
306 editNodeDialog.setVisible(true);
307 if (!editNodeDialog.wasCancelled()) {
308 selectedNode.setName(editNodeDialog.getNodeName());
309 selectedNode.setHostname(editNodeDialog.getNodeHostname());
310 selectedNode.setPort(editNodeDialog.getNodePort());
311 selectedNode.setSameMachine(editNodeDialog.isNodeOnSameMachine());
317 * Deletes the selected node.
319 private void deleteNode() {
320 NodeWrapper selectedNode = (NodeWrapper) nodeList.getSelectedValue();
321 nodes.remove(selectedNode);
322 nodeList.clearSelection();
327 * Sets the default node to the selected node.
329 private void setDefaultNode() {
330 NodeWrapper selectedNode = (NodeWrapper) nodeList.getSelectedValue();
331 for (NodeWrapper nodeWrapper: nodes) {
332 nodeWrapper.setDefaultNode(nodeWrapper == selectedNode);
338 * This method is called when the “okay” button is pressed. The nodes from
339 * the list are read and the {@link #nodes} and {@link #defaultNode} members
340 * are set so that the calling code can use {@link #getNodeList()} and
341 * {@link #getDefaultNode()} to get the changed values.
343 private void confirm() {
348 * Cancels the dialog.
350 private void cancel() {
355 // INTERFACE ListSelectionListener
361 public void valueChanged(ListSelectionEvent listSelectionEvent) {
362 JList list = (JList) listSelectionEvent.getSource();
363 int selectCount = list.getSelectedIndices().length;
364 editNodeAction.setEnabled(selectCount == 1);
365 deleteNodeAction.setEnabled(selectCount >= 1);
366 setDefaultNodeAction.setEnabled(selectCount == 1);
370 * Wrapper around a {@link Node} to store whether a node is the default
371 * node. This frees us from having to write a {@link ListCellRenderer} for
372 * {@link ManageNodesDialog#nodeList}.
374 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
377 private static class NodeWrapper {
379 /** The wrapped node. */
380 private final Node wrappedNode;
382 /** The default node. */
383 private boolean defaultNode;
386 * Creates a new node wrapper around the given node.
391 public NodeWrapper(Node wrappedNode) {
392 this.wrappedNode = wrappedNode;
396 * Returns the wrapped node.
398 * @return The wrapped node
400 public Node getWrappedNode() {
405 * Returns whether the wrapped node is the default node.
407 * @return <code>true</code> if the wrapped node is the default node,
408 * <code>false</code> otherwise
410 public boolean isDefaultNode() {
415 * Sets whether the wrapped node is the default node.
418 * <code>true</code> if the wrapped node is the default
419 * node, <code>false</code> otherwise
421 public void setDefaultNode(boolean defaultNode) {
422 this.defaultNode = defaultNode;
429 public String toString() {
430 return wrappedNode.toString() + (defaultNode ? " (default)" : "");
436 * List model for the {@link ManageNodesDialog#nodeList}. TODO
438 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
441 private class NodeListModel extends AbstractListModel {
443 /** The list of wrapped nodes. */
444 @SuppressWarnings("hiding")
445 private List<NodeWrapper> nodeList = Collections.emptyList();
448 * Creates a new node list model.
450 public NodeListModel() {
454 * Sets the new node list.
457 * The list of nodes to display
459 public void setNodeList(List<NodeWrapper> nodeList) {
460 this.nodeList = nodeList;
461 fireContentsChanged(this, 0, nodeList.size() - 1);
467 @SuppressWarnings("synthetic-access")
468 public Object getElementAt(int index) {
469 NodeWrapper currentNodeWrapper = nodeList.get(index);
470 return currentNodeWrapper;
476 public int getSize() {
477 return nodeList.size();