diff --git a/apps/desktopgui/LICENSE b/apps/desktopgui/LICENSE new file mode 100644 index 000000000..61febe901 --- /dev/null +++ b/apps/desktopgui/LICENSE @@ -0,0 +1,15 @@ +Desktop GUI: provides a simple GUI for I2P. +Copyright (C) 2009 Mathias De Maré + +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; only version 2 of the License. + +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. \ No newline at end of file diff --git a/apps/desktopgui/build.xml b/apps/desktopgui/build.xml new file mode 100644 index 000000000..c7ba1be11 --- /dev/null +++ b/apps/desktopgui/build.xml @@ -0,0 +1,69 @@ + + + + + + Builds, tests, and runs the project desktopgui. + + + diff --git a/apps/desktopgui/desktopgui/resources/howto/howto.html b/apps/desktopgui/desktopgui/resources/howto/howto.html new file mode 100644 index 000000000..ea1b025c7 --- /dev/null +++ b/apps/desktopgui/desktopgui/resources/howto/howto.html @@ -0,0 +1,261 @@ + + + Small Guide to I2P + + +

Small Guide to I2P

+ +

So, what's this all about?

+ +

I2P builds up a new net inside the usual internet, connecting nodes together + via encrypted connections. + It is a JAVA prgram with its most used part (the encryption of the data) written + in handoptimized assembler code. + It will use your bandwith, your RAM and your CPU. It will use them all up if you + do not limit it. + I2P will route unknown traffic through your node, even stuff you dislike. + As that data is encrypted, nobody knows whats data went to or drom your node. +

+ +

+ First, ALWAYS use the latest stable release. + Development releases are called "mtn version" and are marked with a -, e.g. + 0.6.5-1. Those are usually useable by all but could do harm to your I2P + experience. + You can get the latest MTN builds from my eepsite echelon.i2p, but always + remember: I built them, you need to trust me not to changed the code! + After you get the right "i2pupdate.zip" file, put that file into the I2P + directory and hit restart on the router console http://127.0.0.1:7657. + Do NOT deflate the zip file! +

+ +

+ I2P is very dynamic - after startup it tries to get known to other I2P routers + and measures their speed - you need to wait some 10-120 minutes until your + I2P router knows enough other ones to obtain full power of I2P. +

+ +

Filesharing

+ +

+ I2P is able to do anonymous filesharing. + But as there are NO gateways between real net and I2P, you can only share/ + download torrents from within I2P. Look e.g. postman.i2p or planet.i2p. + You CANNOT use azureus, utorrent or any other usual client. + You cannot download anonymous torrents from mininova, piratebay or else. + You need to use I2P internal torrents and I2P aware programs like + I2Psnark (builtin, suitable for 1-20 torrents) + I2PRufus (external, python, high CPU load, suitable >20 torrents) http://echelon.i2p/i2prufus + I2P-BT (external, python) + I2PsnarkXL (mod of I2Psnark made by fwd) +

+ +

+ There are also gnutella and edonkey clients: + i2phex for gnutella (http://echelon.i2p/i2phex) + imule for edonkey (http://echelon.i2p/imule) +

+ +

+ Remember, as I2P uses other routers to route your traffic via 1-6 other PCs, + your transferrates in P2P are slower than in usual internet. + But you are anonymous, no one can easily (within 2 months-2 years) get your IP! + torrents inside of I2P reaches up to 50 kb/sec, usual are 10-20 kb/sec per torrent + i2phex reaches up to 20 kb/sec, usually 5-10 kb/sec + imule in times reaches 10 kb/sec, usually 5-10 kb/sec +

+ +

+ In I2PHex and imule you can just tell "share file or directory", in torrent + you need to create a .torrent file and upload that (and ONLY that small .torrent) + file to the trackers like tracker.postman.i2p/ +

+ +

+ I2P is a smaller net (1000 users) which grows slowly. As of which amount of shared + data will slowly rise. +

+ +

+ I2P is anonymous and it does not censor - there is no administrator. + There IS unwanted stuff like kiddyporn, nazism, or else. + If you dislike all this, do not use I2P. + There is NO way to prohibite this stuff to appear in a anonymous net like I2P. + (as that stuff is available shows the anonymity and transfer function of I2P + is working well enough) + You can delete the destinations in question from your local hosts.txt file (or + deface them) which will partly prevent you to reach those bad sies by accident. +

+ +

Internet (the websites)

+ +

+ Only one outproxy (gateway I2P - webpages in usual Internet) is working. + It is NOT official from I2P, I2P does work without. + If that outproxy is slow, offline, gone,.. I2P still works on and cannot do + anything to change that failure. + That outproxy translates usual internet webpages into the I2P net and you can + reach them via your Router. + The best way for usual webpages is TOR, not that outproxy. + Remember: the owner of the outproxy got ALL traffic from all I2P users + visiting Internet pages and will risk that into the police! +

+ +

+ This proxy is false.i2p. In newer I2P routers it is enabled, but not in + older ones. Go to http://127.0.0.1:7657/i2ptunnel/index.jsp tunnels page and + click on the eepProxy tunnel. Change the entry for the "Outproxies" to false.i2p + and save. On the tunnels page, stop the epproxy tunnel and start it again, + now your router will use the false.i2p outproxy. +

+ +

+ No other (known) gateways are setup and running. No one we know will run + the gateway for torrent or any other P2P data (and risk his life). +

+ +

Bandwidth

+ +

http://127.0.0.1:7657/config.jsp

+ +

Setup your bandwith wisely. Know your linespeed!

+ +

+ E.g. most common terms are: + 1Mbit = roughly 100 kbyte/sec + 10 MBit = roughly 1100 kbyte/sec + 512 kbit = roughly 50 kbyte/sec + or in germany: + 16000er = roughly 1500 kbyte/sec + 6000er = roughly 600 kbyte/sec + 1000er = roughly 100 kb/sec +

+ +

+ Set your bandwith limits to 10% under your line speed and burst rate to + your line speed. + Set the bandwith share percentage to: + >80% if lowest bandwith setting is >50k + >50% if lowest bandwith setting is >30k + >20% if lowest bandwith setting is >16k +

+ +

There is no shared bandwith under 16k.

+ +

+ Limit your participating tunnels (shared bandwith) on: + http://127.0.0.1:7657/configadvanced.jsp + with the line: + router.maxParticipatingTunnels=500 +

+ +

+ 2000 is for roughly 600 kb/sec - very high value with high CPU load + 1000 is for roughly 300 kb/sec + 600 is a good value for 150-200kb/sec + 300 is roughly 90 kb/sec + 150 roughly 50 kb/sec + Remember: even failed tunnel requests will result in a part tunnel on the hops in between! + Those said, there are far more part tunnels unused than used in the live net under load, which + results in slower bandwith per tunnel in the end. + It is wise to first limit the bandwith and afterwards the part tunnels, e.g. set some more part + tunnels and let I2P reach the bandwith limit instead of the part tunnels limit! +

+ +

What is shared bandwidth?

+ +

+ I2P transports your date from the client to the server through 1-6 hops + (other I2P routers). Each of this hops sees the data from you as "participating + tunnel" - which is the shared bandwith of them. + With this in mind, I2P needs some amount of this shared bandwith at some + amount of routers. + Share as much as you are able of - others will thank you! +

+ +

+ With the "share percentage" set like above, you will obtain enough speed for + your own traffic and obtain some participating tunnels (if >16kb/sec) with some + noise traffic to hide your traffic in the stream. +

+ +

+ With release 0.6.5 there is some method to prefer your own traffic ahead + of shared traffic which will result in better experience to you! +

+ +

Addressbook

+ +

+ I2P uses a local addressbook to link short DNS names with the internal used 512bit + hashes (which are destination IDs). + Those links are saved insside the hosts.txt and userhosts.txt files in the i2p + directory. + Hosts which are not in those files cannot be reached via the short DNS names + and a error message with "jumper links" will appear. Those links will ask + some hosts services and forward to the correct site (if the site is known to them). + Those hosts services just made a form to add new "hosts" and those results public + available. + You can subscribe to those hosts service and let your hosts.txt file be updated + automatic. Go to http://127.0.0.1:7657/susidns/subscriptions.jsp SusiDNS + and enter the hosts services into the textbox (and save afterwards): + http://www.i2p2.i2p/hosts.txt + http://stats.i2p/cgi-bin/newhosts.txt + http://tino.i2p/hosts.txt + http://i2host.i2p/cgi-bin/i2hostag + You can add one of them, two or all. + SusiDNS will now ask those hosts for new entries to the hosts.txt and those + will be added to your hosts.txt. The userhosts.txt will ONLY be updated by + yourself (the user) and not be published into the net! + Remember, names once set could not be changed! If you loose your key (destination + ID) to your eepsite, service,..., there is no way to change the linking + between the DNS name and the (lost) destination ID automatic! Only manual by each + user itself - great topic to discuss of need to renew DNS hostnames. + As this subscription will not update old entries, you can "deface" unwanted + eepsites with a false key and if you hit the bad name in browser by accident, + you will not see the bad stuff! +

+ +

Out of Memory errors

+ +

+ If your router hits the Out of Memory error - check your logs! + Usual point for OOM are to much torrents in i2psnark - i2psnark is a real + memory hogg and >10 torrents it requiers hell a lot of memory! +

+ +

+ Maybe it is possible for you to increase the wrapper memory config. + This ONLY works if you start the I2P service restartable with console + (on Windows). + In I2P directory edit the wrapper.config file and change the values: + wrapper.java.maxmemory=256 (or even to 512, IF possible) + Afterwards shutdown I2P complete (the service) and restart it. +

+ +

Blocklists

+ +

+ Sometimes attackers trying to flood the I2P net and try to do some harm. + And some folks setting localnet IPs as their internet reachable address. + To prevent those bad router to harm the local router, I2P implemented + a local blocklist system. It is NOT integrated automatic as it could + really harm your I2P experience if setup the wrong way. + The way to enable blocklists is: + Get the file http://zzz.i2p/files/blocklist.txt and copy this file into the + I2P directory. + On http://127.0.0.1:7657/configadvanced.jsp set the option + router.blocklist.enable=true - click on Apply and restart the router + with the restart link left on router console. + The blockfile.txt file follows a special order, you´ll get it if you read it. + The first entry is the reason to be shown on http://127.0.0.1:7657/profiles.jsp + at the bottom in the shitlist section. + The second entry is the IP or the dest ID of a router. + Right now there are only private subnets in the blocklist AND one chinese router + which floods the floodfill DB while restarting every few minutes with a different + router ID and far to less bandwith for being a floodfill router. +

+ +

(By echelon -- echelon.i2p )

+ + diff --git a/apps/desktopgui/desktopgui/resources/logo/logo.jpg b/apps/desktopgui/desktopgui/resources/logo/logo.jpg new file mode 100644 index 000000000..f1b5ccfc8 Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo.jpg differ diff --git a/apps/desktopgui/lib/appframework.jar b/apps/desktopgui/lib/appframework.jar new file mode 100644 index 000000000..0b8ff0145 Binary files /dev/null and b/apps/desktopgui/lib/appframework.jar differ diff --git a/apps/desktopgui/lib/swing-worker.jar b/apps/desktopgui/lib/swing-worker.jar new file mode 100644 index 000000000..bcdd9d910 Binary files /dev/null and b/apps/desktopgui/lib/swing-worker.jar differ diff --git a/apps/desktopgui/manifest.mf b/apps/desktopgui/manifest.mf new file mode 100644 index 000000000..328e8e5bc --- /dev/null +++ b/apps/desktopgui/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/apps/desktopgui/nbproject/build-impl.xml b/apps/desktopgui/nbproject/build-impl.xml new file mode 100644 index 000000000..f8fea458d --- /dev/null +++ b/apps/desktopgui/nbproject/build-impl.xml @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/apps/desktopgui/nbproject/genfiles.properties b/apps/desktopgui/nbproject/genfiles.properties new file mode 100644 index 000000000..1b326007c --- /dev/null +++ b/apps/desktopgui/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=c4b345cd +build.xml.script.CRC32=9785bb9a +build.xml.stylesheet.CRC32=be360661 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=c4b345cd +nbproject/build-impl.xml.script.CRC32=74d3fda2 +nbproject/build-impl.xml.stylesheet.CRC32=487672f9 diff --git a/apps/desktopgui/nbproject/project.properties b/apps/desktopgui/nbproject/project.properties new file mode 100644 index 000000000..5e888e698 --- /dev/null +++ b/apps/desktopgui/nbproject/project.properties @@ -0,0 +1,68 @@ +application.desc=An anonymous communication network. +application.homepage=http://www.i2p2.de +application.title=I2P Desktop GUI +application.vendor=I2P Developers +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/desktopgui.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +file.reference.i2p.jar=../../core/java/build/i2p.jar +file.reference.router.jar=../../router/java/build/router.jar +includes=** +jar.compress=false +javac.classpath=\ + ${libs.swing-app-framework.classpath}:\ + ${file.reference.router.jar}:\ + ${file.reference.i2p.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=desktopgui.Main +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/apps/desktopgui/nbproject/project.xml b/apps/desktopgui/nbproject/project.xml new file mode 100644 index 000000000..09409a64c --- /dev/null +++ b/apps/desktopgui/nbproject/project.xml @@ -0,0 +1,19 @@ + + + org.netbeans.modules.java.j2seproject + + + desktopgui + 1.6.5 + + + + + + + + + + + + diff --git a/apps/desktopgui/src/META-INF/services/org.jdesktop.application.Application b/apps/desktopgui/src/META-INF/services/org.jdesktop.application.Application new file mode 100644 index 000000000..6cd2ac1fb --- /dev/null +++ b/apps/desktopgui/src/META-INF/services/org.jdesktop.application.Application @@ -0,0 +1 @@ +desktopgui.Main \ No newline at end of file diff --git a/apps/desktopgui/src/desktopgui/Main.java b/apps/desktopgui/src/desktopgui/Main.java new file mode 100644 index 000000000..9d9708c8d --- /dev/null +++ b/apps/desktopgui/src/desktopgui/Main.java @@ -0,0 +1,109 @@ +package desktopgui; + +/* + * Main.java + */ + + + +import gui.Tray; +import gui.SpeedSelector; +import java.awt.SystemTray; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import org.jdesktop.application.Application; +import org.jdesktop.application.SingleFrameApplication; +import persistence.PropertyManager; + +/** + * The main class of the application. + */ +public class Main extends SingleFrameApplication { + + /** + * At startup create and show the main frame of the application. + */ + @Override protected void startup() { + Properties props = PropertyManager.loadProps(); + + //First load: present screen with information (to help choose I2P settings) + if(props.getProperty(FIRSTLOAD).equals("true")) { + props.setProperty(FIRSTLOAD, "false"); + PropertyManager.saveProps(props); + new SpeedSelector(); //Start speed selector GUI + } + + if(SystemTray.isSupported()) { + tray = new Tray(); + } + else { //Alternative if SystemTray is not supported on the platform + } + } + + /** + * This method is to initialize the specified window by injecting resources. + * Windows shown in our application come fully initialized from the GUI + * builder, so this additional configuration is not needed. + */ + @Override protected void configureWindow(java.awt.Window root) { + } + + /** + * A convenient static getter for the application instance. + * @return the instance of Main + */ + public static Main getApplication() { + return Application.getInstance(Main.class); + } + + /** + * Main method launching the application. + */ + public static void main(String[] args) { + System.setProperty("java.awt.headless", "false"); //Make sure I2P is running in GUI mode for our application + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } catch (UnsupportedLookAndFeelException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + + Main main = getApplication(); + main.launchForeverLoop(); + main.startup(); + } + + /** + * Avoids the app terminating because no Window is opened anymore. + * More info: http://java.sun.com/javase/6/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown + */ + public void launchForeverLoop() { + Runnable r = new Runnable() { + public void run() { + try { + Object o = new Object(); + synchronized (o) { + o.wait(); + } + } catch (InterruptedException ie) { + } + } + }; + Thread t = new Thread(r); + t.setDaemon(false); + t.start(); + } + + private Tray tray = null; + ///Indicates if this is the first time the application loads + ///(is only true at the very start of loading the first time!) + private static final String FIRSTLOAD = "firstLoad"; +} diff --git a/apps/desktopgui/src/desktopgui/resources/Main.properties b/apps/desktopgui/src/desktopgui/resources/Main.properties new file mode 100644 index 000000000..f79fe9a00 --- /dev/null +++ b/apps/desktopgui/src/desktopgui/resources/Main.properties @@ -0,0 +1,11 @@ +# Application global resources + +Application.name = desktopgui +Application.title = I2P Desktop GUI +Application.version = 0.7.1 +Application.vendor = I2P Developers +Application.homepage = http://www.i2p2.de +Application.description = An anonymous communication network. +Application.vendorId = I2P +Application.id = ${Application.name} +Application.lookAndFeel = system diff --git a/apps/desktopgui/src/gui/SpeedSelector.form b/apps/desktopgui/src/gui/SpeedSelector.form new file mode 100644 index 000000000..b256265de --- /dev/null +++ b/apps/desktopgui/src/gui/SpeedSelector.form @@ -0,0 +1,160 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/apps/desktopgui/src/gui/SpeedSelector.java b/apps/desktopgui/src/gui/SpeedSelector.java new file mode 100644 index 000000000..19f487534 --- /dev/null +++ b/apps/desktopgui/src/gui/SpeedSelector.java @@ -0,0 +1,176 @@ +/* + * ProfileSelector.java + * + * Created on 3 april 2009, 13:57 + */ + +package gui; + +import java.awt.Dimension; +import java.awt.Point; +import java.util.Properties; +import javax.swing.JTextField; +import persistence.PropertyManager; +import util.IntegerVerifier; + +/** + * + * @author mathias + */ +public class SpeedSelector extends javax.swing.JFrame { + + /** Creates new form ProfileSelector */ + public SpeedSelector() { + this.props = PropertyManager.getProps(); + initComponents(); + initComponentsCustom(); + initSpeeds(props); + this.setVisible(true); + } + + public SpeedSelector(Point point, Dimension dimension) { + this(); + this.setLocation(point); + this.setSize(dimension); + } + + public void initComponentsCustom() { + ((JTextField)uploadChoice.getEditor().getEditorComponent()).setInputVerifier(new IntegerVerifier()); + ((JTextField)downloadChoice.getEditor().getEditorComponent()).setInputVerifier(new IntegerVerifier()); + } + + /** 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() { + + nextButton = new javax.swing.JButton(); + uploadLabel = new javax.swing.JLabel(); + downloadLabel = new javax.swing.JLabel(); + uploadChoice = new javax.swing.JComboBox(); + downloadChoice = new javax.swing.JComboBox(); + kbps1 = new javax.swing.JLabel(); + kbps2 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(SpeedSelector.class); + setTitle(resourceMap.getString("Form.title")); // NOI18N + setName("Form"); // NOI18N + + nextButton.setText(resourceMap.getString("nextButton.text")); // NOI18N + nextButton.setName("nextButton"); // NOI18N + nextButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + nextButtonMouseClicked(evt); + } + }); + + uploadLabel.setText(resourceMap.getString("uploadLabel.text")); // NOI18N + uploadLabel.setName("uploadLabel"); // NOI18N + + downloadLabel.setText(resourceMap.getString("downloadLabel.text")); // NOI18N + downloadLabel.setName("downloadLabel"); // NOI18N + + uploadChoice.setEditable(true); + uploadChoice.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "100", "200", "500", "1000", "2000", "4000", "8000", "10000", "20000", "50000", "100000" })); + uploadChoice.setSelectedIndex(3); + uploadChoice.setName("uploadChoice"); // NOI18N + + downloadChoice.setEditable(true); + downloadChoice.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "100", "200", "500", "1000", "2000", "4000", "8000", "10000", "20000", "50000", "100000" })); + downloadChoice.setSelectedIndex(3); + downloadChoice.setName("downloadChoice"); // NOI18N + + kbps1.setText(resourceMap.getString("kbps1.text")); // NOI18N + kbps1.setName("kbps1"); // NOI18N + + kbps2.setText(resourceMap.getString("kbps2.text")); // NOI18N + kbps2.setName("kbps2"); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(49, 49, 49) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(downloadLabel) + .addComponent(uploadLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(downloadChoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(kbps2)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(layout.createSequentialGroup() + .addComponent(uploadChoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(kbps1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(nextButton) + .addGap(34, 34, 34)))) + .addGap(40, 40, 40)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(67, 67, 67) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(uploadLabel) + .addComponent(uploadChoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(kbps1)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(downloadLabel) + .addComponent(downloadChoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(kbps2)) + .addContainerGap(173, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(271, Short.MAX_VALUE) + .addComponent(nextButton) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + +private void nextButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_nextButtonMouseClicked + props.setProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE, uploadChoice.getSelectedItem().toString()); + props.setProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE, downloadChoice.getSelectedItem().toString()); + PropertyManager.saveProps(props); + new SpeedSelector2(this.getLocationOnScreen(), this.getSize()); + this.dispose(); +}//GEN-LAST:event_nextButtonMouseClicked + +private void initSpeeds(Properties props) { + String up = props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE); + String down = props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE); + + if(up == null) + props.setProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE, "1000"); + if(down == null) + props.setProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE, "1000"); + + uploadChoice.setSelectedItem(props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE)); + downloadChoice.setSelectedItem(props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE)); +} + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox downloadChoice; + private javax.swing.JLabel downloadLabel; + private javax.swing.JLabel kbps1; + private javax.swing.JLabel kbps2; + private javax.swing.JButton nextButton; + private javax.swing.JComboBox uploadChoice; + private javax.swing.JLabel uploadLabel; + // End of variables declaration//GEN-END:variables + + Properties props; +} diff --git a/apps/desktopgui/src/gui/SpeedSelector2.form b/apps/desktopgui/src/gui/SpeedSelector2.form new file mode 100644 index 000000000..2f0abc786 --- /dev/null +++ b/apps/desktopgui/src/gui/SpeedSelector2.form @@ -0,0 +1,116 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/apps/desktopgui/src/gui/SpeedSelector2.java b/apps/desktopgui/src/gui/SpeedSelector2.java new file mode 100644 index 000000000..a02ef9b53 --- /dev/null +++ b/apps/desktopgui/src/gui/SpeedSelector2.java @@ -0,0 +1,174 @@ +/* + * ProfileSelector2.java + * + * Created on 3 april 2009, 14:36 + */ + +package gui; + +import java.awt.Dimension; +import java.awt.Point; +import java.util.Enumeration; +import java.util.Properties; +import javax.swing.AbstractButton; +import persistence.PropertyManager; + +/** + * + * @author mathias + */ +public class SpeedSelector2 extends javax.swing.JFrame { + Properties props; + + /** Creates new form ProfileSelector2 */ + public SpeedSelector2(Point point, Dimension dimension) { + this.props = PropertyManager.getProps(); + initComponents(); + this.setLocation(point); + this.setSize(dimension); + loadButtonSelection(); + this.setVisible(true); + } + + /** 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() { + + buttonGroup1 = new javax.swing.ButtonGroup(); + nextButton = new javax.swing.JButton(); + returnButton = new javax.swing.JButton(); + questionLabel = new javax.swing.JLabel(); + browseButton = new javax.swing.JRadioButton(); + downloadButton = new javax.swing.JRadioButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(SpeedSelector2.class); + setTitle(resourceMap.getString("Form.title")); // NOI18N + setName("Form"); // NOI18N + + nextButton.setText(resourceMap.getString("nextButton.text")); // NOI18N + nextButton.setName("nextButton"); // NOI18N + nextButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + nextButtonMouseClicked(evt); + } + }); + + returnButton.setText(resourceMap.getString("returnButton.text")); // NOI18N + returnButton.setName("returnButton"); // NOI18N + returnButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + returnButtonMouseClicked(evt); + } + }); + + questionLabel.setText(resourceMap.getString("questionLabel.text")); // NOI18N + questionLabel.setName("questionLabel"); // NOI18N + + buttonGroup1.add(browseButton); + browseButton.setText(resourceMap.getString("browseButton.text")); // NOI18N + browseButton.setName("browseButton"); // NOI18N + + buttonGroup1.add(downloadButton); + downloadButton.setText(resourceMap.getString("downloadButton.text")); // NOI18N + downloadButton.setName("downloadButton"); // 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(406, Short.MAX_VALUE) + .addComponent(returnButton) + .addGap(18, 18, 18) + .addComponent(nextButton) + .addGap(74, 74, 74)) + .addGroup(layout.createSequentialGroup() + .addGap(42, 42, 42) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(questionLabel) + .addGroup(layout.createSequentialGroup() + .addGap(12, 12, 12) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(downloadButton) + .addComponent(browseButton)))) + .addContainerGap(32, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(54, 54, 54) + .addComponent(questionLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(browseButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(downloadButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 120, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(nextButton) + .addComponent(returnButton)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + +private void returnButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_returnButtonMouseClicked + saveButtonSelection(); + PropertyManager.saveProps(props); + new SpeedSelector(this.getLocationOnScreen(), this.getSize()).setVisible(true); + this.dispose(); +}//GEN-LAST:event_returnButtonMouseClicked + +private void nextButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_nextButtonMouseClicked + saveButtonSelection(); + PropertyManager.saveProps(props); + new SpeedSelector3(this.getLocationOnScreen(), this.getSize()).setVisible(true); + this.dispose(); +}//GEN-LAST:event_nextButtonMouseClicked + +private void loadButtonSelection() { + Enumeration elements = buttonGroup1.getElements(); + while(elements.hasMoreElements()) { + AbstractButton button = elements.nextElement(); + if(button == null) + continue; + if(props.getProperty(SpeedSelectorConstants.USERTYPE) == null) + break; + String type = button.getText().split(":")[0]; + if(type.equals(props.getProperty(SpeedSelectorConstants.USERTYPE))) { + button.setSelected(true); + break; + } + } +} + +private void saveButtonSelection() { + Enumeration elements = buttonGroup1.getElements(); + while(elements.hasMoreElements()) { + AbstractButton button = elements.nextElement(); + if(button == null) + continue; + if(button.isSelected()) { + String type = button.getText().split(":")[0]; + props.setProperty(SpeedSelectorConstants.USERTYPE, type); + break; + } + } +} + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JRadioButton browseButton; + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.JRadioButton downloadButton; + private javax.swing.JButton nextButton; + private javax.swing.JLabel questionLabel; + private javax.swing.JButton returnButton; + // End of variables declaration//GEN-END:variables + +} diff --git a/apps/desktopgui/src/gui/SpeedSelector3.form b/apps/desktopgui/src/gui/SpeedSelector3.form new file mode 100644 index 000000000..419a22fc1 --- /dev/null +++ b/apps/desktopgui/src/gui/SpeedSelector3.form @@ -0,0 +1,223 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/apps/desktopgui/src/gui/SpeedSelector3.java b/apps/desktopgui/src/gui/SpeedSelector3.java new file mode 100644 index 000000000..e226f7422 --- /dev/null +++ b/apps/desktopgui/src/gui/SpeedSelector3.java @@ -0,0 +1,286 @@ +/* + * ProfileSelector3.java + * + * Created on 3 april 2009, 15:17 + */ + +package gui; + +import java.awt.Dimension; +import java.awt.Point; +import java.util.Properties; +import persistence.PropertyManager; +import router.configuration.SpeedHandler; +import router.configuration.SpeedHelper; + +/** + * + * @author mathias + */ +public class SpeedSelector3 extends javax.swing.JFrame { + Properties props; + + /** Creates new form ProfileSelector3 */ + public SpeedSelector3(Point point, Dimension dimension) { + this.props = PropertyManager.getProps(); + initComponents(); + this.setLocation(point); + this.setSize(dimension); + initSpeeds(); + this.setVisible(true); + } + + /** 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() { + + finishButton = new javax.swing.JButton(); + previousButton = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + uploadLabel = new javax.swing.JLabel(); + downloadLabel = new javax.swing.JLabel(); + uploadBurstLabel = new javax.swing.JLabel(); + downloadBurstLabel = new javax.swing.JLabel(); + uploadUsageLabel = new javax.swing.JLabel(); + downloadUsageLabel = new javax.swing.JLabel(); + uploadField = new javax.swing.JTextField(); + uploadBurstField = new javax.swing.JTextField(); + downloadField = new javax.swing.JTextField(); + downloadBurstField = new javax.swing.JTextField(); + uploadMonth = new javax.swing.JLabel(); + downloadMonth = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(SpeedSelector3.class); + setTitle(resourceMap.getString("Form.title")); // NOI18N + setName("Form"); // NOI18N + + finishButton.setText(resourceMap.getString("finishButton.text")); // NOI18N + finishButton.setName("finishButton"); // NOI18N + finishButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + finishButtonMouseClicked(evt); + } + }); + + previousButton.setText(resourceMap.getString("previousButton.text")); // NOI18N + previousButton.setName("previousButton"); // NOI18N + previousButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + previousButtonMouseClicked(evt); + } + }); + + jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N + jLabel1.setName("jLabel1"); // NOI18N + + uploadLabel.setText(resourceMap.getString("uploadLabel.text")); // NOI18N + uploadLabel.setName("uploadLabel"); // NOI18N + + downloadLabel.setText(resourceMap.getString("downloadLabel.text")); // NOI18N + downloadLabel.setName("downloadLabel"); // NOI18N + + uploadBurstLabel.setText(resourceMap.getString("uploadBurstLabel.text")); // NOI18N + uploadBurstLabel.setName("uploadBurstLabel"); // NOI18N + + downloadBurstLabel.setText(resourceMap.getString("downloadBurstLabel.text")); // NOI18N + downloadBurstLabel.setName("downloadBurstLabel"); // NOI18N + + uploadUsageLabel.setText(resourceMap.getString("uploadUsageLabel.text")); // NOI18N + uploadUsageLabel.setName("uploadUsageLabel"); // NOI18N + + downloadUsageLabel.setText(resourceMap.getString("downloadUsageLabel.text")); // NOI18N + downloadUsageLabel.setName("downloadUsageLabel"); // NOI18N + + uploadField.setText(resourceMap.getString("uploadField.text")); // NOI18N + uploadField.setMinimumSize(new java.awt.Dimension(77, 27)); + uploadField.setName("uploadField"); // NOI18N + uploadField.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + speedFieldKeyReleased(evt); + } + }); + + uploadBurstField.setText(resourceMap.getString("uploadBurstField.text")); // NOI18N + uploadBurstField.setMinimumSize(new java.awt.Dimension(77, 27)); + uploadBurstField.setName("uploadBurstField"); // NOI18N + + downloadField.setText(resourceMap.getString("downloadField.text")); // NOI18N + downloadField.setMinimumSize(new java.awt.Dimension(77, 27)); + downloadField.setName("downloadField"); // NOI18N + downloadField.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + speedFieldKeyReleased(evt); + } + }); + + downloadBurstField.setText(resourceMap.getString("downloadBurstField.text")); // NOI18N + downloadBurstField.setMinimumSize(new java.awt.Dimension(77, 27)); + downloadBurstField.setName("downloadBurstField"); // NOI18N + + uploadMonth.setText(resourceMap.getString("uploadMonth.text")); // NOI18N + uploadMonth.setName("uploadMonth"); // NOI18N + + downloadMonth.setText(resourceMap.getString("downloadMonth.text")); // NOI18N + downloadMonth.setName("downloadMonth"); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel1) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(uploadLabel) + .addComponent(uploadBurstLabel) + .addComponent(uploadUsageLabel)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(uploadBurstField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(uploadField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(uploadMonth, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(46, 46, 46) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(downloadLabel) + .addComponent(downloadBurstLabel) + .addComponent(downloadUsageLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(downloadField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(downloadMonth, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(downloadBurstField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGap(18, 18, 18)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(previousButton) + .addGap(18, 18, 18) + .addComponent(finishButton) + .addGap(33, 33, 33))) + .addGap(400, 400, 400)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(81, 81, 81) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(uploadLabel) + .addComponent(downloadLabel) + .addComponent(uploadField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(downloadField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(uploadBurstLabel) + .addComponent(downloadBurstLabel) + .addComponent(downloadBurstField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(uploadBurstField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(uploadUsageLabel) + .addComponent(downloadUsageLabel) + .addComponent(uploadMonth) + .addComponent(downloadMonth)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 48, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(previousButton) + .addComponent(finishButton)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + +private void previousButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_previousButtonMouseClicked + saveSpeeds(); + PropertyManager.saveProps(props); + new SpeedSelector2(this.getLocationOnScreen(), this.getSize()).setVisible(true); + this.dispose(); +}//GEN-LAST:event_previousButtonMouseClicked + +private void finishButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_finishButtonMouseClicked + saveSpeeds(); + PropertyManager.saveProps(props); + + int maxDownload = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXDOWNLOAD)); + int maxUpload = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXUPLOAD)); + int maxUploadBurst = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXUPLOADBURST)); + int maxDownloadBurst = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXDOWNLOADBURST)); + + //Working in kB, not kb! + SpeedHandler.setInboundBandwidth(maxDownload/8); + SpeedHandler.setOutboundBandwidth(maxUpload/8); + SpeedHandler.setInboundBurstBandwidth(maxDownloadBurst); + SpeedHandler.setOutboundBurstBandwidth(maxUploadBurst/8); + + this.dispose(); +}//GEN-LAST:event_finishButtonMouseClicked + +private void speedFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_speedFieldKeyReleased + try { + initUsage(uploadField.getText(), downloadField.getText()); + } + catch(NumberFormatException e) { + return; + } +}//GEN-LAST:event_speedFieldKeyReleased + + protected void initSpeeds() { + String up = "" + SpeedHelper.calculateSpeed( + props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE)); + String upBurst = "" + SpeedHelper.calculateSpeed( + props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE)); + String down = "" + SpeedHelper.calculateSpeed( + props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE)); + String downBurst = "" + SpeedHelper.calculateSpeed( + props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE)); + String userType = props.getProperty(SpeedSelectorConstants.USERTYPE); + + uploadField.setText(up); + uploadBurstField.setText(upBurst); + downloadField.setText(down); + downloadBurstField.setText(downBurst); + + initUsage(up, down); + } + + protected void saveSpeeds() { + props.setProperty(SpeedSelectorConstants.MAXUPLOAD, uploadField.getText()); + props.setProperty(SpeedSelectorConstants.MAXUPLOADBURST, uploadBurstField.getText()); + props.setProperty(SpeedSelectorConstants.MAXDOWNLOAD, downloadField.getText()); + props.setProperty(SpeedSelectorConstants.MAXDOWNLOADBURST, downloadBurstField.getText()); + } + + protected void initUsage(String upload, String download) { + uploadMonth.setText(SpeedHelper.calculateMonthlyUsage(Integer.parseInt(upload)/8) + " GB"); + downloadMonth.setText(SpeedHelper.calculateMonthlyUsage(Integer.parseInt(download)/8) + " GB"); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTextField downloadBurstField; + private javax.swing.JLabel downloadBurstLabel; + private javax.swing.JTextField downloadField; + private javax.swing.JLabel downloadLabel; + private javax.swing.JLabel downloadMonth; + private javax.swing.JLabel downloadUsageLabel; + private javax.swing.JButton finishButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JButton previousButton; + private javax.swing.JTextField uploadBurstField; + private javax.swing.JLabel uploadBurstLabel; + private javax.swing.JTextField uploadField; + private javax.swing.JLabel uploadLabel; + private javax.swing.JLabel uploadMonth; + private javax.swing.JLabel uploadUsageLabel; + // End of variables declaration//GEN-END:variables + +} diff --git a/apps/desktopgui/src/gui/SpeedSelectorConstants.java b/apps/desktopgui/src/gui/SpeedSelectorConstants.java new file mode 100644 index 000000000..ea5e32427 --- /dev/null +++ b/apps/desktopgui/src/gui/SpeedSelectorConstants.java @@ -0,0 +1,25 @@ +package gui; + +/** + * + * @author mathias + */ +public class SpeedSelectorConstants { + ///Maximum upload speed for the internet connection + public static final String MAXUPLOADCAPABLE = "maxUploadCapable"; + ///Maximum download speed for the internet connection + public static final String MAXDOWNLOADCAPABLE = "maxDownloadCapable"; + + //User profile type: what behaviour does this user have while using IP2? + public static final String USERTYPE = "userType"; + + //Maximum upload speed for I2P + public static final String MAXUPLOAD = "maxUpload"; + //Maximum upload burst speed for I2P + public static final String MAXUPLOADBURST = "maxUploadBurst"; + + //Maximum download speed for I2P + public static final String MAXDOWNLOAD = "maxDownload"; + //Maximum download burst speed for I2P + public static final String MAXDOWNLOADBURST = "maxDownloadBurst"; +} diff --git a/apps/desktopgui/src/gui/Tray.java b/apps/desktopgui/src/gui/Tray.java new file mode 100644 index 000000000..6ed5ea0d4 --- /dev/null +++ b/apps/desktopgui/src/gui/Tray.java @@ -0,0 +1,138 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package gui; + +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; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.logging.Level; +import java.util.logging.Logger; +import router.RouterHandler; + +/** + * + * @author mathias + */ +public class Tray { + + public Tray() { + tray = SystemTray.getSystemTray(); + loadSystemTray(); + } + + private void loadSystemTray() { + + Image image = Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo.jpg"); + + PopupMenu popup = new PopupMenu(); + + //Create menu items to put in the popup menu + MenuItem browserLauncher = new MenuItem("Launch browser"); + browserLauncher.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent arg0) { + if(Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI("http://localhost:7657")); + } catch (URISyntaxException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } catch(IOException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + }); + MenuItem howto = new MenuItem("How to use I2P"); + howto.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent arg0) { + if(Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + try { + File f = new File("desktopgui/resources/howto/howto.html"); + desktop.browse(new URI("file://" + f.getAbsolutePath())); + } catch (URISyntaxException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } catch(IOException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + }); + Menu config = new Menu("Configuration"); + MenuItem speedConfig = new MenuItem("Speed"); + speedConfig.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent arg0) { + (new SpeedSelector()).setVisible(true); + } + + }); + MenuItem advancedConfig = new MenuItem("Advanced Configuration"); + advancedConfig.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent arg0) { + if(Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI("http://localhost:7657/config.jsp")); + } catch (URISyntaxException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } catch(IOException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + }); + MenuItem shutdown = new MenuItem("Shutdown I2P"); + shutdown.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent arg0) { + RouterHandler.setStatus(RouterHandler.SHUTDOWN_GRACEFULLY); + } + + }); + + //Add menu items to popup menu + popup.add(browserLauncher); + popup.add(howto); + + config.add(speedConfig); + config.add(advancedConfig); + popup.add(config); + + popup.add(shutdown); + + //Add tray icon + trayIcon = new TrayIcon(image, "I2P: the anonymous network", popup); + try { + tray.add(trayIcon); + } catch (AWTException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private SystemTray tray = null; + private TrayIcon trayIcon = null; + +} diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector.properties b/apps/desktopgui/src/gui/resources/SpeedSelector.properties new file mode 100644 index 000000000..1a476d874 --- /dev/null +++ b/apps/desktopgui/src/gui/resources/SpeedSelector.properties @@ -0,0 +1,7 @@ + +Form.title=I2P Configuration +nextButton.text=Next +uploadLabel.text=What is your maximum upload speed? +downloadLabel.text=What is your maximum download speed? +kbps1.text=kbit/second +kbps2.text=kbit/second diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector2.properties b/apps/desktopgui/src/gui/resources/SpeedSelector2.properties new file mode 100644 index 000000000..704d9909e --- /dev/null +++ b/apps/desktopgui/src/gui/resources/SpeedSelector2.properties @@ -0,0 +1,6 @@ +returnButton.text=Previous +Form.title=I2P Configuration +questionLabel.text=Which of these descriptions fits you best? +browseButton.text=Browsing: I want to use I2P to browse websites anonymously, no heavy usage. +downloadButton.text=Downloading: I want to use I2P for downloads and filesharing, heavy usage. +nextButton.text=Next diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector3.properties b/apps/desktopgui/src/gui/resources/SpeedSelector3.properties new file mode 100644 index 000000000..49ee18ba0 --- /dev/null +++ b/apps/desktopgui/src/gui/resources/SpeedSelector3.properties @@ -0,0 +1,16 @@ +Form.title=I2P Configuration +jLabel1.text=The profile information your entered, indicates that these are your optimal settings: +previousButton.text=Previous +finishButton.text=Finish +uploadLabel.text=Upload Speed: +uploadBurstLabel.text=Burst Upload Speed: +downloadLabel.text=Download Speed: +downloadBurstLabel.text=Burst Download Speed: +uploadUsageLabel.text=Monthy upload usage: +downloadUsageLabel.text=Monthy Download Usage: +uploadField.text=jTextField1 +uploadBurstField.text=jTextField2 +uploadMonth.text=jLabel8 +downloadMonth.text=jLabel9 +downloadField.text=jTextField4 +downloadBurstField.text=jTextField5 diff --git a/apps/desktopgui/src/persistence/PropertyManager.java b/apps/desktopgui/src/persistence/PropertyManager.java new file mode 100644 index 000000000..bacbf348a --- /dev/null +++ b/apps/desktopgui/src/persistence/PropertyManager.java @@ -0,0 +1,72 @@ +package persistence; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author mathias + */ +public class PropertyManager { + + public static void setProps(Properties props) { + PropertyManager.props = props; + } + + public static Properties getProps() { + return props; + } + + public static Properties loadProps() { + Properties defaultProps = new Properties(); + defaultProps.setProperty("firstLoad", "true"); + + // create application properties with default + Properties applicationProps = new Properties(defaultProps); + + // now load properties from last invocation + FileInputStream in; + try { + in = new FileInputStream(PROPSLOCATION); + applicationProps.load(in); + in.close(); + } catch (FileNotFoundException ex) { + //Nothing serious, just means it's being loaded for the first time. + } catch(IOException ex) { + Logger.getLogger(PropertyManager.class.getName()).log(Level.INFO, null, ex); + } + props = applicationProps; + return applicationProps; + } + + public static void saveProps(Properties props) { + FileOutputStream out; + try { + File d = new File(PROPSDIRECTORY); + if(!d.exists()) + d.mkdir(); + File f = new File(PROPSLOCATION); + if(!f.exists()) + f.createNewFile(); + out = new FileOutputStream(f); + props.store(out, PROPSLOCATION); + } catch (FileNotFoundException ex) { + Logger.getLogger(PropertyManager.class.getName()).log(Level.SEVERE, null, ex); + } catch(IOException ex) { + Logger.getLogger(PropertyManager.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private static Properties props; + + ///Location where we store the Application Properties + public static final String PROPSDIRECTORY = "desktopgui"; + public static final String PROPSFILENAME = "appProperties"; + public static final String PROPSLOCATION = PROPSDIRECTORY + File.separator + PROPSFILENAME; +} diff --git a/apps/desktopgui/src/router/RouterHandler.java b/apps/desktopgui/src/router/RouterHandler.java new file mode 100644 index 000000000..0752f877b --- /dev/null +++ b/apps/desktopgui/src/router/RouterHandler.java @@ -0,0 +1,38 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package router; + +import java.util.logging.Level; +import java.util.logging.Logger; +import net.i2p.router.RouterContext; + +/** + * + * @author mathias + */ +public class RouterHandler { + public static final int SHUTDOWN_GRACEFULLY = 0; + public static void setStatus(int status) { + if(status == SHUTDOWN_GRACEFULLY) { + Thread t = new Thread(new Runnable() { + + public void run() { + RouterContext context = RouterHelper.getContext(); + context.router().shutdownGracefully(); + while(context.router().getShutdownTimeRemaining()>0) + try { + Thread.sleep(context.router().getShutdownTimeRemaining()); + } catch (InterruptedException ex) { + Logger.getLogger(RouterHandler.class.getName()).log(Level.SEVERE, null, ex); + } + System.exit(0); + } + + }); + t.start(); + } + } +} diff --git a/apps/desktopgui/src/router/RouterHelper.java b/apps/desktopgui/src/router/RouterHelper.java new file mode 100644 index 000000000..c5fc78e95 --- /dev/null +++ b/apps/desktopgui/src/router/RouterHelper.java @@ -0,0 +1,13 @@ +package router; + +import net.i2p.router.RouterContext; + +/** + * + * @author mathias + */ +public class RouterHelper { + public static RouterContext getContext() { + return (RouterContext) RouterContext.listContexts().get(0); + } +} diff --git a/apps/desktopgui/src/router/configuration/SpeedHandler.java b/apps/desktopgui/src/router/configuration/SpeedHandler.java new file mode 100644 index 000000000..235790792 --- /dev/null +++ b/apps/desktopgui/src/router/configuration/SpeedHandler.java @@ -0,0 +1,34 @@ +package router.configuration; + +import net.i2p.router.RouterContext; +import net.i2p.router.transport.FIFOBandwidthRefiller; +import router.RouterHelper; + +/** + * + * @author mathias + */ +public class SpeedHandler { + + public static void setInboundBandwidth(int kbytes) { + context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_INBOUND_BANDWIDTH, "" + kbytes); + context.router().saveConfig(); + } + + public static void setOutboundBandwidth(int kbytes) { + context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_OUTBOUND_BANDWIDTH, "" + kbytes); + context.router().saveConfig(); + } + + public static void setInboundBurstBandwidth(int kbytes) { + context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_INBOUND_BURST_BANDWIDTH, "" + kbytes); + context.router().saveConfig(); + } + + public static void setOutboundBurstBandwidth(int kbytes) { + context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_OUTBOUND_BURST_BANDWIDTH, "" + kbytes); + context.router().saveConfig(); + } + + private static final RouterContext context = RouterHelper.getContext(); +} diff --git a/apps/desktopgui/src/router/configuration/SpeedHelper.java b/apps/desktopgui/src/router/configuration/SpeedHelper.java new file mode 100644 index 000000000..1cce2f9c0 --- /dev/null +++ b/apps/desktopgui/src/router/configuration/SpeedHelper.java @@ -0,0 +1,28 @@ +package router.configuration; + +/** + * + * @author mathias + */ +public class SpeedHelper { + public static final String USERTYPE_BROWSING = "Browsing"; + public static final String USERTYPE_DOWNLOADING = "Downloading"; + + public static int calculateSpeed(String capable, String profile) { + int capableSpeed = Integer.parseInt(capable); + int advisedSpeed = capableSpeed; + if(capableSpeed > 1000) { + if(profile.equals(USERTYPE_BROWSING)) //Don't overdo usage for people just wanting to browse (we don't want to drive them away due to resource hogging) + advisedSpeed *= 0.6; + else if(profile.equals(USERTYPE_DOWNLOADING)) + advisedSpeed *= 0.8; + } + else + advisedSpeed *= 0.6; //Lower available bandwidth: don't hog all the bandwidth + return advisedSpeed; + } + + public static int calculateMonthlyUsage(int kbytes) { + return (kbytes*3600*24*31)/1000000; + } +} diff --git a/apps/desktopgui/src/util/IntegerVerifier.java b/apps/desktopgui/src/util/IntegerVerifier.java new file mode 100644 index 000000000..74f87961d --- /dev/null +++ b/apps/desktopgui/src/util/IntegerVerifier.java @@ -0,0 +1,32 @@ +package util; + +import javax.swing.InputVerifier; +import javax.swing.JComponent; +import javax.swing.JTextField; + +/** + * + * @author mathias + */ + +public class IntegerVerifier extends InputVerifier { + + @Override + public boolean verify(JComponent arg0) { + JTextField jtf = (JTextField) arg0; + return verify(jtf.getText()); + } + + @Override + public boolean shouldYieldFocus(JComponent input) { + return verify(input); + } + + public static boolean verify(String s) { + for(int i=0;i '9' || s.charAt(i) < '0') + return false; + return true; + } + +} \ No newline at end of file diff --git a/build.xml b/build.xml index ef84b2aab..26254cd15 100644 --- a/build.xml +++ b/build.xml @@ -37,6 +37,7 @@ + @@ -104,6 +105,7 @@ + @@ -214,6 +216,13 @@ + + + + + + + diff --git a/installer/resources/wrapper.config b/installer/resources/wrapper.config index 4d09ba12c..42958ba77 100644 --- a/installer/resources/wrapper.config +++ b/installer/resources/wrapper.config @@ -54,6 +54,10 @@ wrapper.java.classpath.17=lib/systray.jar wrapper.java.classpath.18=lib/systray4j.jar # BOB wrapper.java.classpath.19=lib/BOB.jar +# desktopgui +wrapper.java.classpath.20=lib/appframework.jar +wrapper.java.classpath.21=lib/swing-worker.jar +wrapper.java.classpath.22=lib/desktopgui.jar # Java Library Path (location of Wrapper.DLL or libwrapper.so) wrapper.java.library.path.1=.