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;
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
26 import java.io.FileInputStream;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.net.UnknownHostException;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.Date;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Locale;
37 import java.util.Properties;
38 import java.util.concurrent.Executor;
39 import java.util.concurrent.Executors;
40 import java.util.logging.Level;
41 import java.util.logging.LogRecord;
42 import java.util.logging.Logger;
44 import javax.swing.JOptionPane;
45 import javax.swing.UIManager;
46 import javax.swing.UnsupportedLookAndFeelException;
48 import net.pterodactylus.jsite.core.Core;
49 import net.pterodactylus.jsite.core.CoreListener;
50 import net.pterodactylus.jsite.core.JSiteException;
51 import net.pterodactylus.jsite.core.Node;
52 import net.pterodactylus.jsite.i18n.I18n;
53 import net.pterodactylus.jsite.i18n.gui.I18nAction;
54 import net.pterodactylus.jsite.project.Project;
55 import net.pterodactylus.util.image.IconLoader;
56 import net.pterodactylus.util.io.Closer;
57 import net.pterodactylus.util.logging.Logging;
58 import net.pterodactylus.util.logging.LoggingListener;
61 * The Swing user interface.
63 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
65 public class SwingInterface implements CoreListener, LoggingListener, PropertyChangeListener {
68 private static final Logger logger = Logging.getLogger(SwingInterface.class.getName());
70 /** The application core. */
71 private final Core core;
73 /** The configuration directory. */
74 private final String configDirectory;
76 /** The main window. */
77 private MainWindow mainWindow;
80 private Executor threadPool = Executors.newCachedThreadPool();
82 /** The logger window. */
83 private LogWindow logWindow;
85 /** The “configure” action. */
86 private I18nAction configureAction;
88 /** The “import config” action. */
89 private I18nAction importConfigAction;
91 /** The “quit” action. */
92 private I18nAction quitAction;
94 /** The “add node” action. */
95 private I18nAction addNodeAction;
97 /** All node menu items. */
98 private Map<Node, I18nAction> nodeConnectActions = Collections.synchronizedMap(new HashMap<Node, I18nAction>());
100 /** All node disconnect actions. */
101 private Map<Node, I18nAction> nodeDisconnectActions = Collections.synchronizedMap(new HashMap<Node, I18nAction>());
103 /** All node edit actions. */
104 private Map<Node, I18nAction> nodeEditActions = Collections.synchronizedMap(new HashMap<Node, I18nAction>());
106 /** All node removal actions. */
107 private Map<Node, I18nAction> nodeDeleteActions = Collections.synchronizedMap(new HashMap<Node, I18nAction>());
109 /** All lanugage menu items. */
110 private List<I18nAction> languageActions = new ArrayList<I18nAction>();
112 /** The “about” action. */
113 private I18nAction helpAboutAction;
115 /** The “add project” action. */
116 private I18nAction addProjectAction;
118 /** The “clone project” actions. */
119 private Map<Project, I18nAction> cloneProjectActions = new HashMap<Project, I18nAction>();
121 /** The “delete project” actions. */
122 private Map<Project, I18nAction> deleteProjectActions = new HashMap<Project, I18nAction>();
124 /** The “about” dialog. */
125 private AboutDialog aboutDialog;
127 /** The configuration dialog. */
128 private ConfigurationDialog configurationDialog;
130 /** The node editor dialog. */
131 private AddNodeDialog addNodeDialog;
133 /** The list of all defined nodes. */
134 private List<Node> nodeList = Collections.synchronizedList(new ArrayList<Node>());
136 /** The list of all projects. */
137 private List<Project> projectList = Collections.synchronizedList(new ArrayList<Project>());
143 /** The advanced mode. */
144 private boolean advancedMode;
146 /** Whether to antialias the GUI. */
147 private boolean antialias;
149 /** The control font. */
150 private String controlFont;
152 /** The user font. */
153 private String userFont;
155 /** The class name of the look and feel. */
156 private String lookAndFeel;
158 /** X coordinate of the main window. */
159 private int mainWindowX = -1;
161 /** Y coordinate of the main window. */
162 private int mainWindowY = -1;
164 /** Width of the main window. */
165 private int mainWindowWidth = -1;
167 /** Height of the main window. */
168 private int mainWindowHeight = -1;
171 * Creates a new swing interface.
174 * The core to operate on
175 * @param configDirectory
176 * The directory the configuration is stored in
178 public SwingInterface(Core core, String configDirectory) {
180 this.configDirectory = configDirectory;
181 I18n.setLocale(Locale.ENGLISH);
183 if (lookAndFeel != null) {
185 UIManager.setLookAndFeel(lookAndFeel);
186 } catch (ClassNotFoundException cnfe1) {
187 logger.log(Level.WARNING, "could not load look and feel", cnfe1);
188 } catch (InstantiationException ie1) {
189 logger.log(Level.WARNING, "could not load look and feel", ie1);
190 } catch (IllegalAccessException iae1) {
191 logger.log(Level.WARNING, "could not load look and feel", iae1);
192 } catch (UnsupportedLookAndFeelException ulafe1) {
193 logger.log(Level.WARNING, "could not load look and feel", ulafe1);
197 System.setProperty("swing.aatext", "true");
199 if (controlFont != null) {
200 System.setProperty("swing.plaf.metal.controlFont", controlFont);
202 if (userFont != null) {
203 System.setProperty("swing.plaf.metal.userFont", userFont);
207 mainWindow = new MainWindow(this);
208 mainWindow.setAdvancedMode(advancedMode);
209 if ((mainWindowX != -1) && (mainWindowY != -1) && (mainWindowWidth != -1) && (mainWindowHeight != -1)) {
210 mainWindow.setLocation(mainWindowX, mainWindowY);
211 mainWindow.setSize(mainWindowWidth, mainWindowHeight);
213 logWindow = new LogWindow();
221 * Returns the core that is controlled by the Swing interface.
230 * Returns the main window of the Swing interface.
232 * @return The main window
234 MainWindow getMainWindow() {
239 * Returns whether the advanced mode is activated.
241 * @return <code>true</code> if the advanced mode is activated,
242 * <code>false</code> if the simple mode is activated
244 boolean isAdvancedMode() {
249 * Returns the “configure” action.
251 * @return The “configure” action
253 I18nAction getConfigureAction() {
254 return configureAction;
258 * Returns the “import config” action.
260 * @return The “import config” action
262 I18nAction getImportConfigAction() {
263 return importConfigAction;
267 * Returns the “quit” action.
269 * @return The “quit” action
271 I18nAction getQuitAction() {
276 * Returns the “add node” action.
278 * @return The “add node” action
280 I18nAction getAddNodeAction() {
281 return addNodeAction;
285 * Returns the “connect to node” action for the given node.
288 * The node go get the “connect” action for
289 * @return The “connect to node” action
291 I18nAction getNodeConnectAction(Node node) {
292 return nodeConnectActions.get(node);
296 * Returns the “disconnect from node” action for the given node.
299 * The node go get the “disconnect” action for
300 * @return The “disconnect from node” action
302 I18nAction getNodeDisconnectAction(Node node) {
303 return nodeDisconnectActions.get(node);
307 * Returns the “edit node” action for the given node.
311 * @return The “edit node” action
313 I18nAction getNodeEditAction(Node node) {
314 return nodeEditActions.get(node);
318 * Returns the “delete node” action for the given node.
322 * @return The “delete node” action
324 I18nAction getNodeDeleteAction(Node node) {
325 return nodeDeleteActions.get(node);
329 * Returns all language actions.
331 * @return All language actions
333 List<I18nAction> getLanguageActions() {
334 return languageActions;
338 * Returns the “about” action.
340 * @return The “about” action
342 I18nAction getHelpAboutAction() {
343 return helpAboutAction;
347 * Returns the “add project” action.
349 * @return The “add project” action
351 I18nAction getAddProjectAction() {
352 return addProjectAction;
356 * Returns the “clone project” action for the given project.
359 * The project to get the “clone project” action for
360 * @return The “clone project” action
362 I18nAction getCloneProjectAction(Project project) {
363 return cloneProjectActions.get(project);
367 * Returns the “delete project” action for the given project.
370 * The project to get the “delete project” action for
371 * @return The “delete project” action
373 I18nAction getDeleteProjectAction(Project project) {
374 return deleteProjectActions.get(project);
378 * Returns all currently configured nodes.
380 * @return All configured nodes
382 List<Node> getNodes() {
387 * Returns a list of all projects.
389 * @return All projects
391 List<Project> getProjects() {
396 * Returns the thread pool used for off-thread processes.
398 * @return The thread pool
400 Executor getThreadPool() {
417 * Loads the configuration of the interface.
419 private void loadConfig() {
420 /* initialize default stuff. */
422 /* now read config. */
423 File configFile = new File(configDirectory, "swing-interface.properties");
424 if (!configFile.exists() || !configFile.canRead() || !configFile.isFile()) {
425 System.err.println("could not find “" + configFile.getAbsolutePath() + "”!");
428 Properties configProperties = new Properties();
429 FileInputStream configInputStream = null;
431 configInputStream = new FileInputStream(configFile);
432 configProperties.load(configInputStream);
433 } catch (IOException ioe1) {
434 System.err.println("could not load config, " + ioe1.getMessage());
436 Closer.close(configInputStream);
438 if (configProperties.containsKey("advancedMode")) {
439 advancedMode = Boolean.valueOf(configProperties.getProperty("advancedMode"));
441 if (configProperties.containsKey("antialias")) {
442 antialias = Boolean.valueOf(configProperties.getProperty("antialias"));
444 if (configProperties.containsKey("controlFont")) {
445 controlFont = configProperties.getProperty("controlFont");
447 if (configProperties.containsKey("userFont")) {
448 userFont = configProperties.getProperty("userFont");
450 if (configProperties.containsKey("lookAndFeel")) {
451 lookAndFeel = configProperties.getProperty("lookAndFeel");
453 if (configProperties.containsKey("language")) {
454 I18n.setLocale(new Locale(configProperties.getProperty("language")));
456 if (configProperties.containsKey("mainWindowX")) {
457 mainWindowX = Integer.valueOf(configProperties.getProperty("mainWindowX"));
459 if (configProperties.containsKey("mainWindowY")) {
460 mainWindowY = Integer.valueOf(configProperties.getProperty("mainWindowY"));
462 if (configProperties.containsKey("mainWindowWidth")) {
463 mainWindowWidth = Integer.valueOf(configProperties.getProperty("mainWindowWidth"));
465 if (configProperties.containsKey("mainWindowHeight")) {
466 mainWindowHeight = Integer.valueOf(configProperties.getProperty("mainWindowHeight"));
471 * Saves the configuration.
473 private void saveConfig() {
474 File configDirectory = new File(this.configDirectory);
475 if (!configDirectory.exists()) {
476 if (!configDirectory.mkdirs()) {
477 System.err.println("could not create “" + this.configDirectory + "”!");
481 if (!configDirectory.exists() || !configDirectory.isDirectory() || !configDirectory.canWrite()) {
482 System.err.println("can not access “" + this.configDirectory + "”!");
485 File configFile = new File(configDirectory, "swing-interface.properties");
486 Properties configProperties = new Properties();
487 configProperties.setProperty("advancedMode", String.valueOf(advancedMode));
488 configProperties.setProperty("antialias", String.valueOf(antialias));
489 if (controlFont != null) {
490 configProperties.setProperty("controlFont", controlFont);
492 if (userFont != null) {
493 configProperties.setProperty("userFont", userFont);
495 if (lookAndFeel != null) {
496 configProperties.setProperty("lookAndFeel", lookAndFeel);
498 configProperties.setProperty("language", I18n.getLocale().getLanguage());
499 configProperties.setProperty("mainWindowX", String.valueOf(mainWindowX));
500 configProperties.setProperty("mainWindowY", String.valueOf(mainWindowY));
501 configProperties.setProperty("mainWindowWidth", String.valueOf(mainWindowWidth));
502 configProperties.setProperty("mainWindowHeight", String.valueOf(mainWindowHeight));
503 FileOutputStream configOutputStream = null;
505 configOutputStream = new FileOutputStream(configFile);
506 configProperties.store(configOutputStream, "configuration of swing interface");
507 } catch (IOException ioe1) {
508 System.err.println("could not save config, " + ioe1.getMessage());
510 Closer.close(configOutputStream);
515 * Initializes all actions.
517 private void initActions() {
518 configureAction = new I18nAction("mainWindow.menu.jSite.configure", IconLoader.loadIcon("/preferences-system.png")) {
523 @SuppressWarnings("synthetic-access")
524 public void actionPerformed(ActionEvent actionEvent) {
528 importConfigAction = new I18nAction("mainWindow.menu.jSite.importConfig") {
533 @SuppressWarnings("synthetic-access")
534 public void actionPerformed(ActionEvent actionEvent) {
538 quitAction = new I18nAction("mainWindow.menu.jSite.quit", IconLoader.loadIcon("/system-log-out.png")) {
543 @SuppressWarnings("synthetic-access")
544 public void actionPerformed(ActionEvent actionEvent) {
548 List<Locale> availableLanguages = I18n.findAvailableLanguages();
549 for (final Locale locale: availableLanguages) {
550 I18nAction languageAction = new I18nAction("general.language." + locale.getLanguage()) {
552 @SuppressWarnings("synthetic-access")
553 public void actionPerformed(ActionEvent e) {
554 changeLanguage(locale, this);
558 if (I18n.getLocale().getLanguage().equals(locale.getLanguage())) {
559 languageAction.setEnabled(false);
561 languageActions.add(languageAction);
563 addNodeAction = new I18nAction("mainWindow.menu.node.item.addNode", IconLoader.loadIcon("/node-new.png")) {
568 @SuppressWarnings("synthetic-access")
569 public void actionPerformed(ActionEvent actionEvent) {
573 helpAboutAction = new I18nAction("mainWindow.menu.help.item.about") {
578 @SuppressWarnings("synthetic-access")
579 public void actionPerformed(ActionEvent actionEvent) {
583 addProjectAction = new I18nAction("mainWindow.button.addProject") {
588 @SuppressWarnings("synthetic-access")
589 public void actionPerformed(ActionEvent actionEvent) {
596 * Initializes all child dialogs.
598 private void initDialogs() {
599 aboutDialog = new AboutDialog(this);
600 configurationDialog = new ConfigurationDialog(this);
601 addNodeDialog = new AddNodeDialog(mainWindow);
609 * Shows the configuration dialog.
611 private void configure() {
612 configurationDialog.setAdvancedMode(advancedMode);
613 configurationDialog.setAntialias(antialias);
614 configurationDialog.setControlFont(controlFont);
615 configurationDialog.setUserFont(userFont);
616 configurationDialog.setLookAndFeel(lookAndFeel);
617 configurationDialog.setVisible(true);
618 if (!configurationDialog.wasCancelled()) {
619 advancedMode = configurationDialog.isAdvancedMode();
620 if (!advancedMode && (nodeList.size() > 1)) {
621 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.warning.multipleNodesNotAdvancedMode.message"), I18n.get("mainWindow.warning.multipleNodesNotAdvancedMode.title"), JOptionPane.WARNING_MESSAGE);
623 mainWindow.setAdvancedMode(advancedMode);
624 antialias = configurationDialog.isAntialias();
625 controlFont = configurationDialog.getControlFont();
626 userFont = configurationDialog.getUserFont();
627 lookAndFeel = configurationDialog.getLookAndFeel();
633 * Imports old jSite configuration.
635 private void importConfig() {
642 private void quit() {
645 mainWindowX = mainWindow.getX();
646 mainWindowY = mainWindow.getY();
647 mainWindowWidth = mainWindow.getWidth();
648 mainWindowHeight = mainWindow.getHeight();
656 private void addNode() {
657 addNodeDialog.setNodeName(I18n.get(nodeList.isEmpty() ? "general.defaultNode.name" : "general.newNode.name"));
658 addNodeDialog.setNodeHostname("localhost");
659 addNodeDialog.setNodePort(9481);
660 addNodeDialog.setVisible(true);
661 if (!addNodeDialog.wasCancelled()) {
662 Node newNode = new Node();
663 newNode.setName(addNodeDialog.getNodeName());
664 newNode.setHostname(addNodeDialog.getNodeHostname());
665 newNode.setPort(addNodeDialog.getNodePort());
667 core.addNode(newNode);
668 } catch (UnknownHostException e) {
669 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.hostnameUnresolvable.message"), I18n.get("mainWindow.error.hostnameUnresolvable.title"), JOptionPane.ERROR_MESSAGE);
675 * Edits the given node.
680 private void editNode(Node node) {
681 addNodeDialog.setNodeName(node.getName());
682 addNodeDialog.setNodeHostname(node.getHostname());
683 addNodeDialog.setNodePort(node.getPort());
684 addNodeDialog.setVisible(true);
685 if (!addNodeDialog.wasCancelled()) {
686 node.setName(addNodeDialog.getNodeName());
687 node.setHostname(addNodeDialog.getNodeHostname());
688 node.setPort(addNodeDialog.getNodePort());
693 * Deletes the given node.
698 private void deleteNode(Node node) {
699 int option = JOptionPane.showConfirmDialog(mainWindow, I18n.get("mainWindow.question.deleteNode.message", node.getName()), I18n.get("mainWindow.question.deleteNode.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
700 if (option == JOptionPane.OK_OPTION) {
701 core.removeNode(node);
706 * Connects to the node.
709 * The node to connect to
711 private void nodeConnect(final Node node) {
712 threadPool.execute(new Runnable() {
717 @SuppressWarnings("synthetic-access")
719 logger.log(Level.INFO, "connecting to node “" + node.getName() + "”…");
720 core.connectToNode(node);
726 * Disconnects from the node.
729 * The node to disconnect from
731 private void nodeDisconnect(Node node) {
732 logger.log(Level.INFO, "disconnecting from node “" + node.getName() + "”…");
733 core.disconnectFromNode(node);
737 * Changes the language of the interface. This method also disables the
738 * action for the newly set language and enables all others.
742 * @param languageAction
743 * The action that triggered the change
745 private void changeLanguage(Locale newLocale, I18nAction languageAction) {
746 for (I18nAction i18nAction: languageActions) {
747 i18nAction.setEnabled(i18nAction != languageAction);
749 I18n.setLocale(newLocale);
753 * Shows the “about” dialog.
755 private void helpAbout() {
756 aboutDialog.setVisible(true);
762 private void addProject() {
764 core.createProject();
765 } catch (JSiteException nne1) {
766 /* TODO - add i18n */
767 JOptionPane.showMessageDialog(mainWindow, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE);
768 } catch (IOException e) {
769 /* TODO - add i18n */
770 JOptionPane.showMessageDialog(mainWindow, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE);
778 * The project to clone
780 private void cloneProject(Project project) {
781 core.cloneProject(project);
788 * The project to delete
790 private void deleteProject(Project project) {
791 int choice = JOptionPane.showConfirmDialog(mainWindow, I18n.get("mainWindow.question.deleteProject.message", project.getName()), I18n.get("mainWindow.question.deleteProject.title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
792 if (choice == JOptionPane.NO_OPTION) {
795 core.removeProject(project);
799 // INTERFACE CoreListener
805 public void loadingProjectsDone(String directory) {
806 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.projectLoadingDone"));
807 for (Project project: core.getProjects()) {
808 projectAdded(project, false);
815 public void loadingProjectsFailed(String directory, Throwable throwable) {
816 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.projectLoadingFailed.message", directory), I18n.get("mainWindow.error.projectLoadingFailed.title"), JOptionPane.ERROR_MESSAGE);
822 public void savingProjectsDone(String directory) {
823 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.projectSavingDone"));
829 public void savingProjectsFailed(String directory, Throwable throwabled) {
836 public void projectAdded(Project project) {
837 project.setName(I18n.get("general.newProject.name"));
838 project.setDescription(I18n.get("general.newProject.description", new Date()));
839 projectAdded(project, true);
844 * @param switchToProject
846 private void projectAdded(final Project project, boolean switchToProject) {
847 cloneProjectActions.put(project, new I18nAction("mainWindow.button.cloneProject") {
852 @SuppressWarnings("synthetic-access")
853 public void actionPerformed(ActionEvent actionEvent) {
854 cloneProject(project);
857 deleteProjectActions.put(project, new I18nAction("mainWindow.button.deleteProject") {
862 @SuppressWarnings("synthetic-access")
863 public void actionPerformed(ActionEvent actionEvent) {
864 deleteProject(project);
867 projectList.add(project);
868 mainWindow.addProject(project, switchToProject);
874 public void projectCloned(Project clonedProject, Project projectClone) {
875 projectAdded(projectClone, true);
881 public void projectRemoved(Project project) {
882 mainWindow.removeProject(project);
883 cloneProjectActions.remove(project);
884 deleteProjectActions.remove(project);
890 public void loadingNodesDone(String directory) {
891 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.loadingNodesDone"));
897 public void loadingNodesFailed(String directory, Throwable throwable) {
904 public void savingNodesDone(String directory) {
905 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.savingNodesDone"));
911 public void savingNodesFailed(String directory, Throwable throwable) {
918 public void coreLoaded() {
919 mainWindow.setVisible(true);
920 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.coreLoaded"));
926 public void coreStopped() {
927 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.coreStopped"));
933 public void nodeAdded(final Node node) {
934 logger.log(Level.INFO, "node added: " + node);
936 node.addPropertyChangeListener(this);
937 logger.log(Level.FINE, "nodeList.size(): " + nodeList.size());
938 nodeConnectActions.put(node, new I18nAction("mainWindow.menu.node.item.connect") {
943 @SuppressWarnings("synthetic-access")
944 public void actionPerformed(ActionEvent e) {
948 nodeDisconnectActions.put(node, new I18nAction("mainWindow.menu.node.item.disconnect") {
953 @SuppressWarnings("synthetic-access")
954 public void actionPerformed(ActionEvent e) {
955 nodeDisconnect(node);
958 nodeDisconnectActions.get(node).setEnabled(false);
959 nodeEditActions.put(node, new I18nAction("mainWindow.menu.node.item.edit") {
964 @SuppressWarnings("synthetic-access")
965 public void actionPerformed(ActionEvent actionEvent) {
969 nodeDeleteActions.put(node, new I18nAction("mainWindow.menu.node.item.remove") {
974 @SuppressWarnings("synthetic-access")
975 public void actionPerformed(ActionEvent actionEvent) {
979 mainWindow.addNode(node);
985 public void nodeRemoved(Node node) {
986 logger.log(Level.INFO, "node removed: " + node);
987 nodeList.remove(node);
988 node.removePropertyChangeListener(this);
989 nodeConnectActions.remove(node);
990 nodeDisconnectActions.remove(node);
991 nodeEditActions.remove(node);
992 nodeDeleteActions.remove(node);
993 mainWindow.removeNode(node);
999 public void nodeConnecting(Node node) {
1000 nodeConnectActions.get(node).setEnabled(false);
1001 nodeEditActions.get(node).setEnabled(false);
1002 nodeDeleteActions.get(node).setEnabled(false);
1003 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectingToNode", node.getName(), node.getHostname(), node.getPort()));
1009 public void nodeConnected(Node node) {
1010 nodeDisconnectActions.get(node).setEnabled(true);
1011 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectedToNode", node.getName(), node.getHostname(), node.getPort()));
1012 mainWindow.setOnline(node);
1018 public void nodeConnectionFailed(Node node, Throwable cause) {
1019 nodeConnectActions.get(node).setEnabled(true);
1020 nodeEditActions.get(node).setEnabled(true);
1021 nodeDeleteActions.get(node).setEnabled(true);
1022 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectionToNodeFailed", node.getName(), node.getHostname(), node.getPort(), (cause != null) ? cause.getMessage() : "no reason given"));
1023 mainWindow.setError(node);
1024 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.nodeConnectionFailed.message", node.getName(), node.getHostname(), node.getPort(), (cause != null) ? cause.getMessage() : "no reason given"), I18n.get("mainWindow.error.nodeConnectionFailed.title"), JOptionPane.ERROR_MESSAGE);
1030 public void nodeDisconnected(Node node, Throwable throwable) {
1031 nodeDisconnectActions.get(node).setEnabled(false);
1032 nodeConnectActions.get(node).setEnabled(true);
1033 nodeEditActions.get(node).setEnabled(true);
1034 nodeDeleteActions.get(node).setEnabled(true);
1035 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.disconnectedFromNode", node.getName(), node.getHostname(), node.getPort()));
1036 mainWindow.setOffline(node);
1040 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertStarted(net.pterodactylus.jsite.project.Project)
1042 public void projectInsertStarted(Project project) {
1043 mainWindow.projectInsertStarted(project);
1047 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertProgressed(net.pterodactylus.jsite.project.Project,
1048 * int, int, int, int, int, boolean)
1050 public void projectInsertProgressed(Project project, int totalBlocks, int requiredBlocks, int successfulBlocks, int failedBlocks, int fatallyFailedBlocks, boolean finalizedTotal) {
1051 mainWindow.projectInsertProgressed(project, totalBlocks, requiredBlocks, successfulBlocks, failedBlocks, fatallyFailedBlocks, finalizedTotal);
1055 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertGeneratedURI(net.pterodactylus.jsite.project.Project,
1058 public void projectInsertGeneratedURI(Project project, String uri) {
1059 mainWindow.projectInsertGeneratedURI(project);
1063 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertFinished(net.pterodactylus.jsite.project.Project,
1066 public void projectInsertFinished(Project project, boolean success) {
1067 mainWindow.projectInsertFinished(project, success);
1071 // INTERFACE LoggingListener
1077 public void logged(LogRecord logRecord) {
1078 logWindow.logged(logRecord);
1082 // INTERFACE PropertyChangeListener
1088 public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
1089 /* do not react to anything (yet). */