add package javadoc
[jSite2.git] / src / net / pterodactylus / jsite / gui / ProjectPanel.java
1 /*
2  * jSite2 - ProjectPanel.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.util.logging.Level;
29 import java.util.logging.Logger;
30
31 import javax.swing.AbstractAction;
32 import javax.swing.Action;
33 import javax.swing.BorderFactory;
34 import javax.swing.DefaultComboBoxModel;
35 import javax.swing.JButton;
36 import javax.swing.JComboBox;
37 import javax.swing.JFileChooser;
38 import javax.swing.JPanel;
39 import javax.swing.JTextField;
40 import javax.swing.event.DocumentEvent;
41 import javax.swing.event.DocumentListener;
42 import javax.swing.text.Document;
43
44 import net.pterodactylus.jsite.core.Node;
45 import net.pterodactylus.jsite.core.Project;
46 import net.pterodactylus.jsite.i18n.I18n;
47 import net.pterodactylus.jsite.i18n.I18nable;
48 import net.pterodactylus.jsite.i18n.gui.I18nAction;
49 import net.pterodactylus.jsite.i18n.gui.I18nLabel;
50 import net.pterodactylus.util.logging.Logging;
51
52 /**
53  * A panel that contains all information about a project and lets the user edit
54  * the properties of the project.
55  * 
56  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
57  */
58 public class ProjectPanel extends JPanel implements DocumentListener, I18nable {
59
60         /** Logger. */
61         @SuppressWarnings("unused")
62         private static final Logger logger = Logging.getLogger(ProjectPanel.class.getName());
63
64         /** The Swing interface. */
65         private final SwingInterface swingInterface;
66
67         /** The project to show. */
68         private final Project project;
69
70         /** The “change base path” action. */
71         private I18nAction changeBasePathAction;
72
73         /** The “edit files” action. */
74         private I18nAction editFilesAction;
75
76         /** The “name” label. */
77         private I18nLabel nameLabel;
78
79         /** The “name” textfield. */
80         private JTextField nameTextField;
81
82         /** The “description” label. */
83         private I18nLabel descriptionLabel;
84
85         /** The “description” textfield. */
86         private JTextField descriptionTextField;
87
88         /** The “base path” label. */
89         private I18nLabel basePathLabel;
90
91         /** The “base path” textfield. */
92         private JTextField basePathTextField;
93
94         /** The “node” label. */
95         private I18nLabel nodeLabel;
96
97         /** The “node” action. */
98         private Action nodeAction;
99
100         /** The “node” combo box. */
101         private JComboBox nodeComboBox;
102
103         /**
104          * Creates a new project panel.
105          * 
106          * @param swingInterface
107          *            The Swing interface
108          * @param project
109          *            The project to display
110          */
111         public ProjectPanel(SwingInterface swingInterface, Project project) {
112                 super(new BorderLayout(12, 12));
113                 logger.log(Level.FINEST, "project: " + project);
114                 this.swingInterface = swingInterface;
115                 this.project = project;
116                 initActions();
117                 initComponents();
118         }
119
120         //
121         // ACCESSORS
122         //
123
124         /**
125          * Returns the project that is displayed in this panel.
126          * 
127          * @return The project of this panel
128          */
129         public Project getProject() {
130                 return project;
131         }
132
133         //
134         // ACTIONS
135         //
136
137         /**
138          * Adds the given node to the node combo boxes in all {@link ProjectPanel}s.
139          * 
140          * @param node
141          *            The node to add
142          */
143         public void addNode(Node node) {
144                 ((DefaultComboBoxModel) nodeComboBox.getModel()).addElement(node);
145         }
146
147         /**
148          * Removes the given node from the node combo boxes in all
149          * {@link ProjectPanel}s.
150          * 
151          * @param node
152          *            The node to remove
153          */
154         public void removeNode(Node node) {
155                 ((DefaultComboBoxModel) nodeComboBox.getModel()).removeElement(node);
156         }
157
158         //
159         // PRIVATE METHODS
160         //
161
162         /**
163          * Initializes all actions.
164          */
165         private void initActions() {
166                 changeBasePathAction = new I18nAction("projectPanel.button.changeBasePath") {
167
168                         /**
169                          * {@inheritDoc}
170                          */
171                         @SuppressWarnings("synthetic-access")
172                         public void actionPerformed(ActionEvent actionEvent) {
173                                 changeBasePath();
174                         }
175                 };
176                 editFilesAction = new I18nAction("projectPanel.button.editFiles") {
177
178                         /**
179                          * {@inheritDoc}
180                          */
181                         @SuppressWarnings("synthetic-access")
182                         public void actionPerformed(ActionEvent actionEvent) {
183                                 editFiles();
184                         }
185                 };
186                 nodeAction = new AbstractAction() {
187
188                         /**
189                          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
190                          */
191                         @SuppressWarnings("synthetic-access")
192                         public void actionPerformed(ActionEvent actionEvent) {
193                                 Node node = (Node) nodeComboBox.getSelectedItem();
194                                 project.setNode(node);
195                         }
196                 };
197         }
198
199         /**
200          * Initializes all components of the panel.
201          */
202         private void initComponents() {
203                 setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
204
205                 JPanel propertiesPanel = createPropertiesPanel();
206                 add(propertiesPanel, BorderLayout.CENTER);
207
208                 JPanel buttonPanel = createButtonPanel();
209                 add(buttonPanel, BorderLayout.PAGE_END);
210         }
211
212         /**
213          * Creates the properties panel.
214          * 
215          * @return The properties panel
216          */
217         private JPanel createPropertiesPanel() {
218                 JPanel propertiesPanel = new JPanel(new GridBagLayout());
219
220                 nameTextField = new JTextField(project.getName());
221                 nameTextField.getDocument().addDocumentListener(this);
222                 nameLabel = new I18nLabel("projectPanel.label.name", nameTextField);
223                 propertiesPanel.add(nameLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
224                 propertiesPanel.add(nameTextField, new GridBagConstraints(1, 0, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 12, 0, 0), 0, 0));
225
226                 descriptionTextField = new JTextField(project.getDescription());
227                 descriptionTextField.getDocument().addDocumentListener(this);
228                 descriptionLabel = new I18nLabel("projectPanel.label.description", descriptionTextField);
229                 propertiesPanel.add(descriptionLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 0, 0, 0), 0, 0));
230                 propertiesPanel.add(descriptionTextField, new GridBagConstraints(1, 1, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0));
231
232                 basePathTextField = new JTextField(project.getBasePath());
233                 basePathTextField.setEditable(false);
234                 basePathLabel = new I18nLabel("projectPanel.label.basePath");
235                 JButton changeBasePathButton = new JButton(changeBasePathAction);
236                 JButton editFilesButton = new JButton(editFilesAction);
237                 propertiesPanel.add(basePathLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 0, 0, 0), 0, 0));
238                 propertiesPanel.add(basePathTextField, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(12, 12, 0, 0), 0, 0));
239                 propertiesPanel.add(changeBasePathButton, new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0));
240                 propertiesPanel.add(editFilesButton, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0));
241
242                 nodeComboBox = new JComboBox(new DefaultComboBoxModel());
243                 ((DefaultComboBoxModel) nodeComboBox.getModel()).addElement(null);
244                 for (Node node : swingInterface.getNodes()) {
245                         ((DefaultComboBoxModel) nodeComboBox.getModel()).addElement(node);
246                 }
247                 nodeComboBox.setSelectedItem(project.getNode());
248                 nodeComboBox.addActionListener(nodeAction);
249                 nodeLabel = new I18nLabel("projectPanel.label.node", nodeComboBox);
250                 propertiesPanel.add(nodeLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 0, 0, 0), 0, 0));
251                 propertiesPanel.add(nodeComboBox, new GridBagConstraints(1, 3, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0));
252
253                 propertiesPanel.add(new JPanel(), new GridBagConstraints(0, 4, 4, 1, 1.0, 1.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
254
255                 return propertiesPanel;
256         }
257
258         /**
259          * Creates the button panel.
260          * 
261          * @return The button panel
262          */
263         private JPanel createButtonPanel() {
264                 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 12, 12));
265                 buttonPanel.setBorder(BorderFactory.createEmptyBorder(-12, -12, -12, -12));
266
267                 buttonPanel.add(new JButton(swingInterface.getDeleteProjectAction(project)));
268                 buttonPanel.add(new JButton(swingInterface.getCloneProjectAction(project)));
269
270                 return buttonPanel;
271         }
272
273         /**
274          * Updates the project from changes in the text fields.
275          * 
276          * @param document
277          *            The document that was changed
278          */
279         private void textFieldsUpdated(Document document) {
280                 if (nameTextField.getDocument() == document) {
281                         project.setName(nameTextField.getText());
282                 } else if (descriptionTextField.getDocument() == document) {
283                         project.setDescription(descriptionTextField.getText());
284                 }
285         }
286
287         //
288         // PRIVATE ACTIONS
289         //
290
291         /**
292          * Lets the user select a new base path and repopulates the file list.
293          */
294         void changeBasePath() {
295                 JFileChooser fileChooser = new JFileChooser(project.getBasePath());
296                 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
297                 fileChooser.setApproveButtonText(I18n.get("projectPanel.button.approve.name"));
298                 int chooseAction = fileChooser.showOpenDialog(this);
299                 if (chooseAction == JFileChooser.APPROVE_OPTION) {
300                         String newBasePath = fileChooser.getSelectedFile().getPath();
301                         basePathTextField.setText(newBasePath);
302                         project.setBasePath(newBasePath);
303                 }
304         }
305
306         /**
307          * Pops up the file manager and lets the user edit the parameters for the
308          * physical and virtual files.
309          */
310         private void editFiles() {
311                 FileManager fileManager = new FileManager(swingInterface, project);
312                 fileManager.setVisible(true);
313         }
314
315         //
316         // INTERFACE I18nable
317         //
318
319         /**
320          * {@inheritDoc}
321          */
322         public void updateI18n() {
323                 nameLabel.updateI18n();
324                 descriptionLabel.updateI18n();
325                 basePathLabel.updateI18n();
326                 changeBasePathAction.updateI18n();
327                 editFilesAction.updateI18n();
328         }
329
330         //
331         // INTERFACE DocumentListener
332         //
333
334         /**
335          * {@inheritDoc}
336          */
337         public void changedUpdate(DocumentEvent documentEvent) {
338                 textFieldsUpdated(documentEvent.getDocument());
339         }
340
341         /**
342          * {@inheritDoc}
343          */
344         public void insertUpdate(DocumentEvent documentEvent) {
345                 textFieldsUpdated(documentEvent.getDocument());
346         }
347
348         /**
349          * {@inheritDoc}
350          */
351         public void removeUpdate(DocumentEvent documentEvent) {
352                 textFieldsUpdated(documentEvent.getDocument());
353         }
354
355 }