enhance javadoc
[jSite2.git] / src / net / pterodactylus / jsite / gui / SwingInterface.java
1 /*
2  * jSite2 - SwingInterface.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.event.ActionEvent;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Properties;
31
32 import javax.swing.JOptionPane;
33
34 import net.pterodactylus.jsite.core.Core;
35 import net.pterodactylus.jsite.core.CoreListener;
36 import net.pterodactylus.jsite.core.Node;
37 import net.pterodactylus.jsite.i18n.I18n;
38 import net.pterodactylus.jsite.i18n.gui.I18nAction;
39 import net.pterodactylus.util.io.Closer;
40
41 /**
42  * The Swing user interface.
43  * 
44  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
45  * @version $Id$
46  */
47 public class SwingInterface implements CoreListener {
48
49         /** The application core. */
50         private final Core core;
51
52         /** The configuration directory. */
53         private final String configDirectory;
54
55         /** The main window. */
56         private MainWindow mainWindow;
57
58         /** The “configure” action. */
59         private I18nAction configureAction;
60
61         /** The “import config” action. */
62         private I18nAction importConfigAction;
63
64         /** The “quit” action. */
65         private I18nAction quitAction;
66
67         /** The “manage nodes” action. */
68         private I18nAction manageNodesAction;
69
70         /** The “connect to node” action. */
71         private I18nAction nodeConnectAction;
72
73         /** The “disconnect from node” action. */
74         private I18nAction nodeDisconnectAction;
75
76         /** The node manager dialog. */
77         private ManageNodesDialog manageNodesDialog;
78
79         /** All lanugage menu items. */
80         private List<I18nAction> languageActions = new ArrayList<I18nAction>();
81
82         /** The “about” action. */
83         private I18nAction helpAboutAction;
84
85         /** The “add project” action. */
86         private I18nAction addProjectAction;
87
88         /** The “about” dialog. */
89         private AboutDialog aboutDialog;
90
91         /** The configuration dialog. */
92         private ConfigurationDialog configurationDialog;
93
94         /** The list of all defined nodes. */
95         private List<Node> nodeList;
96
97         //
98         // CONFIGURATION
99         //
100
101         /** Whether to beautify the GUI. */
102         private boolean beautify;
103
104         /**
105          * Creates a new swing interface.
106          * 
107          * @param core
108          *            The core to operate on
109          * @param configDirectory
110          *            The directory the configuration is stored in
111          */
112         public SwingInterface(Core core, String configDirectory) {
113                 this.core = core;
114                 this.configDirectory = configDirectory;
115                 I18n.setLocale(Locale.ENGLISH);
116                 loadConfig();
117                 if (beautify) {
118                         System.setProperty("swing.aatext", "true");
119                         System.setProperty("swing.plaf.metal.controlFont", "Tahoma");
120                         System.setProperty("swing.plaf.metal.userFont", "Tahoma");
121                 }
122                 initActions();
123                 initDialogs();
124         }
125
126         //
127         // ACCESSORS
128         //
129
130         /**
131          * Returns the core that is controlled by the Swing interface.
132          * 
133          * @return The core
134          */
135         Core getCore() {
136                 return core;
137         }
138
139         /**
140          * Returns the main window of the Swing interface.
141          * 
142          * @return The main window
143          */
144         MainWindow getMainWindow() {
145                 return mainWindow;
146         }
147
148         /**
149          * Returns the “configure” action.
150          * 
151          * @return The “configure” action
152          */
153         I18nAction getConfigureAction() {
154                 return configureAction;
155         }
156
157         /**
158          * Returns the “import config” action.
159          * 
160          * @return The “import config” action
161          */
162         I18nAction getImportConfigAction() {
163                 return importConfigAction;
164         }
165
166         /**
167          * Returns the “quit” action.
168          * 
169          * @return The “quit” action
170          */
171         I18nAction getQuitAction() {
172                 return quitAction;
173         }
174
175         /**
176          * Returns the “manage nodes” action.
177          * 
178          * @return The “manage nodes” action
179          */
180         I18nAction getManageNodesAction() {
181                 return manageNodesAction;
182         }
183
184         /**
185          * Returns the “connect to node” action.
186          * 
187          * @return The “connect to node” action
188          */
189         I18nAction getNodeConnectAction() {
190                 return nodeConnectAction;
191         }
192
193         /**
194          * Returns the “disconnect from node” action.
195          * 
196          * @return The “disconnect from node” action
197          */
198         I18nAction getNodeDisconnectAction() {
199                 return nodeDisconnectAction;
200         }
201
202         /**
203          * Returns all language actions.
204          * 
205          * @return All language actions
206          */
207         List<I18nAction> getLanguageActions() {
208                 return languageActions;
209         }
210
211         /**
212          * Returns the “about” action.
213          * 
214          * @return The “about” action
215          */
216         I18nAction getHelpAboutAction() {
217                 return helpAboutAction;
218         }
219
220         /**
221          * Returns the “add project” action.
222          * 
223          * @return The “add project” action
224          */
225         I18nAction getAddProjectAction() {
226                 return addProjectAction;
227         }
228
229         //
230         // ACTIONS
231         //
232
233         //
234         // SERVICE METHODS
235         //
236
237         /**
238          * Starts the interface.
239          */
240         public void start() {
241                 mainWindow = new MainWindow(this);
242         }
243
244         //
245         // PRIVATE METHODS
246         //
247
248         /**
249          * Loads the configuration of the interface.
250          */
251         private void loadConfig() {
252                 /* initialize default stuff. */
253                 beautify = false;
254                 /* now read config. */
255                 System.out.println("configDirectory: “" + configDirectory + "”");
256                 File configFile = new File(configDirectory, "swing-interface.properties");
257                 if (!configFile.exists() || !configFile.canRead() || !configFile.isFile()) {
258                         System.err.println("could not find “" + configFile.getAbsolutePath() + "”!");
259                         return;
260                 }
261                 Properties configProperties = new Properties();
262                 FileInputStream configInputStream = null;
263                 try {
264                         configInputStream = new FileInputStream(configFile);
265                         configProperties.load(configInputStream);
266                 } catch (IOException ioe1) {
267                         System.err.println("could not load config, " + ioe1.getMessage());
268                 } finally {
269                         Closer.close(configInputStream);
270                 }
271                 if (configProperties.containsKey("beautify")) {
272                         beautify = Boolean.valueOf(configProperties.getProperty("beautify"));
273                 }
274         }
275
276         /**
277          * Saves the configuration.
278          */
279         private void saveConfig() {
280                 File configDirectory = new File(this.configDirectory);
281                 if (!configDirectory.exists()) {
282                         if (!configDirectory.mkdirs()) {
283                                 System.err.println("could not create “" + this.configDirectory + "”!");
284                                 return;
285                         }
286                 }
287                 if (!configDirectory.exists() || !configDirectory.isDirectory() || !configDirectory.canWrite()) {
288                         System.err.println("can not access “" + this.configDirectory + "”!");
289                         return;
290                 }
291                 File configFile = new File(configDirectory, "swing-interface.properties");
292                 Properties configProperties = new Properties();
293                 configProperties.setProperty("beautify", String.valueOf(beautify));
294                 FileOutputStream configOutputStream = null;
295                 try {
296                         configOutputStream = new FileOutputStream(configFile);
297                         configProperties.store(configOutputStream, "configuration of swing interface");
298                 } catch (IOException ioe1) {
299                         System.err.println("could not save config, " + ioe1.getMessage());
300                 } finally {
301                         Closer.close(configOutputStream);
302                 }
303         }
304
305         /**
306          * Initializes all actions.
307          */
308         private void initActions() {
309                 configureAction = new I18nAction("mainWindow.menu.jSite.configure") {
310
311                         /**
312                          * {@inheritDoc}
313                          */
314                         @SuppressWarnings("synthetic-access")
315                         public void actionPerformed(ActionEvent actionEvent) {
316                                 configure();
317                         }
318                 };
319                 importConfigAction = new I18nAction("mainWindow.menu.jSite.importConfig") {
320
321                         /**
322                          * {@inheritDoc}
323                          */
324                         @SuppressWarnings("synthetic-access")
325                         public void actionPerformed(ActionEvent actionEvent) {
326                                 importConfig();
327                         }
328                 };
329                 quitAction = new I18nAction("mainWindow.menu.jSite.quit") {
330
331                         /**
332                          * {@inheritDoc}
333                          */
334                         @SuppressWarnings("synthetic-access")
335                         public void actionPerformed(ActionEvent actionEvent) {
336                                 quit();
337                         }
338                 };
339                 manageNodesAction = new I18nAction("mainWindow.menu.node.item.manageNodes") {
340
341                         /**
342                          * {@inheritDoc}
343                          */
344                         @SuppressWarnings("synthetic-access")
345                         public void actionPerformed(ActionEvent actionEvent) {
346                                 manageNodes();
347                         }
348                 };
349                 nodeConnectAction = new I18nAction("mainWindow.menu.node.item.connect", false) {
350
351                         @SuppressWarnings("synthetic-access")
352                         public void actionPerformed(ActionEvent actionEvent) {
353                                 nodeConnect();
354                         }
355
356                 };
357                 nodeDisconnectAction = new I18nAction("mainWindow.menu.node.item.disconnect", false) {
358
359                         /**
360                          * {@inheritDoc}
361                          */
362                         @SuppressWarnings("synthetic-access")
363                         public void actionPerformed(ActionEvent e) {
364                                 nodeDisconnect();
365                         }
366                 };
367                 List<Locale> availableLanguages = I18n.findAvailableLanguages();
368                 for (final Locale locale: availableLanguages) {
369                         I18nAction languageAction = new I18nAction("general.language." + locale.getLanguage()) {
370
371                                 @SuppressWarnings("synthetic-access")
372                                 public void actionPerformed(ActionEvent e) {
373                                         changeLanguage(locale, this);
374                                 }
375
376                         };
377                         if (I18n.getLocale().getLanguage().equals(locale.getLanguage())) {
378                                 languageAction.setEnabled(false);
379                         }
380                         languageActions.add(languageAction);
381                 }
382                 helpAboutAction = new I18nAction("mainWindow.menu.help.item.about") {
383
384                         /**
385                          * {@inheritDoc}
386                          */
387                         @SuppressWarnings("synthetic-access")
388                         public void actionPerformed(ActionEvent actionEvent) {
389                                 helpAbout();
390                         }
391                 };
392                 addProjectAction = new I18nAction("mainWindow.button.addProject") {
393
394                         /**
395                          * {@inheritDoc}
396                          */
397                         @SuppressWarnings("synthetic-access")
398                         public void actionPerformed(ActionEvent actionEvent) {
399                                 addProject();
400                         }
401                 };
402         }
403
404         /**
405          * Initializes all child dialogs.
406          */
407         private void initDialogs() {
408                 manageNodesDialog = new ManageNodesDialog(this);
409                 aboutDialog = new AboutDialog(this);
410                 configurationDialog = new ConfigurationDialog(this);
411         }
412
413         //
414         // PRIVATE ACTIONS
415         //
416
417         /**
418          * Shows the configuration dialog.
419          */
420         private void configure() {
421                 configurationDialog.setBeautify(beautify);
422                 configurationDialog.setVisible(true);
423                 if (!configurationDialog.wasCancelled()) {
424                         beautify = configurationDialog.getBeautify();
425                         saveConfig();
426                 }
427         }
428
429         /**
430          * Imports old jSite configuration.
431          */
432         private void importConfig() {
433         }
434
435         /**
436          * Quits jSite.
437          */
438         private void quit() {
439                 saveConfig();
440                 System.exit(0);
441         }
442
443         /**
444          * Pops up the “manage nodes” dialog.
445          */
446         private void manageNodes() {
447                 manageNodesDialog.setNodeList(nodeList);
448                 manageNodesDialog.setVisible(true);
449                 nodeList = manageNodesDialog.getNodeList();
450         }
451
452         /**
453          * Connects to the node.
454          */
455         private void nodeConnect() {
456         }
457
458         /**
459          * Disconnects from the node.
460          */
461         private void nodeDisconnect() {
462         }
463
464         /**
465          * Changes the language of the interface. This method also disables the
466          * action for the newly set language and enables all others.
467          * 
468          * @param newLocale
469          *            The new language
470          * @param languageAction
471          *            The action that triggered the change
472          */
473         private void changeLanguage(Locale newLocale, I18nAction languageAction) {
474                 for (I18nAction i18nAction: languageActions) {
475                         i18nAction.setEnabled(i18nAction != languageAction);
476                 }
477                 I18n.setLocale(newLocale);
478         }
479
480         /**
481          * Shows the “about” dialog.
482          */
483         private void helpAbout() {
484                 aboutDialog.setVisible(true);
485         }
486
487         /**
488          * Adds a project.
489          */
490         private void addProject() {
491         }
492
493         //
494         // INTERFACE CoreListener
495         //
496
497         /**
498          * {@inheritDoc}
499          */
500         public void loadingProjectsFailed(String directory) {
501                 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.projectLoadingFailed.message", directory), I18n.get("mainWindow.error.projectLoadingFailed.title"), JOptionPane.ERROR_MESSAGE);
502         }
503
504         /**
505          * {@inheritDoc}
506          */
507         public void coreLoaded() {
508                 this.nodeList = core.getNodes();
509                 manageNodesDialog.setNodeList(nodeList);
510                 mainWindow.setVisible(true);
511                 mainWindow.setStatusBarText("Core loaded.");
512         }
513
514         /**
515          * {@inheritDoc}
516          */
517         public void nodeConnected(Node node) {
518         }
519
520         /**
521          * {@inheritDoc}
522          */
523         public void nodeConnecting(Node node) {
524         }
525
526         /**
527          * {@inheritDoc}
528          */
529         public void nodeDisconnected(Node node) {
530         }
531
532 }