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