From 495558a949b47931516b9ab2cda542cc2aa22b71 Mon Sep 17 00:00:00 2001 From: mathiasdm Date: Mon, 6 Apr 2009 17:53:32 +0000 Subject: [PATCH] New application for I2P: desktopgui. Should eventually replace systray, and have more functionality. To use the application, you need to (by default) add the following to clients.config : # desktopgui clientApp.6.args= clientApp.6.delay=5 clientApp.6.main=desktopgui.Main clientApp.6.name=desktopgui clientApp.6.startOnLoad=true --- apps/desktopgui/LICENSE | 15 + apps/desktopgui/build.xml | 69 ++ .../desktopgui/resources/howto/howto.html | 261 ++++++++ .../desktopgui/resources/logo/logo.jpg | Bin 0 -> 1105 bytes apps/desktopgui/lib/appframework.jar | Bin 0 -> 264341 bytes apps/desktopgui/lib/swing-worker.jar | Bin 0 -> 11103 bytes apps/desktopgui/manifest.mf | 3 + apps/desktopgui/nbproject/build-impl.xml | 629 ++++++++++++++++++ apps/desktopgui/nbproject/genfiles.properties | 8 + apps/desktopgui/nbproject/project.properties | 68 ++ apps/desktopgui/nbproject/project.xml | 19 + .../org.jdesktop.application.Application | 1 + apps/desktopgui/src/desktopgui/Main.java | 109 +++ .../src/desktopgui/resources/Main.properties | 11 + apps/desktopgui/src/gui/SpeedSelector.form | 160 +++++ apps/desktopgui/src/gui/SpeedSelector.java | 176 +++++ apps/desktopgui/src/gui/SpeedSelector2.form | 116 ++++ apps/desktopgui/src/gui/SpeedSelector2.java | 174 +++++ apps/desktopgui/src/gui/SpeedSelector3.form | 223 +++++++ apps/desktopgui/src/gui/SpeedSelector3.java | 286 ++++++++ .../src/gui/SpeedSelectorConstants.java | 25 + apps/desktopgui/src/gui/Tray.java | 138 ++++ .../gui/resources/SpeedSelector.properties | 7 + .../gui/resources/SpeedSelector2.properties | 6 + .../gui/resources/SpeedSelector3.properties | 16 + .../src/persistence/PropertyManager.java | 72 ++ apps/desktopgui/src/router/RouterHandler.java | 38 ++ apps/desktopgui/src/router/RouterHelper.java | 13 + .../router/configuration/SpeedHandler.java | 34 + .../src/router/configuration/SpeedHelper.java | 28 + apps/desktopgui/src/util/IntegerVerifier.java | 32 + build.xml | 9 + installer/resources/wrapper.config | 4 + 33 files changed, 2750 insertions(+) create mode 100644 apps/desktopgui/LICENSE create mode 100644 apps/desktopgui/build.xml create mode 100644 apps/desktopgui/desktopgui/resources/howto/howto.html create mode 100644 apps/desktopgui/desktopgui/resources/logo/logo.jpg create mode 100644 apps/desktopgui/lib/appframework.jar create mode 100644 apps/desktopgui/lib/swing-worker.jar create mode 100644 apps/desktopgui/manifest.mf create mode 100644 apps/desktopgui/nbproject/build-impl.xml create mode 100644 apps/desktopgui/nbproject/genfiles.properties create mode 100644 apps/desktopgui/nbproject/project.properties create mode 100644 apps/desktopgui/nbproject/project.xml create mode 100644 apps/desktopgui/src/META-INF/services/org.jdesktop.application.Application create mode 100644 apps/desktopgui/src/desktopgui/Main.java create mode 100644 apps/desktopgui/src/desktopgui/resources/Main.properties create mode 100644 apps/desktopgui/src/gui/SpeedSelector.form create mode 100644 apps/desktopgui/src/gui/SpeedSelector.java create mode 100644 apps/desktopgui/src/gui/SpeedSelector2.form create mode 100644 apps/desktopgui/src/gui/SpeedSelector2.java create mode 100644 apps/desktopgui/src/gui/SpeedSelector3.form create mode 100644 apps/desktopgui/src/gui/SpeedSelector3.java create mode 100644 apps/desktopgui/src/gui/SpeedSelectorConstants.java create mode 100644 apps/desktopgui/src/gui/Tray.java create mode 100644 apps/desktopgui/src/gui/resources/SpeedSelector.properties create mode 100644 apps/desktopgui/src/gui/resources/SpeedSelector2.properties create mode 100644 apps/desktopgui/src/gui/resources/SpeedSelector3.properties create mode 100644 apps/desktopgui/src/persistence/PropertyManager.java create mode 100644 apps/desktopgui/src/router/RouterHandler.java create mode 100644 apps/desktopgui/src/router/RouterHelper.java create mode 100644 apps/desktopgui/src/router/configuration/SpeedHandler.java create mode 100644 apps/desktopgui/src/router/configuration/SpeedHelper.java create mode 100644 apps/desktopgui/src/util/IntegerVerifier.java 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 0000000000000000000000000000000000000000..f1b5ccfc8728618281387d7a4b8ed11dedb8f39e GIT binary patch literal 1105 zcmex=>Qk2%s@GP0R~1ECMHHk7A|Ip0#;@gHg+ZsMotDHVG&VD zK`|-i@QBFC(`H=0b_1wEk`ZVavQZ4I42(?7EI=t`L12h5GP5u-!z^QD5@Z%qWMDB2 z6n0cnE}Z!P76T7Z5-2LjV9(%jJ@4S+OL6n{+*w zeZ`}!kPTbTpL6Z#pQn*i<5MhNG-;+uKp1~?`89K)X0ZE^o@$*VFd^iK9DY*3rIB~;yC zQulT2#uu~87uJ@(I9?{5Z6<&6N_Op1se9TY2XkhxHr}vQZ%N<|5r5Ik2VJGN8>*=s zH0lrb^=W7GnW$Iz#rX6*Q7f6froVH)_Z_}3d+ScYwD2@*PO0q+c70rvbRaVBrC)gB z;-cwk7k|vUD6;xNMXe7@HrGEnsems98OFoKGL^?&^S#olr(Bq(!qk{wo0+*#!CI|y*HVjfcE8rFu+OmG@IB`Id#$_4rM4DV ztu}q^zcekfY*wasL+z0Z8x~A*o0uxOB=*dfZ098Y&ZJuj$E4YE-22i=y_vyc(Qn4RrJhN^RI->RA|#S$y;yfo-e~zdGuOr z=aJ8A(@nm`=6&6LHZk?aBi);Cw7XXQcp$Ut6vK_n2A7%M{#X1&2e_IZ1y>_zyj!1jd-t24JN&<~F-PI<}n)Wp-$EiplWwG1Gv|YPZ zwsC&&;4DhI^H($VoUh#acA3ZL;@0u=bG+$!p7Z3xTcg@v-}s&De0|hUR`{sBI#lKJ zslIBW)#1B;cQ3uj$-^A_<+;;~A1Uhs)?9LxX}-3-Td_6On?r;%I4`hxqu~iidCyt?OF9SKI`Y} G|2F|xQl?`7 literal 0 HcmV?d00001 diff --git a/apps/desktopgui/lib/appframework.jar b/apps/desktopgui/lib/appframework.jar new file mode 100644 index 0000000000000000000000000000000000000000..0b8ff0145f010a8e1e9bfe065704cb4ad675f761 GIT binary patch literal 264341 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

b3C#0adb5Et>9)K}}&1LqoU{fLLrP^m)I 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

+&eO1NyNTy);90KwDiffI8) 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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=.