2ad2b4b2135bd22da4abfcc9c28e92973237afb5
[jSite2.git] / src / net / pterodactylus / jsite / gui / EditNodeDialog.java
1 /*
2  * jSite2 - NodeEditDialog.java -
3  * Copyright © 2008 David Roden
4  *
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.
9  *
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.
14  *
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.
18  */
19
20 package net.pterodactylus.jsite.gui;
21
22 import java.awt.BorderLayout;
23 import java.awt.FlowLayout;
24 import java.awt.GridBagConstraints;
25 import java.awt.GridBagLayout;
26 import java.awt.Insets;
27 import java.awt.event.ActionEvent;
28 import java.net.InetAddress;
29 import java.net.UnknownHostException;
30
31 import javax.swing.Action;
32 import javax.swing.BorderFactory;
33 import javax.swing.JButton;
34 import javax.swing.JCheckBox;
35 import javax.swing.JComponent;
36 import javax.swing.JDialog;
37 import javax.swing.JLabel;
38 import javax.swing.JOptionPane;
39 import javax.swing.JPanel;
40 import javax.swing.JTextField;
41 import javax.swing.border.EtchedBorder;
42
43 import net.pterodactylus.jsite.i18n.I18n;
44 import net.pterodactylus.jsite.main.Version;
45 import net.pterodactylus.util.swing.SwingUtils;
46
47 /**
48  * Dialog that lets the user edit the properties of a node.
49  * 
50  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
51  * @version $Id$
52  */
53 public class EditNodeDialog extends JDialog {
54
55         /** The user-given name of the node. */
56         private String name;
57
58         /** The hostname of the node. */
59         private String hostname;
60
61         /** The FNP port number of the node. */
62         private int port;
63
64         /** Whether the node is on the same machine. */
65         private boolean sameMachine;
66
67         /** Action of the okay button. */
68         private Action okayAction;
69
70         /** Action of the cancel button. */
71         private Action cancelAction;
72
73         /** The name textfield. */
74         private JTextField nameTextField;
75
76         /** The hostname textfield. */
77         private JTextField hostnameTextField;
78
79         /** The port textfield. */
80         private JTextField portTextField;
81
82         /** The same machine checkbox. */
83         private JCheckBox sameMachineCheckBox;
84
85         /** Whether the dialog was cancelled. */
86         private boolean cancelled;
87
88         /**
89          * Creates a new node edit dialog with the given parent.
90          * 
91          * @param parentDialog
92          *            The parent dialog of this dialog
93          */
94         public EditNodeDialog(JDialog parentDialog) {
95                 super(parentDialog, I18n.get("editNodeDialog.title") + " – jSite " + Version.getVersion(), true);
96                 initActions();
97                 initComponents();
98                 pack();
99                 SwingUtils.center(this);
100         }
101
102         //
103         // ACCESSORS
104         //
105
106         /**
107          * Returns the user-given name of the node.
108          * 
109          * @return The user-given name of the node
110          */
111         public String getNodeName() {
112                 return name;
113         }
114
115         /**
116          * Sets the user-given name of the node.
117          * 
118          * @param name
119          *            The name of the node
120          */
121         public void setNodeName(String name) {
122                 this.name = name;
123                 nameTextField.setText(name);
124         }
125
126         /**
127          * Returns the hostname of the node.
128          * 
129          * @return The hostname of the node
130          */
131         public String getNodeHostname() {
132                 return hostname;
133         }
134
135         /**
136          * Sets the hostname of the node.
137          * 
138          * @param hostname
139          *            The hostname of the node
140          */
141         public void setNodeHostname(String hostname) {
142                 this.hostname = hostname;
143                 hostnameTextField.setText(hostname);
144         }
145
146         /**
147          * Returns the FCP port number of the node.
148          * 
149          * @return The FCP port number of the node
150          */
151         public int getNodePort() {
152                 return port;
153         }
154
155         /**
156          * Sets the FCP port number of the node.
157          * 
158          * @param port
159          *            The FCP port number of the node
160          */
161         public void setNodePort(int port) {
162                 this.port = port;
163                 portTextField.setText(String.valueOf(port));
164         }
165
166         /**
167          * Returns whether the node is on the same machine as jSite.
168          * 
169          * @return <code>true</code> if the node is on the same machine as jSite,
170          *         <code>false</code> otherwise
171          */
172         public boolean isNodeOnSameMachine() {
173                 return sameMachine;
174         }
175
176         /**
177          * Sets whether the node is on the same machine as jSite.
178          * 
179          * @param sameMachine
180          *            <code>true</code> if the node is on the same machine as
181          *            jSite, <code>false</code> otherwise
182          */
183         public void setNodeOnSameMachine(boolean sameMachine) {
184                 this.sameMachine = sameMachine;
185                 sameMachineCheckBox.setSelected(sameMachine);
186         }
187
188         /**
189          * Returns whether the dialog was cancelled.
190          * 
191          * @return <code>true</code> if the dialog was cancelled,
192          *         <code>false</code> if the user clicked “okay”
193          */
194         public boolean wasCancelled() {
195                 return cancelled;
196         }
197
198         //
199         // PRIVATE METHODS
200         //
201
202         /**
203          * Initializes all actions.
204          */
205         private void initActions() {
206                 okayAction = new I18nAction("general.button.okay") {
207
208                         /**
209                          * {@inheritDoc}
210                          */
211                         @SuppressWarnings("synthetic-access")
212                         public void actionPerformed(ActionEvent e) {
213                                 confirm();
214                         }
215                 };
216                 cancelAction = new I18nAction("general.button.cancel") {
217
218                         /**
219                          * {@inheritDoc}
220                          */
221                         @SuppressWarnings("synthetic-access")
222                         public void actionPerformed(ActionEvent e) {
223                                 cancel();
224                         }
225                 };
226         }
227
228         /**
229          * Initializes all components.
230          */
231         private void initComponents() {
232                 JPanel rootPanel = new JPanel(new BorderLayout(12, 12));
233                 setContentPane(rootPanel);
234                 rootPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
235
236                 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 12, 12));
237                 rootPanel.add(buttonPanel, BorderLayout.PAGE_END);
238                 buttonPanel.setBorder(BorderFactory.createEmptyBorder(-12, -12, -12, -12));
239                 buttonPanel.add(new JButton(cancelAction));
240                 JButton okayButton = new JButton(okayAction);
241                 buttonPanel.add(okayButton);
242                 getRootPane().setDefaultButton(okayButton);
243
244                 JPanel contentPanel = new JPanel(new GridBagLayout());
245                 rootPanel.add(contentPanel, BorderLayout.CENTER);
246                 contentPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(12, 12, 12, 12)));
247
248                 nameTextField = new JTextField();
249                 contentPanel.add(createLabel(I18n.get("editNodeDialog.label.name"), nameTextField), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
250                 contentPanel.add(nameTextField, new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 12, 0, 0), 0, 0));
251
252                 hostnameTextField = new JTextField();
253                 contentPanel.add(createLabel(I18n.get("editNodeDialog.label.hostname"), hostnameTextField), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
254                 contentPanel.add(hostnameTextField, new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(12, 12, 0, 0), 0, 0));
255
256                 portTextField = new JTextField();
257                 contentPanel.add(createLabel(I18n.get("editNodeDialog.label.port"), portTextField), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
258                 contentPanel.add(portTextField, new GridBagConstraints(1, 2, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(12, 12, 0, 0), 0, 0));
259
260                 sameMachineCheckBox = new JCheckBox(new I18nAction("editNodeDialog.checkbox.sameMachine") {
261
262                         public void actionPerformed(ActionEvent e) {
263                                 /* don't do anything. */
264                         }
265                 });
266                 contentPanel.add(sameMachineCheckBox, new GridBagConstraints(0, 3, 2, 1, 1, 1, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(12, 0, 0, 0), 0, 0));
267         }
268
269         /**
270          * Creates a label whose name and mnemonic are initialized from the given
271          * i18n property.
272          * 
273          * @param i18nBasename
274          *            The i18n property basename of the label
275          * @param labelFor
276          *            The component this label describes
277          * @return The created label
278          */
279         private JLabel createLabel(String i18nBasename, JComponent labelFor) {
280                 JLabel label = new JLabel(I18n.get(i18nBasename + ".name"));
281                 label.setDisplayedMnemonic(I18n.getKey(i18nBasename + ".mnemonic"));
282                 label.setLabelFor(labelFor);
283                 return label;
284         }
285
286         //
287         // PRIVATE ACTIONS
288         //
289
290         /**
291          * Checks the name textfield for valid input.
292          * 
293          * @return <code>true</code> if the name textfield seem okay,
294          *         <code>false</code> if there is an error
295          */
296         private boolean verifyName() {
297                 return (nameTextField.getText().trim().length() != 0);
298         }
299
300         /**
301          * Verifies the hostname textfield by resolving the given name.
302          * 
303          * @return <code>true</code> if the hostname is not empty and can be
304          *         resolved, <code>false</code> otherwise
305          */
306         private boolean verifyHostname() {
307                 if (hostnameTextField.getText().trim().length() == 0) {
308                         return false;
309                 }
310                 try {
311                         InetAddress.getByName(hostnameTextField.getText().trim());
312                         return true;
313                 } catch (UnknownHostException uhe1) {
314                         return false;
315                 }
316         }
317
318         /**
319          * Verifies that the port number is numeric and in the range from
320          * <code>0</code> to <code>65535</code>.
321          * 
322          * @return <code>true</code> if the port number is okay,
323          *         <code>false</code> otherwise
324          */
325         private boolean verifyPort() {
326                 try {
327                         int portNumber = Integer.valueOf(portTextField.getText().trim());
328                         if ((portNumber > 0) && (portNumber < 65536)) {
329                                 return true;
330                         }
331                 } catch (NumberFormatException nfe1) {
332                         /* ignore. */
333                 }
334                 return false;
335         }
336
337         /**
338          * Confirms the node settings and closes the dialog.
339          */
340         private void confirm() {
341                 if (!verifyName()) {
342                         JOptionPane.showMessageDialog(this, I18n.get("editNodeDialog.error.name.message"), I18n.get("editNodeDialog.error.name.title"), JOptionPane.ERROR_MESSAGE);
343                         return;
344                 }
345                 if (!verifyHostname()) {
346                         JOptionPane.showMessageDialog(this, I18n.get("editNodeDialog.error.hostname.message"), I18n.get("editNodeDialog.error.hostname.title"), JOptionPane.ERROR_MESSAGE);
347                         return;
348                 }
349                 if (!verifyPort()) {
350                         JOptionPane.showMessageDialog(this, I18n.get("editNodeDialog.error.port.message"), I18n.get("editNodeDialog.error.port.title"), JOptionPane.ERROR_MESSAGE);
351                         return;
352                 }
353                 name = nameTextField.getText().trim();
354                 hostname = hostnameTextField.getText().trim();
355                 try {
356                         port = Integer.parseInt(portTextField.getText().trim());
357                 } catch (NumberFormatException nfe1) {
358                         /* should not occur, the value was checked! */
359                         assert false: "port number is invalid though it was checked!";
360                 }
361                 sameMachine = sameMachineCheckBox.isSelected();
362                 cancelled = false;
363                 setVisible(false);
364         }
365
366         /**
367          * Cancels the node settings and closes the dialog.
368          */
369         private void cancel() {
370                 cancelled = true;
371                 setVisible(false);
372         }
373
374 }