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.Collections;
29 import java.util.Date;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Locale;
34 import java.util.Properties;
35 import java.util.concurrent.Executor;
36 import java.util.concurrent.Executors;
37 import java.util.logging.Level;
38 import java.util.logging.LogRecord;
39 import java.util.logging.Logger;
41 import javax.swing.AbstractAction;
42 import javax.swing.Action;
43 import javax.swing.JOptionPane;
44 import javax.swing.UIManager;
45 import javax.swing.UnsupportedLookAndFeelException;
47 import net.pterodactylus.jsite.core.Core;
48 import net.pterodactylus.jsite.core.CoreListener;
49 import net.pterodactylus.jsite.core.JSiteException;
50 import net.pterodactylus.jsite.core.Node;
51 import net.pterodactylus.jsite.i18n.I18n;
52 import net.pterodactylus.jsite.i18n.gui.I18nAction;
53 import net.pterodactylus.jsite.project.Project;
54 import net.pterodactylus.util.image.IconLoader;
55 import net.pterodactylus.util.io.Closer;
56 import net.pterodactylus.util.logging.Logging;
57 import net.pterodactylus.util.logging.LoggingListener;
60 * The Swing user interface.
62 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
65 public class SwingInterface implements CoreListener, LoggingListener {
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 “manage nodes” action. */
95 private I18nAction manageNodesAction;
97 /** The “connect to node” (simple mode) action. */
98 private I18nAction nodeConnectAction;
100 /** The “disconnect from node” (simple mode) action. */
101 private I18nAction nodeDisconnectAction;
103 /** All node menu items. */
104 private List<Action> nodeConnectActions = Collections.synchronizedList(new ArrayList<Action>());
106 /** Mapping from nodes to node connect actions. */
107 private Map<Node, Action> nodeNodeConnectActions = Collections.synchronizedMap(new HashMap<Node, Action>());
109 /** Mapping from node connect actions to nodes. */
110 private Map<Action, Node> nodeConnectActionNodes = Collections.synchronizedMap(new HashMap<Action, Node>());
112 /** All node disconnect actions. */
113 private List<Action> nodeDisconnectActions = Collections.synchronizedList(new ArrayList<Action>());
115 /** Mapping from nodes to node disconnect actions. */
116 private Map<Node, Action> nodeNodeDisconnectActions = Collections.synchronizedMap(new HashMap<Node, Action>());
118 /** Mapping from node disconnect actions to nodes. */
119 private Map<Action, Node> nodeDisconnectActionNodes = Collections.synchronizedMap(new HashMap<Action, Node>());
121 /** The node manager dialog. */
122 private ManageNodesDialog manageNodesDialog;
124 /** All lanugage menu items. */
125 private List<I18nAction> languageActions = new ArrayList<I18nAction>();
127 /** The “about” action. */
128 private I18nAction helpAboutAction;
130 /** The “add project” action. */
131 private I18nAction addProjectAction;
133 /** The “clone project” action. */
134 private I18nAction cloneProjectAction;
136 /** The “delete project” action. */
137 private I18nAction deleteProjectAction;
139 /** The “about” dialog. */
140 private AboutDialog aboutDialog;
142 /** The configuration dialog. */
143 private ConfigurationDialog configurationDialog;
145 /** The list of all defined nodes. */
146 private List<Node> nodeList = Collections.synchronizedList(new ArrayList<Node>());
152 /** The advanced mode. */
153 private boolean advancedMode;
155 /** Whether to antialias the GUI. */
156 private boolean antialias;
158 /** The control font. */
159 private String controlFont;
161 /** The user font. */
162 private String userFont;
164 /** The class name of the look and feel. */
165 private String lookAndFeel;
167 /** X coordinate of the main window. */
168 private int mainWindowX = -1;
170 /** Y coordinate of the main window. */
171 private int mainWindowY = -1;
173 /** Width of the main window. */
174 private int mainWindowWidth = -1;
176 /** Height of the main window. */
177 private int mainWindowHeight = -1;
180 * Creates a new swing interface.
183 * The core to operate on
184 * @param configDirectory
185 * The directory the configuration is stored in
187 public SwingInterface(Core core, String configDirectory) {
189 this.configDirectory = configDirectory;
190 I18n.setLocale(Locale.ENGLISH);
192 if (lookAndFeel != null) {
194 UIManager.setLookAndFeel(lookAndFeel);
195 } catch (ClassNotFoundException cnfe1) {
196 logger.log(Level.WARNING, "could not load look and feel", cnfe1);
197 } catch (InstantiationException ie1) {
198 logger.log(Level.WARNING, "could not load look and feel", ie1);
199 } catch (IllegalAccessException iae1) {
200 logger.log(Level.WARNING, "could not load look and feel", iae1);
201 } catch (UnsupportedLookAndFeelException ulafe1) {
202 logger.log(Level.WARNING, "could not load look and feel", ulafe1);
206 System.setProperty("swing.aatext", "true");
208 if (controlFont != null) {
209 System.setProperty("swing.plaf.metal.controlFont", controlFont);
211 if (userFont != null) {
212 System.setProperty("swing.plaf.metal.userFont", userFont);
216 mainWindow = new MainWindow(this);
217 mainWindow.setAdvancedMode(advancedMode);
218 if ((mainWindowX != -1) && (mainWindowY != -1) && (mainWindowWidth != -1) && (mainWindowHeight != -1)) {
219 mainWindow.setLocation(mainWindowX, mainWindowY);
220 mainWindow.setSize(mainWindowWidth, mainWindowHeight);
222 logWindow = new LogWindow();
230 * Returns the core that is controlled by the Swing interface.
239 * Returns the main window of the Swing interface.
241 * @return The main window
243 MainWindow getMainWindow() {
248 * Returns whether the advanced mode is activated.
250 * @return <code>true</code> if the advanced mode is activated,
251 * <code>false</code> if the simple mode is activated
253 boolean isAdvancedMode() {
258 * Returns the “configure” action.
260 * @return The “configure” action
262 I18nAction getConfigureAction() {
263 return configureAction;
267 * Returns the “import config” action.
269 * @return The “import config” action
271 I18nAction getImportConfigAction() {
272 return importConfigAction;
276 * Returns the “quit” action.
278 * @return The “quit” action
280 I18nAction getQuitAction() {
285 * Returns the “manage nodes” action.
287 * @return The “manage nodes” action
289 I18nAction getManageNodesAction() {
290 return manageNodesAction;
294 * Returns the “connect to node” action.
296 * @return The “connect to node” action
298 I18nAction getNodeConnectAction() {
299 return nodeConnectAction;
303 * Returns all “connect node” actions.
305 * @return All “connect node” actions
307 List<Action> getNodeConnectActions() {
308 return nodeConnectActions;
312 * Returns the “disconnect from node” action.
314 * @return The “disconnect from node” action
316 I18nAction getNodeDisconnectAction() {
317 return nodeDisconnectAction;
321 * Returns all “disconnect node” actions.
323 * @return All “disconnect node” action
325 List<Action> getNodeDisconnectActions() {
326 return nodeDisconnectActions;
330 * Returns all language actions.
332 * @return All language actions
334 List<I18nAction> getLanguageActions() {
335 return languageActions;
339 * Returns the “about” action.
341 * @return The “about” action
343 I18nAction getHelpAboutAction() {
344 return helpAboutAction;
348 * Returns the “add project” action.
350 * @return The “add project” action
352 I18nAction getAddProjectAction() {
353 return addProjectAction;
357 * Returns the “clone project” action.
359 * @return The “clone project” action
361 I18nAction getCloneProjectAction() {
362 return cloneProjectAction;
366 * Returns the “delete project” action.
368 * @return The “delete project” action
370 I18nAction getDeleteProjectAction() {
371 return deleteProjectAction;
387 * Loads the configuration of the interface.
389 private void loadConfig() {
390 /* initialize default stuff. */
392 /* now read config. */
393 File configFile = new File(configDirectory, "swing-interface.properties");
394 if (!configFile.exists() || !configFile.canRead() || !configFile.isFile()) {
395 System.err.println("could not find “" + configFile.getAbsolutePath() + "”!");
398 Properties configProperties = new Properties();
399 FileInputStream configInputStream = null;
401 configInputStream = new FileInputStream(configFile);
402 configProperties.load(configInputStream);
403 } catch (IOException ioe1) {
404 System.err.println("could not load config, " + ioe1.getMessage());
406 Closer.close(configInputStream);
408 if (configProperties.containsKey("advancedMode")) {
409 advancedMode = Boolean.valueOf(configProperties.getProperty("advancedMode"));
411 if (configProperties.containsKey("antialias")) {
412 antialias = Boolean.valueOf(configProperties.getProperty("antialias"));
414 if (configProperties.containsKey("controlFont")) {
415 controlFont = configProperties.getProperty("controlFont");
417 if (configProperties.containsKey("userFont")) {
418 userFont = configProperties.getProperty("userFont");
420 if (configProperties.containsKey("lookAndFeel")) {
421 lookAndFeel = configProperties.getProperty("lookAndFeel");
423 if (configProperties.containsKey("language")) {
424 I18n.setLocale(new Locale(configProperties.getProperty("language")));
426 if (configProperties.containsKey("mainWindowX")) {
427 mainWindowX = Integer.valueOf(configProperties.getProperty("mainWindowX"));
429 if (configProperties.containsKey("mainWindowY")) {
430 mainWindowY = Integer.valueOf(configProperties.getProperty("mainWindowY"));
432 if (configProperties.containsKey("mainWindowWidth")) {
433 mainWindowWidth = Integer.valueOf(configProperties.getProperty("mainWindowWidth"));
435 if (configProperties.containsKey("mainWindowHeight")) {
436 mainWindowHeight = Integer.valueOf(configProperties.getProperty("mainWindowHeight"));
441 * Saves the configuration.
443 private void saveConfig() {
444 File configDirectory = new File(this.configDirectory);
445 if (!configDirectory.exists()) {
446 if (!configDirectory.mkdirs()) {
447 System.err.println("could not create “" + this.configDirectory + "”!");
451 if (!configDirectory.exists() || !configDirectory.isDirectory() || !configDirectory.canWrite()) {
452 System.err.println("can not access “" + this.configDirectory + "”!");
455 File configFile = new File(configDirectory, "swing-interface.properties");
456 Properties configProperties = new Properties();
457 configProperties.setProperty("advancedMode", String.valueOf(advancedMode));
458 configProperties.setProperty("antialias", String.valueOf(antialias));
459 if (controlFont != null) {
460 configProperties.setProperty("controlFont", controlFont);
462 if (userFont != null) {
463 configProperties.setProperty("userFont", userFont);
465 if (lookAndFeel != null) {
466 configProperties.setProperty("lookAndFeel", lookAndFeel);
468 configProperties.setProperty("language", I18n.getLocale().getLanguage());
469 configProperties.setProperty("mainWindowX", String.valueOf(mainWindowX));
470 configProperties.setProperty("mainWindowY", String.valueOf(mainWindowY));
471 configProperties.setProperty("mainWindowWidth", String.valueOf(mainWindowWidth));
472 configProperties.setProperty("mainWindowHeight", String.valueOf(mainWindowHeight));
473 FileOutputStream configOutputStream = null;
475 configOutputStream = new FileOutputStream(configFile);
476 configProperties.store(configOutputStream, "configuration of swing interface");
477 } catch (IOException ioe1) {
478 System.err.println("could not save config, " + ioe1.getMessage());
480 Closer.close(configOutputStream);
485 * Initializes all actions.
487 private void initActions() {
488 configureAction = new I18nAction("mainWindow.menu.jSite.configure", IconLoader.loadIcon("/preferences-system.png")) {
493 @SuppressWarnings("synthetic-access")
494 public void actionPerformed(ActionEvent actionEvent) {
498 importConfigAction = new I18nAction("mainWindow.menu.jSite.importConfig") {
503 @SuppressWarnings("synthetic-access")
504 public void actionPerformed(ActionEvent actionEvent) {
508 quitAction = new I18nAction("mainWindow.menu.jSite.quit", IconLoader.loadIcon("/system-log-out.png")) {
513 @SuppressWarnings("synthetic-access")
514 public void actionPerformed(ActionEvent actionEvent) {
518 manageNodesAction = new I18nAction("mainWindow.menu.node.item.manageNodes") {
523 @SuppressWarnings("synthetic-access")
524 public void actionPerformed(ActionEvent actionEvent) {
528 nodeConnectAction = new I18nAction("mainWindow.menu.node.item.connect", false) {
530 @SuppressWarnings("synthetic-access")
531 public void actionPerformed(ActionEvent actionEvent) {
532 List<Node> nodes = core.getNodes();
533 if (nodes.isEmpty()) {
536 nodeConnect(nodes.get(0));
540 nodeDisconnectAction = new I18nAction("mainWindow.menu.node.item.disconnect", false) {
545 @SuppressWarnings("synthetic-access")
546 public void actionPerformed(ActionEvent e) {
547 List<Node> nodes = core.getNodes();
548 if (nodes.isEmpty()) {
551 nodeDisconnect(nodes.get(0));
554 rebuildNodeActions(core.getNodes());
555 List<Locale> availableLanguages = I18n.findAvailableLanguages();
556 for (final Locale locale: availableLanguages) {
557 I18nAction languageAction = new I18nAction("general.language." + locale.getLanguage()) {
559 @SuppressWarnings("synthetic-access")
560 public void actionPerformed(ActionEvent e) {
561 changeLanguage(locale, this);
565 if (I18n.getLocale().getLanguage().equals(locale.getLanguage())) {
566 languageAction.setEnabled(false);
568 languageActions.add(languageAction);
570 helpAboutAction = new I18nAction("mainWindow.menu.help.item.about") {
575 @SuppressWarnings("synthetic-access")
576 public void actionPerformed(ActionEvent actionEvent) {
580 addProjectAction = new I18nAction("mainWindow.button.addProject") {
585 @SuppressWarnings("synthetic-access")
586 public void actionPerformed(ActionEvent actionEvent) {
590 cloneProjectAction = new I18nAction("mainWindow.button.cloneProject") {
595 @SuppressWarnings("synthetic-access")
596 public void actionPerformed(ActionEvent actionEvent) {
600 deleteProjectAction = new I18nAction("mainWindow.button.deleteProject") {
605 @SuppressWarnings("synthetic-access")
606 public void actionPerformed(ActionEvent actionEvent) {
613 * Initializes all child dialogs.
615 private void initDialogs() {
616 manageNodesDialog = new ManageNodesDialog(this);
617 aboutDialog = new AboutDialog(this);
618 configurationDialog = new ConfigurationDialog(this);
626 * Shows the configuration dialog.
628 private void configure() {
629 configurationDialog.setAdvancedMode(advancedMode);
630 configurationDialog.setAntialias(antialias);
631 configurationDialog.setControlFont(controlFont);
632 configurationDialog.setUserFont(userFont);
633 configurationDialog.setLookAndFeel(lookAndFeel);
634 configurationDialog.setVisible(true);
635 if (!configurationDialog.wasCancelled()) {
636 advancedMode = configurationDialog.isAdvancedMode();
637 if (!advancedMode && (nodeList.size() > 1)) {
638 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.warning.multipleNodesNotAdvancedMode.message"), I18n.get("mainWindow.warning.multipleNodesNotAdvancedMode.title"), JOptionPane.WARNING_MESSAGE);
640 mainWindow.setAdvancedMode(advancedMode);
641 antialias = configurationDialog.isAntialias();
642 controlFont = configurationDialog.getControlFont();
643 userFont = configurationDialog.getUserFont();
644 lookAndFeel = configurationDialog.getLookAndFeel();
650 * Imports old jSite configuration.
652 private void importConfig() {
659 private void quit() {
662 mainWindowX = mainWindow.getX();
663 mainWindowY = mainWindow.getY();
664 mainWindowWidth = mainWindow.getWidth();
665 mainWindowHeight = mainWindow.getHeight();
671 * Rebuilds all node connect and disconnect actions.
676 private void rebuildNodeActions(List<Node> nodes) {
677 logger.fine("rebuilding node actions…");
678 nodeConnectActions.clear();
679 nodeNodeConnectActions.clear();
680 nodeConnectActionNodes.clear();
681 nodeDisconnectActions.clear();
682 nodeNodeDisconnectActions.clear();
683 nodeDisconnectActionNodes.clear();
684 for (Node node: nodes) {
685 logger.finer("adding node “" + node + "” to menus");
686 Action nodeConnectAction = new AbstractAction(node.getName()) {
691 @SuppressWarnings("synthetic-access")
692 public void actionPerformed(ActionEvent e) {
693 Node node = nodeConnectActionNodes.get(this);
697 nodeConnectActions.add(nodeConnectAction);
698 nodeConnectActionNodes.put(nodeConnectAction, node);
699 nodeNodeConnectActions.put(node, nodeConnectAction);
700 Action nodeDisconnectAction = new AbstractAction(node.getName()) {
705 @SuppressWarnings("synthetic-access")
706 public void actionPerformed(ActionEvent e) {
707 Node node = nodeDisconnectActionNodes.get(this);
708 nodeDisconnect(node);
711 // nodeDisconnectActions.add(nodeDisconnectAction);
712 nodeDisconnectActionNodes.put(nodeDisconnectAction, node);
713 nodeNodeDisconnectActions.put(node, nodeDisconnectAction);
718 * Pops up the “manage nodes” dialog.
720 private void manageNodes() {
722 manageNodesDialog.setNodeList(nodeList);
723 manageNodesDialog.setVisible(true);
724 nodeList = manageNodesDialog.getNodeList();
725 rebuildNodeActions(nodeList);
726 mainWindow.refreshNodeMenuItems();
728 if (nodeList.isEmpty()) {
729 Node newNode = new Node();
730 newNode.setName(I18n.get("general.defaultNode.name"));
731 newNode.setHostname("localhost");
732 newNode.setPort(9481);
733 nodeList.add(newNode);
735 Node firstNode = nodeList.get(0);
736 EditNodeDialog editNodeDialog = manageNodesDialog.getEditNodeDialog();
737 editNodeDialog.setNodeName(firstNode.getName());
738 editNodeDialog.setNodeHostname(firstNode.getHostname());
739 editNodeDialog.setNodePort(firstNode.getPort());
740 editNodeDialog.setVisible(true);
741 if (!editNodeDialog.wasCancelled()) {
742 firstNode.setName(editNodeDialog.getNodeName());
743 firstNode.setHostname(editNodeDialog.getNodeHostname());
744 firstNode.setPort(editNodeDialog.getNodePort());
745 /* TODO - give to core. */
751 * Connects to the node.
754 * The node to connect to
756 private void nodeConnect(final Node node) {
757 threadPool.execute(new Runnable() {
762 @SuppressWarnings("synthetic-access")
764 logger.log(Level.INFO, "connecting to node “" + node.getName() + "”…");
765 core.connectToNode(node);
771 * Disconnects from the node.
774 * The node to disconnect from
776 private void nodeDisconnect(Node node) {
777 logger.log(Level.INFO, "disconnecting from node “" + node.getName() + "”…");
778 core.disconnectFromNode(node);
782 * Changes the language of the interface. This method also disables the
783 * action for the newly set language and enables all others.
787 * @param languageAction
788 * The action that triggered the change
790 private void changeLanguage(Locale newLocale, I18nAction languageAction) {
791 for (I18nAction i18nAction: languageActions) {
792 i18nAction.setEnabled(i18nAction != languageAction);
794 I18n.setLocale(newLocale);
798 * Shows the “about” dialog.
800 private void helpAbout() {
801 aboutDialog.setVisible(true);
807 private void addProject() {
809 Project project = core.createProject();
810 project.setName(I18n.get("general.newProject.name"));
811 project.setDescription(I18n.get("general.newProject.description", new Date()));
812 mainWindow.addProject(project, true);
813 } catch (JSiteException nne1) {
814 /* TODO - add i18n */
815 JOptionPane.showMessageDialog(mainWindow, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE);
816 } catch (IOException e) {
817 /* TODO - add i18n */
818 JOptionPane.showMessageDialog(mainWindow, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE);
825 private void cloneProject() {
832 private void deleteProject() {
837 // INTERFACE CoreListener
843 public void loadingProjectsDone(String directory) {
844 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.projectLoadingDone"));
845 for (Project project: core.getProjects()) {
846 mainWindow.addProject(project, false);
853 public void loadingProjectsFailed(String directory, Throwable throwable) {
854 JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.projectLoadingFailed.message", directory), I18n.get("mainWindow.error.projectLoadingFailed.title"), JOptionPane.ERROR_MESSAGE);
860 public void savingProjectsDone(String directory) {
861 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.projectSavingDone"));
867 public void savingProjectsFailed(String directory, Throwable throwabled) {
874 public void loadingNodesDone(String directory) {
875 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.loadingNodesDone"));
881 public void loadingNodesFailed(String directory, Throwable throwable) {
888 public void savingNodesDone(String directory) {
889 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.savingNodesDone"));
895 public void savingNodesFailed(String directory, Throwable throwable) {
902 public void coreLoaded() {
903 mainWindow.setVisible(true);
904 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.coreLoaded"));
910 public void coreStopped() {
911 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.coreStopped"));
917 public void nodeAdded(Node node) {
918 logger.log(Level.INFO, "node added: " + node);
920 logger.log(Level.FINE, "nodeList.size(): " + nodeList.size());
921 manageNodesDialog.setNodeList(nodeList);
922 rebuildNodeActions(nodeList);
923 mainWindow.refreshNodeMenuItems();
929 public void nodeRemoved(Node node) {
930 logger.log(Level.INFO, "node removed: " + node);
931 nodeList.remove(node);
932 rebuildNodeActions(nodeList);
933 mainWindow.refreshNodeMenuItems();
939 public void nodeConnecting(Node node) {
940 Action nodeConnectAction = nodeNodeConnectActions.get(node);
941 nodeConnectActions.remove(nodeConnectAction);
942 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectingToNode", node.getName(), node.getHostname(), node.getPort()));
943 mainWindow.refreshNodeMenuItems();
949 public void nodeConnected(Node node) {
950 Action nodeDisconnectAction = nodeNodeDisconnectActions.get(node);
951 nodeDisconnectActions.add(nodeDisconnectAction);
952 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectedToNode", node.getName(), node.getHostname(), node.getPort()));
953 mainWindow.refreshNodeMenuItems();
959 public void nodeConnectionFailed(Node node, Throwable cause) {
960 Action nodeConnectAction = nodeNodeConnectActions.get(node);
961 nodeConnectActions.add(nodeConnectAction);
962 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectionToNodeFailed", node.getName(), node.getHostname(), node.getPort(), (cause != null) ? cause.getMessage() : "no reason given"));
963 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);
964 mainWindow.refreshNodeMenuItems();
970 public void nodeDisconnected(Node node, Throwable throwable) {
971 Action nodeConnectAction = nodeNodeConnectActions.get(node);
972 nodeConnectActions.add(nodeConnectAction);
973 Action nodeDisconnectAction = nodeNodeDisconnectActions.get(node);
974 nodeDisconnectActions.remove(nodeDisconnectAction);
975 mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.disconnectedFromNode", node.getName(), node.getHostname(), node.getPort()));
976 mainWindow.refreshNodeMenuItems();
980 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertStarted(net.pterodactylus.jsite.project.Project)
982 public void projectInsertStarted(Project project) {
983 mainWindow.projectInsertStarted(project);
987 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertProgressed(net.pterodactylus.jsite.project.Project,
988 * int, int, int, int, int, boolean)
990 public void projectInsertProgressed(Project project, int totalBlocks, int requiredBlocks, int successfulBlocks, int failedBlocks, int fatallyFailedBlocks, boolean finalizedTotal) {
991 mainWindow.projectInsertProgressed(project, totalBlocks, requiredBlocks, successfulBlocks, failedBlocks, fatallyFailedBlocks, finalizedTotal);
995 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertGeneratedURI(net.pterodactylus.jsite.project.Project,
998 public void projectInsertGeneratedURI(Project project, String uri) {
999 mainWindow.projectInsertGeneratedURI(project);
1003 * @see net.pterodactylus.jsite.core.CoreListener#projectInsertFinished(net.pterodactylus.jsite.project.Project,
1006 public void projectInsertFinished(Project project, boolean success) {
1007 mainWindow.projectInsertFinished(project, success);
1011 // INTERFACE LoggingListener
1017 public void logged(LogRecord logRecord) {
1018 logWindow.logged(logRecord);