2 * jSite2 - SwingInterface.java -
3 * Copyright © 2008 David Roden
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.
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.
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.
20 package net.pterodactylus.jsite.gui;
22 import java.awt.event.ActionEvent;
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;
32 import javax.swing.JOptionPane;
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.core.Project;
38 import net.pterodactylus.jsite.i18n.I18n;
39 import net.pterodactylus.jsite.i18n.gui.I18nAction;
40 import net.pterodactylus.util.io.Closer;
43 * The Swing user interface.
45 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
48 public class SwingInterface implements CoreListener {
50 /** The application core. */
51 private final Core core;
53 /** The configuration directory. */
54 private final String configDirectory;
56 /** The main window. */
57 private MainWindow mainWindow;
59 /** The “configure” action. */
60 private I18nAction configureAction;
62 /** The “import config” action. */
63 private I18nAction importConfigAction;
65 /** The “quit” action. */
66 private I18nAction quitAction;
68 /** The “manage nodes” action. */
69 private I18nAction manageNodesAction;
71 /** The “connect to node” action. */
72 private I18nAction nodeConnectAction;
74 /** The “disconnect from node” action. */
75 private I18nAction nodeDisconnectAction;
77 /** The node manager dialog. */
78 private ManageNodesDialog manageNodesDialog;
80 /** All lanugage menu items. */
81 private List<I18nAction> languageActions = new ArrayList<I18nAction>();
83 /** The “about” action. */
84 private I18nAction helpAboutAction;
86 /** The “add project” action. */
87 private I18nAction addProjectAction;
89 /** The “clone project” action. */
90 private I18nAction cloneProjectAction;
92 /** The “delete project” action. */
93 private I18nAction deleteProjectAction;
95 /** The “about” dialog. */
96 private AboutDialog aboutDialog;
98 /** The configuration dialog. */
99 private ConfigurationDialog configurationDialog;
101 /** The list of all defined nodes. */
102 private List<Node> nodeList;
108 /** Whether to beautify the GUI. */
109 private boolean beautify;
112 * Creates a new swing interface.
115 * The core to operate on
116 * @param configDirectory
117 * The directory the configuration is stored in
119 public SwingInterface(Core core, String configDirectory) {
121 this.configDirectory = configDirectory;
122 I18n.setLocale(Locale.ENGLISH);
125 System.setProperty("swing.aatext", "true");
126 System.setProperty("swing.plaf.metal.controlFont", "Tahoma");
127 System.setProperty("swing.plaf.metal.userFont", "Tahoma");
138 * Returns the core that is controlled by the Swing interface.
147 * Returns the main window of the Swing interface.
149 * @return The main window
151 MainWindow getMainWindow() {
156 * Returns the “configure” action.
158 * @return The “configure” action
160 I18nAction getConfigureAction() {
161 return configureAction;
165 * Returns the “import config” action.
167 * @return The “import config” action
169 I18nAction getImportConfigAction() {
170 return importConfigAction;
174 * Returns the “quit” action.
176 * @return The “quit” action
178 I18nAction getQuitAction() {
183 * Returns the “manage nodes” action.
185 * @return The “manage nodes” action
187 I18nAction getManageNodesAction() {
188 return manageNodesAction;
192 * Returns the “connect to node” action.
194 * @return The “connect to node” action
196 I18nAction getNodeConnectAction() {
197 return nodeConnectAction;
201 * Returns the “disconnect from node” action.
203 * @return The “disconnect from node” action
205 I18nAction getNodeDisconnectAction() {
206 return nodeDisconnectAction;
210 * Returns all language actions.
212 * @return All language actions
214 List<I18nAction> getLanguageActions() {
215 return languageActions;
219 * Returns the “about” action.
221 * @return The “about” action
223 I18nAction getHelpAboutAction() {
224 return helpAboutAction;
228 * Returns the “add project” action.
230 * @return The “add project” action
232 I18nAction getAddProjectAction() {
233 return addProjectAction;
237 * Returns the “clone project” action.
239 * @return The “clone project” action
241 I18nAction getCloneProjectAction() {
242 return cloneProjectAction;
246 * Returns the “delete project” action.
248 * @return The “delete project” action
250 I18nAction getDeleteProjectAction() {
251 return deleteProjectAction;
263 * Starts the interface.
265 public void start() {
266 mainWindow = new MainWindow(this);
274 * Loads the configuration of the interface.
276 private void loadConfig() {
277 /* initialize default stuff. */
279 /* now read config. */
280 File configFile = new File(configDirectory, "swing-interface.properties");
281 if (!configFile.exists() || !configFile.canRead() || !configFile.isFile()) {
282 System.err.println("could not find “" + configFile.getAbsolutePath() + "”!");
285 Properties configProperties = new Properties();
286 FileInputStream configInputStream = null;
288 configInputStream = new FileInputStream(configFile);
289 configProperties.load(configInputStream);
290 } catch (IOException ioe1) {
291 System.err.println("could not load config, " + ioe1.getMessage());
293 Closer.close(configInputStream);
295 if (configProperties.containsKey("beautify")) {
296 beautify = Boolean.valueOf(configProperties.getProperty("beautify"));
301 * Saves the configuration.
303 private void saveConfig() {
304 File configDirectory = new File(this.configDirectory);
305 if (!configDirectory.exists()) {
306 if (!configDirectory.mkdirs()) {
307 System.err.println("could not create “" + this.configDirectory + "”!");
311 if (!configDirectory.exists() || !configDirectory.isDirectory() || !configDirectory.canWrite()) {
312 System.err.println("can not access “" + this.configDirectory + "”!");
315 File configFile = new File(configDirectory, "swing-interface.properties");
316 Properties configProperties = new Properties();
317 configProperties.setProperty("beautify", String.valueOf(beautify));
318 FileOutputStream configOutputStream = null;
320 configOutputStream = new FileOutputStream(configFile);
321 configProperties.store(configOutputStream, "configuration of swing interface");
322 } catch (IOException ioe1) {
323 System.err.println("could not save config, " + ioe1.getMessage());
325 Closer.close(configOutputStream);
330 * Initializes all actions.
332 private void initActions() {
333 configureAction = new I18nAction("mainWindow.menu.jSite.configure") {
338 @SuppressWarnings("synthetic-access")
339 public void actionPerformed(ActionEvent actionEvent) {
343 importConfigAction = new I18nAction("mainWindow.menu.jSite.importConfig") {
348 @SuppressWarnings("synthetic-access")
349 public void actionPerformed(ActionEvent actionEvent) {
353 quitAction = new I18nAction("mainWindow.menu.jSite.quit") {
358 @SuppressWarnings("synthetic-access")
359 public void actionPerformed(ActionEvent actionEvent) {
363 manageNodesAction = new I18nAction("mainWindow.menu.node.item.manageNodes") {
368 @SuppressWarnings("synthetic-access")
369 public void actionPerformed(ActionEvent actionEvent) {
373 nodeConnectAction = new I18nAction("mainWindow.menu.node.item.connect", false) {
375 @SuppressWarnings("synthetic-access")
376 public void actionPerformed(ActionEvent actionEvent) {
381 nodeDisconnectAction = new I18nAction("mainWindow.menu.node.item.disconnect", false) {
386 @SuppressWarnings("synthetic-access")
387 public void actionPerformed(ActionEvent e) {
391 List<Locale> availableLanguages = I18n.findAvailableLanguages();
392 for (final Locale locale: availableLanguages) {
393 I18nAction languageAction = new I18nAction("general.language." + locale.getLanguage()) {
395 @SuppressWarnings("synthetic-access")
396 public void actionPerformed(ActionEvent e) {
397 changeLanguage(locale, this);
401 if (I18n.getLocale().getLanguage().equals(locale.getLanguage())) {
402 languageAction.setEnabled(false);
404 languageActions.add(languageAction);
406 helpAboutAction = new I18nAction("mainWindow.menu.help.item.about") {
411 @SuppressWarnings("synthetic-access")
412 public void actionPerformed(ActionEvent actionEvent) {
416 addProjectAction = new I18nAction("mainWindow.button.addProject") {
421 @SuppressWarnings("synthetic-access")
422 public void actionPerformed(ActionEvent actionEvent) {
426 cloneProjectAction = new I18nAction("mainWindow.button.cloneProject") {
431 @SuppressWarnings("synthetic-access")
432 public void actionPerformed(ActionEvent actionEvent) {
436 deleteProjectAction = new I18nAction("mainWindow.button.deleteProject") {
441 @SuppressWarnings("synthetic-access")
442 public void actionPerformed(ActionEvent actionEvent) {
449 * Initializes all child dialogs.
451 private void initDialogs() {
452 manageNodesDialog = new ManageNodesDialog(this);
453 aboutDialog = new AboutDialog(this);
454 configurationDialog = new ConfigurationDialog(this);
462 * Shows the configuration dialog.
464 private void configure() {
465 configurationDialog.setBeautify(beautify);
466 configurationDialog.setVisible(true);
467 if (!configurationDialog.wasCancelled()) {
468 beautify = configurationDialog.getBeautify();
474 * Imports old jSite configuration.
476 private void importConfig() {
482 private void quit() {
488 * Pops up the “manage nodes” dialog.
490 private void manageNodes() {
491 manageNodesDialog.setNodeList(nodeList);
492 manageNodesDialog.setVisible(true);
493 nodeList = manageNodesDialog.getNodeList();
497 * Connects to the node.
499 private void nodeConnect() {
503 * Disconnects from the node.
505 private void nodeDisconnect() {
509 * Changes the language of the interface. This method also disables the
510 * action for the newly set language and enables all others.
514 * @param languageAction
515 * The action that triggered the change
517 private void changeLanguage(Locale newLocale, I18nAction languageAction) {
518 for (I18nAction i18nAction: languageActions) {
519 i18nAction.setEnabled(i18nAction != languageAction);
521 I18n.setLocale(newLocale);
525 * Shows the “about” dialog.
527 private void helpAbout() {
528 aboutDialog.setVisible(true);
534 private void addProject() {
535 Project project = new Project();
536 project.setName("New Project");
537 project.setDescription("");
543 private void cloneProject() {
549 private void deleteProject() {
553 // INTERFACE CoreListener
559 public void loadingProjectsFailed(String directory) {
560 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.projectLoadingFailed.message", directory), I18n.get("mainWindow.error.projectLoadingFailed.title"), JOptionPane.ERROR_MESSAGE);
566 public void coreLoaded() {
567 this.nodeList = core.getNodes();
568 manageNodesDialog.setNodeList(nodeList);
569 mainWindow.setVisible(true);
570 mainWindow.setStatusBarText("Core loaded.");
576 public void nodeConnected(Node node) {
582 public void nodeConnecting(Node node) {
588 public void nodeDisconnected(Node node) {