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