diff --git a/apps/desktopgui/desktopgui/resources/logo/logo_green.jpg b/apps/desktopgui/desktopgui/resources/logo/logo_green.jpg
new file mode 100644
index 000000000..9a29b6d1c
Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo_green.jpg differ
diff --git a/apps/desktopgui/desktopgui/resources/logo/logo_orange.jpg b/apps/desktopgui/desktopgui/resources/logo/logo_orange.jpg
new file mode 100644
index 000000000..137a25e7a
Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo_orange.jpg differ
diff --git a/apps/desktopgui/desktopgui/resources/logo/logo_red.jpg b/apps/desktopgui/desktopgui/resources/logo/logo_red.jpg
new file mode 100644
index 000000000..1da898381
Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo_red.jpg differ
diff --git a/apps/desktopgui/src/gui/GeneralConfiguration.form b/apps/desktopgui/src/gui/GeneralConfiguration.form
new file mode 100644
index 000000000..070e20138
--- /dev/null
+++ b/apps/desktopgui/src/gui/GeneralConfiguration.form
@@ -0,0 +1,103 @@
+
+
+
diff --git a/apps/desktopgui/src/gui/GeneralConfiguration.java b/apps/desktopgui/src/gui/GeneralConfiguration.java
new file mode 100644
index 000000000..b9c740381
--- /dev/null
+++ b/apps/desktopgui/src/gui/GeneralConfiguration.java
@@ -0,0 +1,106 @@
+/*
+ * GeneralConfiguration.java
+ *
+ * Created on 10 april 2009, 19:04
+ */
+
+package gui;
+
+/**
+ *
+ * @author mathias
+ */
+public class GeneralConfiguration extends javax.swing.JFrame {
+
+ /** Creates new form GeneralConfiguration */
+ public GeneralConfiguration() {
+ initComponents();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jTabbedPane1 = new javax.swing.JTabbedPane();
+ jPanel1 = new javax.swing.JPanel();
+ jPanel2 = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setName("Form"); // NOI18N
+
+ jTabbedPane1.setName("jTabbedPane1"); // NOI18N
+
+ jPanel1.setName("jPanel1"); // NOI18N
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 474, Short.MAX_VALUE)
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 338, Short.MAX_VALUE)
+ );
+
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(GeneralConfiguration.class);
+ jTabbedPane1.addTab(resourceMap.getString("jPanel1.TabConstraints.tabTitle"), jPanel1); // NOI18N
+
+ jPanel2.setName("jPanel2"); // NOI18N
+
+ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2Layout.setHorizontalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 474, Short.MAX_VALUE)
+ );
+ jPanel2Layout.setVerticalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 338, Short.MAX_VALUE)
+ );
+
+ jTabbedPane1.addTab(resourceMap.getString("jPanel2.TabConstraints.tabTitle"), jPanel2); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 478, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 369, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new GeneralConfiguration().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JTabbedPane jTabbedPane1;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/apps/desktopgui/src/gui/JPopupTrayIcon.java b/apps/desktopgui/src/gui/JPopupTrayIcon.java
new file mode 100644
index 000000000..83872e4a5
--- /dev/null
+++ b/apps/desktopgui/src/gui/JPopupTrayIcon.java
@@ -0,0 +1,176 @@
+/*
+* Created on Sep 15, 2008 5:51:33 PM
+*/
+
+/*
+ * This class is part of fishfarm project: https://fishfarm.dev.java.net/
+ * It is licensed under the GPL version 2.0 with Classpath Exception.
+ *
+ * Copyright (C) 2008 Michael Bien
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+package gui;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.PopupMenu;
+import java.awt.TrayIcon;
+import java.awt.Window;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JWindow;
+import javax.swing.RootPaneContainer;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+
+
+
+/**
+ * JPopupMenu compatible TrayIcon based on Alexander Potochkin's JXTrayIcon
+ * (http://weblogs.java.net/blog/alexfromsun/archive/2008/02/jtrayicon_updat.html)
+ * but uses a JWindow instead of a JDialog to workaround some bugs on linux.
+ *
+ * @author Michael Bien
+ */
+public class JPopupTrayIcon extends TrayIcon {
+
+ private JPopupMenu menu;
+
+ private Window window;
+ private PopupMenuListener popupListener;
+
+ private final static boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("windows");
+
+ public JPopupTrayIcon(Image image) {
+ super(image);
+ init();
+ }
+
+ public JPopupTrayIcon(Image image, String tooltip) {
+ super(image, tooltip);
+ init();
+ }
+
+ public JPopupTrayIcon(Image image, String tooltip, PopupMenu popup) {
+ super(image, tooltip, popup);
+ init();
+ }
+
+ public JPopupTrayIcon(Image image, String tooltip, JPopupMenu popup) {
+ super(image, tooltip);
+ init();
+ setJPopupMenu(popup);
+ }
+
+
+ private final void init() {
+
+
+ popupListener = new PopupMenuListener() {
+
+ @Override
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+// System.out.println("popupMenuWillBecomeVisible");
+ }
+
+ @Override
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+// System.out.println("popupMenuWillBecomeInvisible");
+ if(window != null) {
+ window.dispose();
+ window = null;
+ }
+ }
+
+ @Override
+ public void popupMenuCanceled(PopupMenuEvent e) {
+// System.out.println("popupMenuCanceled");
+ if(window != null) {
+ window.dispose();
+ window = null;
+ }
+ }
+ };
+
+ addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent e) {
+// System.out.println(e.getPoint());
+ showJPopupMenu(e);
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+// System.out.println(e.getPoint());
+ showJPopupMenu(e);
+ }
+ });
+
+ }
+
+ private final void showJPopupMenu(MouseEvent e) {
+ if(e.isPopupTrigger() && menu != null) {
+ if (window == null) {
+
+ if(IS_WINDOWS) {
+ window = new JDialog((Frame)null);
+ ((JDialog)window).setUndecorated(true);
+ }else{
+ window = new JWindow((Frame)null);
+ }
+ window.setAlwaysOnTop(true);
+ Dimension size = menu.getPreferredSize();
+
+ Point centerPoint = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
+ if(e.getY() > centerPoint.getY())
+ window.setLocation(e.getX(), e.getY() - size.height);
+ else
+ window.setLocation(e.getX(), e.getY());
+
+ window.setVisible(true);
+
+ menu.show(((RootPaneContainer)window).getContentPane(), 0, 0);
+
+ // popup works only for focused windows
+ window.toFront();
+
+ }
+ }
+ }
+
+
+ public final JPopupMenu getJPopupMenu() {
+ return menu;
+ }
+
+ public final void setJPopupMenu(JPopupMenu menu) {
+ if (this.menu != null) {
+ this.menu.removePopupMenuListener(popupListener);
+ }
+ this.menu = menu;
+ menu.addPopupMenuListener(popupListener);
+ }
+
+}
diff --git a/apps/desktopgui/src/gui/SpeedSelector.form b/apps/desktopgui/src/gui/SpeedSelector.form
index 6ccf414b5..79d25ae96 100644
--- a/apps/desktopgui/src/gui/SpeedSelector.form
+++ b/apps/desktopgui/src/gui/SpeedSelector.form
@@ -22,6 +22,7 @@
+
diff --git a/apps/desktopgui/src/gui/SpeedSelector2.form b/apps/desktopgui/src/gui/SpeedSelector2.form
index 215d407f0..5c305de19 100644
--- a/apps/desktopgui/src/gui/SpeedSelector2.form
+++ b/apps/desktopgui/src/gui/SpeedSelector2.form
@@ -26,6 +26,7 @@
+
@@ -82,7 +83,7 @@
-
+
@@ -97,7 +98,7 @@
-
+
@@ -108,7 +109,7 @@
-
+
diff --git a/apps/desktopgui/src/gui/SpeedSelector2.java b/apps/desktopgui/src/gui/SpeedSelector2.java
index d929e4ccd..1177b5725 100644
--- a/apps/desktopgui/src/gui/SpeedSelector2.java
+++ b/apps/desktopgui/src/gui/SpeedSelector2.java
@@ -85,19 +85,19 @@ public class SpeedSelector2 extends javax.swing.JFrame {
browseButton.setActionCommand(resourceMap.getString("browseButton.actionCommand")); // NOI18N
browseButton.setName("browseButton"); // NOI18N
getContentPane().add(browseButton);
- browseButton.setBounds(40, 130, 520, 40);
+ browseButton.setBounds(40, 120, 520, 40);
buttonGroup1.add(downloadButton);
downloadButton.setText(resourceMap.getString("downloadButton.text")); // NOI18N
downloadButton.setActionCommand(resourceMap.getString("downloadButton.actionCommand")); // NOI18N
downloadButton.setName("downloadButton"); // NOI18N
getContentPane().add(downloadButton);
- downloadButton.setBounds(40, 80, 499, 40);
+ downloadButton.setBounds(40, 70, 499, 40);
jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
jLabel1.setName("jLabel1"); // NOI18N
getContentPane().add(jLabel1);
- jLabel1.setBounds(30, 190, 530, 50);
+ jLabel1.setBounds(30, 170, 530, 70);
pack();
}// //GEN-END:initComponents
diff --git a/apps/desktopgui/src/gui/SpeedSelector3.form b/apps/desktopgui/src/gui/SpeedSelector3.form
index ec2697221..9c6ef533a 100644
--- a/apps/desktopgui/src/gui/SpeedSelector3.form
+++ b/apps/desktopgui/src/gui/SpeedSelector3.form
@@ -329,7 +329,7 @@
-
+
diff --git a/apps/desktopgui/src/gui/SpeedSelector3.java b/apps/desktopgui/src/gui/SpeedSelector3.java
index 8115acb2b..1f523befd 100644
--- a/apps/desktopgui/src/gui/SpeedSelector3.java
+++ b/apps/desktopgui/src/gui/SpeedSelector3.java
@@ -122,12 +122,12 @@ public class SpeedSelector3 extends javax.swing.JFrame {
uploadUsageLabel.setText(resourceMap.getString("uploadUsageLabel.text")); // NOI18N
uploadUsageLabel.setName("uploadUsageLabel"); // NOI18N
getContentPane().add(uploadUsageLabel);
- uploadUsageLabel.setBounds(20, 150, 141, 30);
+ uploadUsageLabel.setBounds(20, 150, 19, 30);
downloadUsageLabel.setText(resourceMap.getString("downloadUsageLabel.text")); // NOI18N
downloadUsageLabel.setName("downloadUsageLabel"); // NOI18N
getContentPane().add(downloadUsageLabel);
- downloadUsageLabel.setBounds(340, 150, 162, 30);
+ downloadUsageLabel.setBounds(340, 150, 19, 30);
uploadField.setText(resourceMap.getString("uploadField.text")); // NOI18N
uploadField.setMinimumSize(new java.awt.Dimension(77, 27));
@@ -236,7 +236,7 @@ public class SpeedSelector3 extends javax.swing.JFrame {
explanation.setText(resourceMap.getString("explanation.text")); // NOI18N
explanation.setName("explanation"); // NOI18N
getContentPane().add(explanation);
- explanation.setBounds(20, 200, 600, 40);
+ explanation.setBounds(20, 180, 600, 70);
pack();
}// //GEN-END:initComponents
diff --git a/apps/desktopgui/src/gui/Tray.java b/apps/desktopgui/src/gui/Tray.java
index bf3cd28c8..5a8da78db 100644
--- a/apps/desktopgui/src/gui/Tray.java
+++ b/apps/desktopgui/src/gui/Tray.java
@@ -9,9 +9,6 @@ import desktopgui.*;
import java.awt.AWTException;
import java.awt.Desktop;
import java.awt.Image;
-import java.awt.MenuItem;
-import java.awt.Menu;
-import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
@@ -23,8 +20,12 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
import router.RouterHandler;
import router.RouterHelper;
+import router.configuration.PeerHelper;
/**
*
@@ -41,12 +42,13 @@ public class Tray {
Image image = Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo.jpg");
- PopupMenu popup = new PopupMenu();
+ final JPopupMenu popup = new JPopupMenu();
//Create menu items to put in the popup menu
- MenuItem browserLauncher = new MenuItem("Launch browser");
+ JMenuItem browserLauncher = new JMenuItem("Launch browser");
browserLauncher.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent arg0) {
if(Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
@@ -66,9 +68,10 @@ public class Tray {
}
});
- MenuItem howto = new MenuItem("How to use I2P");
+ JMenuItem howto = new JMenuItem("How to use I2P");
howto.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent arg0) {
if(Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
@@ -84,18 +87,20 @@ public class Tray {
}
});
- Menu config = new Menu("Configuration");
- MenuItem speedConfig = new MenuItem("Speed");
+ JMenu config = new JMenu("Configuration");
+ JMenuItem speedConfig = new JMenuItem("Speed");
speedConfig.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent arg0) {
(new SpeedSelector()).setVisible(true);
}
});
- MenuItem advancedConfig = new MenuItem("Advanced Configuration");
+ JMenuItem advancedConfig = new JMenuItem("Advanced Configuration");
advancedConfig.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent arg0) {
if(Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
@@ -110,7 +115,7 @@ public class Tray {
}
});
- MenuItem viewLog = new MenuItem("View log");
+ JMenuItem viewLog = new JMenuItem("View log");
viewLog.addActionListener(new ActionListener() {
@Override
@@ -119,17 +124,21 @@ public class Tray {
}
});
- MenuItem shutdown = new MenuItem("Shutdown I2P");
+ JMenuItem shutdown = new JMenuItem("Shutdown I2P");
shutdown.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent arg0) {
RouterHandler.setStatus(RouterHandler.SHUTDOWN_GRACEFULLY);
long shutdownTime = RouterHelper.getGracefulShutdownTimeRemaining();
System.out.println(shutdownTime);
- if(shutdownTime>0)
- trayIcon.displayMessage("Shutting down...", "Shutdown time remaining: " + shutdownTime/1000 + " seconds.", TrayIcon.MessageType.INFO);
- else
+ if(shutdownTime>0) {
+ trayIcon.displayMessage("Shutting down...", "Shutdown time remaining: " + shutdownTime/1000 + " seconds."
+ + System.getProperty("line.separator") + "Shutdown will not happen immediately, because we are still participating in the network.", TrayIcon.MessageType.INFO);
+ }
+ else {
trayIcon.displayMessage("Shutting down...", "Shutting down immediately.", TrayIcon.MessageType.INFO);
+ }
}
});
@@ -147,7 +156,31 @@ public class Tray {
popup.add(shutdown);
//Add tray icon
- trayIcon = new TrayIcon(image, "I2P: the anonymous network", popup);
+ trayIcon = new JPopupTrayIcon(image, "I2P: the anonymous network", popup);
+ PeerHelper.addReachabilityListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ trayIcon.setToolTip("I2P Network status: " + PeerHelper.getReachability());
+ }
+
+ });
+ PeerHelper.addActivePeerListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ int activePeers = PeerHelper.getActivePeers();
+ if(activePeers == 0)
+ trayIcon.setImage(Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo_red.jpg"));
+ else if(activePeers < 10)
+ trayIcon.setImage(Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo_orange.jpg"));
+ else
+ trayIcon.setImage(Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo_green.jpg"));
+
+ }
+
+ });
+
try {
tray.add(trayIcon);
} catch (AWTException ex) {
@@ -156,6 +189,6 @@ public class Tray {
}
private SystemTray tray = null;
- private TrayIcon trayIcon = null;
+ private JPopupTrayIcon trayIcon = null;
}
diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector.properties b/apps/desktopgui/src/gui/resources/SpeedSelector.properties
index 03b04286f..00eb6c973 100644
--- a/apps/desktopgui/src/gui/resources/SpeedSelector.properties
+++ b/apps/desktopgui/src/gui/resources/SpeedSelector.properties
@@ -3,4 +3,4 @@ Form.title=I2P Speed Configuration
nextButton.text=Next
uploadLabel.text=What is your maximum upload speed?
downloadLabel.text=What is your maximum download speed?
-speedExplanation.text=Explanation about speeds...
+speedExplanation.text=The maximum speed is set by your provider. It can be given in kilobit (kbps) or kilobyte (kBps).
One kilobyte equals eight kilobit.
diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector2.properties b/apps/desktopgui/src/gui/resources/SpeedSelector2.properties
index 54424ed05..909518ada 100644
--- a/apps/desktopgui/src/gui/resources/SpeedSelector2.properties
+++ b/apps/desktopgui/src/gui/resources/SpeedSelector2.properties
@@ -6,4 +6,4 @@ downloadButton.text=Downloading: I want to use I2P for downloads and filesharing
nextButton.text=Next
browseButton.actionCommand=Browsing
downloadButton.actionCommand=Downloading
-jLabel1.text=Text explaining ...
+jLabel1.text=I2P can be used for many different purposes. Here, we present two possible descriptions. If you use a lot of bandwidth in I2P (for example using downloading), please check the downloading option. If your bandwidth usage is limited, please check the browsing option.
diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector3.properties b/apps/desktopgui/src/gui/resources/SpeedSelector3.properties
index 9d0718f8d..6dca3ca51 100644
--- a/apps/desktopgui/src/gui/resources/SpeedSelector3.properties
+++ b/apps/desktopgui/src/gui/resources/SpeedSelector3.properties
@@ -14,4 +14,4 @@ downloadBurstField.text=jTextField5
uploadMonth.text=jTextField1
downloadMonth.text=jTextField2
settingsInfo.text=The profile information your entered, indicates that these are your optimal settings:
-explanation.text=Text explaining ...
+explanation.text=We give a suggested upload and download speed. If your provider imposes a monthly bandwidth limit (usually given in gigabyte (GB)), please enter a value lower than that limit. If you run I2P only 50% of the time, you can double the bandwidth limit to use the same amount as when you are online 100% of the time.
diff --git a/apps/desktopgui/src/router/configuration/PeerHelper.java b/apps/desktopgui/src/router/configuration/PeerHelper.java
new file mode 100644
index 000000000..2272456f8
--- /dev/null
+++ b/apps/desktopgui/src/router/configuration/PeerHelper.java
@@ -0,0 +1,165 @@
+package router.configuration;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import net.i2p.data.RouterAddress;
+import net.i2p.router.CommSystemFacade;
+import net.i2p.router.RouterContext;
+import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
+import net.i2p.router.transport.ntcp.NTCPAddress;
+import router.RouterHelper;
+
+/**
+ * Part of the code imported and adapted from the I2P Router Console (which is licensed as public domain)
+ */
+public class PeerHelper {
+ public static String getReachability() {
+ RouterContext context = RouterHelper.getContext();
+ if (context.router().getUptime() > 60*1000
+ && (!context.router().gracefulShutdownInProgress())
+ && !context.clientManager().isAlive())
+ return "ERROR: Client Manager I2CP Error - check logs"; // not a router problem but the user should know
+ if (!context.clock().getUpdatedSuccessfully())
+ return "ERROR: ClockSkew";
+ if (context.router().isHidden())
+ return "Hidden";
+
+ int status = context.commSystem().getReachabilityStatus();
+ switch (status) {
+ case CommSystemFacade.STATUS_OK:
+ RouterAddress ra = context.router().getRouterInfo().getTargetAddress("NTCP");
+ if (ra == null || (new NTCPAddress(ra)).isPubliclyRoutable())
+ return "OK";
+ return "ERROR: Private TCP Address";
+ case CommSystemFacade.STATUS_DIFFERENT:
+ return "ERROR: You are behind a symmetric NAT.";
+ case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
+ if (context.router().getRouterInfo().getTargetAddress("NTCP") != null)
+ return "WARNING: You are behind a firewall and have Inbound TCP Enabled";
+ if (((FloodfillNetworkDatabaseFacade)context.netDb()).floodfillEnabled())
+ return "WARNING: You are behind a firewall and are a floodfill router";
+ if (context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0)
+ return "WARNING: You are behind a firewall and are a fast router";
+ return "Firewalled";
+ case CommSystemFacade.STATUS_HOSED:
+ return "ERROR: The UDP port is already in use. Set i2np.udp.internalPort=xxxx to a different value in the advanced config and restart";
+ case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
+ default:
+ ra = context.router().getRouterInfo().getTargetAddress("UDP");
+ if (ra == null && context.router().getUptime() > 5*60*1000) {
+ if (context.getProperty(PROP_I2NP_NTCP_HOSTNAME) == null ||
+ context.getProperty(PROP_I2NP_NTCP_PORT) == null)
+ return "ERROR: UDP is disabled and the inbound TCP host/port combination is not set";
+ else
+ return "WARNING: You are behind a firewall and have UDP Disabled";
+ }
+ return "Testing";
+ }
+ }
+
+ /**
+ * How many peers we are talking to now
+ *
+ */
+ public static int getActivePeers() {
+ RouterContext context = RouterHelper.getContext();
+ if (context == null)
+ return 0;
+ else
+ return context.commSystem().countActivePeers();
+ }
+
+ public static void addActivePeerListener(ActionListener listener) {
+ synchronized(activePeerListeners) {
+ activePeerListeners.add(listener);
+ if(activePeerTimer == null) {
+ activePeerTimer = new Timer();
+ TimerTask t = new TimerTask() {
+ private int activePeers = 0;
+
+ @Override
+ public void run() {
+ int newActivePeers = getActivePeers();
+ if(!(activePeers == newActivePeers)) {
+ synchronized(activePeerListeners) {
+ for(int i=0; i reachabilityListeners = new ArrayList();
+ private static Timer reachabilityTimer = null;
+
+ private static List activePeerListeners = new ArrayList();
+ private static Timer activePeerTimer = null;
+
+ /** copied from various private components */
+ public final static String PROP_I2NP_UDP_PORT = "i2np.udp.port";
+ public final static String PROP_I2NP_INTERNAL_UDP_PORT = "i2np.udp.internalPort";
+ public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
+ public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
+ public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoip";
+ public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoport";
+}