From 75d6df7789a1047e618b42bb9ca45b7250ad7157 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 5 May 2016 13:13:44 +0000 Subject: [PATCH] DesktopGui: - Remove all static log, context, and instance fields - Make Main class a RouterApp - Remove unused ConfigurationManager class - Translate tooltip, disable tooltip on linux - Use safer exec call to start i2p - Remove all images, use itoopie - Don't start spinner thread in router context - Handle various startup errors better - Synchs, finals, javadocs, cleanups --- apps/desktopgui/build.xml | 6 +- apps/desktopgui/resources/images/logo.jpg | Bin 1105 -> 0 bytes apps/desktopgui/resources/images/logo.png | Bin 34366 -> 0 bytes .../resources/images/logo_green.jpg | Bin 1309 -> 0 bytes .../resources/images/logo_orange.jpg | Bin 1289 -> 0 bytes apps/desktopgui/resources/images/logo_red.jpg | Bin 1312 -> 0 bytes .../i2p/desktopgui/ExternalTrayManager.java | 17 +- .../i2p/desktopgui/InternalTrayManager.java | 23 ++- .../src/net/i2p/desktopgui/Main.java | 174 ++++++++++++++---- .../src/net/i2p/desktopgui/TrayManager.java | 78 ++++---- .../gui/DesktopguiConfigurationFrame.java | 13 +- .../desktopgui/i18n/DesktopguiTranslator.java | 17 +- .../i2p/desktopgui/router/RouterManager.java | 50 +---- .../desktopgui/util/ConfigurationManager.java | 103 ----------- .../net/i2p/desktopgui/util/I2PDesktop.java | 5 +- 15 files changed, 240 insertions(+), 246 deletions(-) delete mode 100644 apps/desktopgui/resources/images/logo.jpg delete mode 100644 apps/desktopgui/resources/images/logo.png delete mode 100644 apps/desktopgui/resources/images/logo_green.jpg delete mode 100644 apps/desktopgui/resources/images/logo_orange.jpg delete mode 100644 apps/desktopgui/resources/images/logo_red.jpg delete mode 100644 apps/desktopgui/src/net/i2p/desktopgui/util/ConfigurationManager.java diff --git a/apps/desktopgui/build.xml b/apps/desktopgui/build.xml index 7e25f3897..3f6256b89 100644 --- a/apps/desktopgui/build.xml +++ b/apps/desktopgui/build.xml @@ -5,7 +5,6 @@ - @@ -36,9 +35,6 @@ - - - @@ -76,6 +72,8 @@ + + diff --git a/apps/desktopgui/resources/images/logo.jpg b/apps/desktopgui/resources/images/logo.jpg deleted file mode 100644 index f1b5ccfc8728618281387d7a4b8ed11dedb8f39e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/apps/desktopgui/resources/images/logo.png b/apps/desktopgui/resources/images/logo.png deleted file mode 100644 index ad89a98643d2fd0a323a9beadd1a70f05de9d159..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34366 zcmZU3cQl;Q^Y^oBt=@YldJw%uSwfWPB}MNwN(9mEB8f<}5G^`E^j;FeDnWt}CAwWD zL|=We*6aJ8^S!XE%Ad;c>)1HPY~0e~CO)l@eR&e^fCh-V)N!B>tdzHl3z{Tm@B z{GfwxzDQG-k%5Pioe#9a{@VL*w@z{_Qk-N*8@A5l$H~zLErO^gbE{EvQ|Trnbwst_ z^30|STcnFhrtrUA^9*v^4}0PIwes*99(Wco`fEf*Cp5C|$)bwQ)I<2xncc%h5%irB z0;0UT`ypFFE&GJh=)hoAR-74uphLhG%CCHoD);X( z+gngFzh>Ywvq-OG7u+Rt@Fj6z_#^`taM`@X&UYCZ*tB<|ylb=_yV$75vDmbMl7LRv zxji$e7Y7FSu((Z;jE&8o{E+kHpDiyfc|-(n@(5*&iyObtwiBwhgV^|deR9&s4z+(u zvs(!;vwXp^4E@BHuYS67{``l9UG~e91dGX?v@5SiNuf<5&L8=x50i&DxTB13dwYL- zRPGfX;j_1xaaL&%b_eJm$Y(eEdC{`#oJZ$a40np4ee}rZtSLMxvhYn+OjJ}%CS`%r zvZ$}O_f@5L#x?d&b!+-*14ozuAcNV38prj+ZI!PZ zgDn%uT-gZy&?k)Vvc*Ge&)>c3F>(t!%4)w2^!MlC!=^`6_RszM7k0AIAtj69)=8lO zcGT5(*p-7R#bR=-t*pWdje}RIg0?N%Zvk3bdDxuQHTBmI zTX&|4_u?EMeJ%_-VVT__W>>&+2QxIk+&kR=HQaHMuXGj9!2~!tjdpx6JhQQ}yH*qx z?H~%GlmX3lDmzOTCmT|!3rP2T*>&!g@s^+{dw6iS>6?L#bWuX|ieX4{u-4UAOZnA1 zw86J#(@#TCT3lP^F9vW%=IK>KXG59FLK$)ePps8lT8Xo>hjMCbM`KKbPQ7>_@rilS zg@wFNP;)`0rMA~;N)>f2_}mJieE3R}%gOcN3w!q#4DZaG<=)qtfKXH~C2rp8hA1CCceR}?dcxcG1u1SXE-MiK&5&?SU=9Gz?-`)gX z`2T&rd3b!xCf{Bos-+~=Qe12lDVD~0@p^wW`&HIc8?j9jz***+J3c8l7QetlOejdf z&Gjd~cE|Y<(gj`; z=nR-X(2o@T{l|_W^NDOsV==l`8l!>sQa2r5WJGN=KFyF7<84fZGZ<>NvY^5_xGWx^Bwi+(_&sMOeR=+h4f8u;+CH#( z%%t)87e9r7e>|eChel>*zTx%7J(63YIRgXvSL%0DBf?uSw=d*&_br|+Mk>f23{@RG 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�ggQ-$FTw;~+cz6b)h_(TJQtfsK&76QP7C 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
  • vqr|ynS z2fu{j=kTz_D>uKtpWADP<7+fptJ0EQ(Hpn-sScofK2KhG zb4j=*!lJguP`GiJRl;VxzL$4VTlDbY0lQ)piVLR6GQ?qu~8L z%_7g0($zrV9Xa8HOn$MSl_Di?bWoP;9iu;9J0CJn%(NNx*YbF=b%x~XZzb#88BgH?Ya=Ah%UqO@MH&;c|U11(sO34d&L zoYQq6f^m92_C=)I=AEHuKF|4i?foRRUH`vOy3|kmjk>&0zPGP0b$sDh$aGs=#W-Fu z$OKkamQO#ocZ@7jI$sUpQ_g`uiE$*$knYNr{%Q!z0eoDlw`ay=mrC(mo&#|~*=Ezn z14R0>NI@zkV?6uB0V0JN%a}I~*Q|#H@XTBW*yDR~O=V-*=sH#~b!Gn6&dn zg0TO_ejnEFNlrZ+Qpthqo7Xk+)T#aFwAKa{mr#DblqV`bE>&Ui^botyVs<WXf3`awiu6#1)3>%>a+d~1dmsJNVMLaM z|7s|N`8jUXc|eM5U(ooTx`Gc&ih4mY%aKBlg9Dc16{M&2XBXjz(XCNS^x`(5>udA# zUIB$smG^r{GFFv$_w+;yWqkZgVz*YZ{_inGFwBL-cZV6pj=1^O%aJZIxN{+`dIY9! z1wwF-9$`Ac9Yb1Vxp{3bmXm&7x6k-M$|fGo_hc_1Y)M8oG%&EZnS+@)vnrg3*mlHs zoMVeg_BE`H002^iuBN)F@Fga*liu+cVL$e5^!<^bessJi^h{iAz*=PA1HO3KIdzu1 z^rr!NcPQV*8FxvUV&c0VaXsU48jiHz@;i_q_0Ma;KW9=#clDp0{dCwvx~C(fvT*R* zlz7&AxX9NJa7r$o(oiplo7_~pa-43yE00jc2d8vT7aXr&Ph}#IjZUr9tXsWNT@m!P z`t2Yj3Ed+?vB^OqH;c3qrpGD2>q z@z~Tj=gqQ4*$+o^O?EWVS!eXTk(QoSMz15Y?s4zJUkgK@G?{uz5(#IQf*!tI~ViAK6H;s2Vjb^_E-CuBXi+LcHq#+O1btWDv^x85eI} zX~HEwE%I@9&9@$ul-mY3sHFs?c$}Q0iwPYMhead-@7vqC2qqN)hsDo)t;@*8=*V;! zAJWmOIypJC)_fV_NEsIN5TgiRPzLHh;Kh8h`(TxPD>P9B63Pi~F2N&@kerZ1E zc!;OB1mDsj!|(FJzF(TZzZR)hha*>bjtvp~ZiPjxd(6fN7lmGHYO34r=IOIsd5f`Y zk|}?q)1T>o@83?b3R0=_URZ>nGkf)5e#R$uv+Y_N#CFxp;ay&(^CA1+N`|aR(aR9Y ztN6hQe=T9O9)Z(*8S-rZ>2g$K3A$#=N+Ie(uM%WSm8?cTg!EUC<~;kZehc-$+*AGH z-*a2F6XtS^k0!QsxiW2LejC>5E6H}7*=48wliG6r6nc>KqZOksAc=V)c_-`|2BfvLk@wT>}gzfF8SUa%V6&S+I z(~}IajpVQYxsM+FQ}50Z?<4TrWe@%S9s>Ukbi0c}ch4fH^Zfk}u)x287k;)<#i7=9 zpif@_82m%zihtF6+Lvtkcu0-L4z$}BG@WPWkkfQtuz*gg6suC+Nd|wNWj#LN_Y*&S zbSg&eUVj(*y@$M4-{PtBd6crY;r;M`!NUIpB$DCERQEz~q)Y!cR`%a>uG{pUVkE8F zksJ;aP9sw|g=t%k&22U&QiISoNAqa|{_3;=f7yGaa{A=JwPk|qH zP+i)=za<{B25n1T-*k+xshkZx9`yf@lK6%!1O5+TK}WWkz5sc^CM@G)M#jHa{{8z0 mx3bX>*6b1%1PN1;7AOkZ<24M-%3|2-qb|D5~5z+s*7Q1#%ae7&71Kd&1G3+cAK_qyX&Stn>*^$W*nYXdh*VHhLF2D+!J@2-{AXU$<8Jo zuW{rElxUKU~zVaZG`eB>CErR&NJd-N~g@Y%)gt#nMHl!^kQ+1GxNiv{Uh_& zt+2mj>wj^B{@;b0UQe&uw&-$G>A5ovQf)`9<}QkzvAHbrfJb1{k+SJ5Gk(c>xNZxv zdYc!xG$N;L_TKf%tBc)_zRY~({n7jOJKo(Qfy-`h$}jnl{#h!&bib_6t&2OqvM;}J zsmtK(;o~VC>s&N#T^W3O_fL*Lnwgp9`!Sa1+q1h}8dq{}hVK-3{-2@We&_wZ#kVeQ z>vF#I`lYMHvqvd1ovU2dx^#*8Oq@TZZ~LX$k$)rg7ti_n`Sq!zi?ymn{Pt~|n?KoP zjaqQpY%a}dt2Zq?R{k-B?F9FiAiIHx$L~;9bYF)rR9w z*BfQyRmW6%6SwTxGokHu)1Qm_H;-T6{`S?{KXd;xsCVwO{`8;0^!1bC?6X^aPG5@h zEd8~&rkDR!%K5dtHb-Aq{%7#_>11YNZx5gUTk`1l_vI|rM*jVKj-R!;>)ZnV*t zX_I2(mPf1o3pqJA3QLTxn55=RVK+D(vQ!V@t1Epw46ot)6a<)&Ts8GE#y|hUbJlL{OMC(1y6Yz5ysCi zvHHYMm&?4KpXDk;o=x(%YJK!jz~e4_8FZiMq3Y zrv6TQFH8Gh(gpQ*_t@A3PY;c_;5)tF`%`g>P|VDm>rxC(v7Eo*XftWjat~pNV*+cF z&&`}!K0oPw)nc<%g$w5!%e6mEJE0=<{MpV4hYbWLbEr=W3KCK|Yz9_25u~#E|4jg$ CH4?u7 diff --git a/apps/desktopgui/resources/images/logo_orange.jpg b/apps/desktopgui/resources/images/logo_orange.jpg deleted file mode 100644 index d131f21b6297f0955632ab353844db0c4a8c587f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1289 zcmex=&=E7}z)%SU7<)DuN&xCPo&xJkUlKRyH9)c3}}k22l?S$B2R}onMtWy=ggPClR|`M0IN8I0o^+neovj@k z@;$@^MMMmbGz$Ju;#Zq4yQKC^hZ}cBY-{fcBbSfYrp`D0X5N2JKE3SI$QmS2Rdv2EQ3+ieDX=RbRdMx=v1=)=`6KJN+(XA zSj^{c?td?T^S7)#eJh6_h6VB`6YtNG`d7btk2w3)vvU?+KUO%e_UVf2$$3w?3sYC6 zPBoq4IQ6a7CiYbau04ztX7f^Qe!S#svHy?n$A2>^5(@k8e$iWP9+2=;@S4wT(@-|w+hR3czFRNWem%45_$kd*lTxIPuCv(Qo>c5$ zp}L^>al-d)ar_4h{SQw1E>U`sPw-f5r^3&!op*IVx5Vo98n3%u9bqfiGr7HEdx+`d zr;OKB{}l85Y6|_eXO`VbuB6bbOMK-f*-5w*{#};-vBoa^6sP%wn8`JhYrLPUY%@s> zw>@=o)%j^VH!CLZP1W1^`$Fx64S|&r97iv@{5<_aFO4Bh*R?oZ`nusu#=TEckFvDH z?%r0F>88_`_n)DDjTPggS(?+7XPSKzx@%InxVG$2L~yG4y^p`W?>_#te~P`+?fdWM z^}8?jnQqm}^;Ki*mQ^d#M57jSZ7n@0GSlhOOx6}bL6NT#pMs6;i;aI6E)`r}di~4d oZ{lkv%>Qk2EI>Ie0R~1ECMHHkc2=l7D>DllI}-;ZCxeKPsFDNZn2dx?(kXLu(M+MI|+f31vTtzbY8_TS$m}K z#k{58Qa7@-E>zN%&R^@eV593)PdQcNm)55{OcI<{X{^$EWT<|w!dNAAy4HkDaiN@M zv3D_>eObl-I^PW0cQ{XEf7W*Hj7b}|Z@b8y-oEf1C^r1=7y(oVSXi8|D?P11V0Sv6<%v)7lG zzj*3hcXw;@kNHaf8A58^&RFX%S924)`8d=zm}$3!;lyjXkB%(W;giZ06ng2|a71KQ zOCRslV)+Ssdp8>WvI)HKZRhH@S|2C9>Ny`!?{`1)KSPFZo$I{+3<;n7;+EftGGY45 z?ff^|JCM7KZ|jX}#y&P#LqWA`K0G=+vH~tiF2;s(Y}4=UW&iNK@3l@*Y?<)$YOb$W zw%fnXnq70{Y0yT0xuaHlm2Z8ycM8H%nr2mY9@u=})-zB<0AxZGjorDwTZVF0mU(FNHth2M| zY+lg8b6yKic|V%9LrzYfEiJ>V!+1rb`sGiGD`QgQmg&f!ODt4;bx6&9eLq`J;J?ep zAN@Dq`F1UI!EV|1psz2OlO6M3n9dSkxb>pv#sa>Zyfacw^%mP_*jJrq5ueJ?;%OW6 z{(Dl%A!C)cY`ax2Wn(3$pDdp4(aPVM)4AltiK#LNyjqG1)owBS3p`hREUEZ1+QN03 zrRwaS=z^E0mrkF2Kg>V*e#V#cAFtm2*YV-Q=b(k6DY~Z50;c|K2ucfC&}lfcA)>0` z$eA-|T-;~Qod4UNp)73gT5YRpZr)t&6!vUqAGW`*)fkpCMr_ZLPCTN;5HVRINI^-^ KKv_`!|4jhMnDUMQ diff --git a/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java b/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java index 2a3a16b63..e15e5c08b 100644 --- a/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java +++ b/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java @@ -8,14 +8,21 @@ import java.awt.event.ActionListener; import javax.swing.SwingWorker; +import net.i2p.I2PAppContext; import net.i2p.desktopgui.router.RouterManager; -import net.i2p.util.Log; -public class ExternalTrayManager extends TrayManager { +/** + * When started before the router, e.g. with + * java -cp i2p.jar:desktopgui.jar net.i2p.desktopgui.Main + * + * No access to context, very limited abilities. + * Not fully supported. + */ +class ExternalTrayManager extends TrayManager { - private final static Log log = new Log(ExternalTrayManager.class); - - protected ExternalTrayManager() {} + public ExternalTrayManager(I2PAppContext ctx) { + super(ctx); + } @Override public PopupMenu getMainMenu() { diff --git a/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java b/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java index 1cb464308..90017c035 100644 --- a/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java +++ b/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java @@ -11,13 +11,24 @@ import net.i2p.desktopgui.gui.DesktopguiConfigurationFrame; import net.i2p.desktopgui.router.RouterManager; import net.i2p.desktopgui.util.BrowseException; import net.i2p.desktopgui.util.I2PDesktop; +import net.i2p.router.RouterContext; import net.i2p.util.Log; -public class InternalTrayManager extends TrayManager { +/** + * java -cp i2p.jar:desktopgui.jar net.i2p.desktopgui.Main + * + * Full access to router context. + */ +class InternalTrayManager extends TrayManager { - private final static Log log = new Log(InternalTrayManager.class); + private final RouterContext _context; + private final Log log; - protected InternalTrayManager() {} + public InternalTrayManager(RouterContext ctx) { + super(ctx); + _context = ctx; + log = ctx.logManager().getLog(InternalTrayManager.class); + } @Override public PopupMenu getMainMenu() { @@ -56,7 +67,7 @@ public class InternalTrayManager extends TrayManager { @Override protected Object doInBackground() throws Exception { - new DesktopguiConfigurationFrame().setVisible(true); + new DesktopguiConfigurationFrame(_context).setVisible(true); return null; } @@ -73,7 +84,7 @@ public class InternalTrayManager extends TrayManager { @Override protected Object doInBackground() throws Exception { - RouterManager.restart(); + RouterManager.restart(_context); return null; } @@ -91,7 +102,7 @@ public class InternalTrayManager extends TrayManager { @Override protected Object doInBackground() throws Exception { - RouterManager.shutDown(); + RouterManager.shutDown(_context); return null; } diff --git a/apps/desktopgui/src/net/i2p/desktopgui/Main.java b/apps/desktopgui/src/net/i2p/desktopgui/Main.java index c07e03f44..4592ae7b1 100644 --- a/apps/desktopgui/src/net/i2p/desktopgui/Main.java +++ b/apps/desktopgui/src/net/i2p/desktopgui/Main.java @@ -7,8 +7,15 @@ package net.i2p.desktopgui; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; + +import net.i2p.I2PAppContext; +import net.i2p.app.ClientAppManager; +import net.i2p.app.ClientAppState; +import static net.i2p.app.ClientAppState.*; import net.i2p.desktopgui.router.RouterManager; import net.i2p.desktopgui.util.*; +import net.i2p.router.RouterContext; +import net.i2p.router.app.RouterApp; import net.i2p.util.Log; import net.i2p.util.Translate; import net.i2p.util.I2PProperties.I2PPropertyCallback; @@ -16,22 +23,57 @@ import net.i2p.util.I2PProperties.I2PPropertyCallback; /** * The main class of the application. */ -public class Main { - - ///Manages the lifetime of the tray icon. - private TrayManager trayManager = null; - private final static Log log = new Log(Main.class); +public class Main implements RouterApp { + + private final I2PAppContext _appContext; + private final RouterContext _context; + private final ClientAppManager _mgr; + private final Log log; + private ClientAppState _state = UNINITIALIZED; + private TrayManager _trayManager; /** - * Start the tray icon code (loads tray icon in the tray area). - * @throws Exception + * @since 0.9.26 */ - public void startUp() throws Exception { - trayManager = TrayManager.getInstance(); + public Main(RouterContext ctx, ClientAppManager mgr, String args[]) { + _appContext = _context = ctx; + _mgr = mgr; + log = _appContext.logManager().getLog(Main.class); + _state = INITIALIZED; + } + + /** + * @since 0.9.26 + */ + public Main() { + _appContext = I2PAppContext.getGlobalContext(); + if (_appContext instanceof RouterContext) + _context = (RouterContext) _appContext; + else + _context = null; + _mgr = null; + log = _appContext.logManager().getLog(Main.class); + _state = INITIALIZED; + } + + /** + * Start the tray icon code (loads tray icon in the tray area). + * @throws AWTException on startup error, including systray not supported + */ + private synchronized void startUp() throws Exception { + final TrayManager trayManager; + if (_context != null) + trayManager = new InternalTrayManager(_context); + else + trayManager = new ExternalTrayManager(_appContext); trayManager.startManager(); + _trayManager = trayManager; + changeState(RUNNING); + if (_mgr != null) + _mgr.register(this); - if(RouterManager.inI2P()) { - RouterManager.getRouterContext().addPropertyCallback(new I2PPropertyCallback() { + if (_context != null) { + _context.addPropertyCallback(new I2PPropertyCallback() { @Override public void propertyChanged(String arg0, String arg1) { @@ -45,26 +87,36 @@ public class Main { } public static void main(String[] args) { - beginStartup(args); + Main main = new Main(); + main.beginStartup(args); } /** * Main method launching the application. + * + * @param args unused */ - public static void beginStartup(String[] args) { - try { - String headless = System.getProperty("java.awt.headless"); - boolean isHeadless = Boolean.parseBoolean(headless); - if(isHeadless) { - log.warn("Headless environment: not starting desktopgui!"); - return; - } - } - catch(Exception e) { + private void beginStartup(String[] args) { + changeState(STARTING); + String headless = System.getProperty("java.awt.headless"); + boolean isHeadless = Boolean.parseBoolean(headless); + if (isHeadless) { + log.warn("Headless environment: not starting desktopgui!"); + changeState(START_FAILED, "Headless environment: not starting desktopgui!", null); return; } try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + //UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels(); + //for (int i = 0; i < lafs.length; i++) { + // System.out.println("LAF " + i + ": " + lafs[i].getName() + ' ' + lafs[i].getClassName()); + //} + String laf = UIManager.getSystemLookAndFeelClassName(); + //System.out.println("Default: " + laf); + UIManager.setLookAndFeel(laf); + //laf = UIManager.getCrossPlatformLookAndFeelClassName(); + //System.out.println("Cross-Platform: " + laf); + //UIManager.setLookAndFeel(laf); + //UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (ClassNotFoundException ex) { log.log(Log.ERROR, null, ex); } catch (InstantiationException ex) { @@ -73,23 +125,28 @@ public class Main { log.log(Log.ERROR, null, ex); } catch (UnsupportedLookAndFeelException ex) { log.log(Log.ERROR, null, ex); + } catch (Error ex) { + // on permissions error (different user) + // Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable. + log.log(Log.ERROR, "No permissions? Different user?", ex); + changeState(START_FAILED, "No permissions? Different user?", new RuntimeException(ex)); + return; } - ConfigurationManager.getInstance().loadArguments(args); + // TODO process args with getopt if needed - final Main main = new Main(); - - main.launchForeverLoop(); + if (_context == null) + launchForeverLoop(); //We'll be doing GUI work, so let's stay in the event dispatcher thread. SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { - main.startUp(); - } - catch(Exception e) { + startUp(); + } catch(Exception e) { log.error("Failed while running desktopgui!", e); + changeState(START_FAILED, "Failed while running desktopgui!", e); } } @@ -102,7 +159,7 @@ public class Main { * 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() { + private static void launchForeverLoop() { Runnable r = new Runnable() { public void run() { try { @@ -114,9 +171,60 @@ public class Main { } } }; - Thread t = new Thread(r); + Thread t = new Thread(r, "DesktopGUI spinner"); t.setDaemon(false); t.start(); } - + + /////// ClientApp methods + + /** @since 0.9.26 */ + public synchronized void startup() { + beginStartup(null); + } + + /** @since 0.9.26 */ + public synchronized void shutdown(String[] args) { + if (_state == STOPPED) + return; + changeState(STOPPING); + if (_trayManager != null) + _trayManager.stopManager(); + changeState(STOPPED); + } + + /** @since 0.9.26 */ + public synchronized ClientAppState getState() { + return _state; + } + + /** @since 0.9.26 */ + public String getName() { + return "desktopgui"; + } + + /** @since 0.9.26 */ + public String getDisplayName() { + return "Desktop GUI"; + } + + /////// end ClientApp methods + + /** @since 0.9.26 */ + private void changeState(ClientAppState state) { + changeState(state, null, null); + } + + /** @since 0.9.26 */ + private synchronized void changeState(ClientAppState state, String msg, Exception e) { + _state = state; + if (_mgr != null) + _mgr.notify(this, state, msg, e); + if (_context == null) { + if (msg != null) + System.out.println(state + ": " + msg); + if (e != null) + e.printStackTrace(); + } + } } diff --git a/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java b/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java index 227050735..ac0242dd6 100644 --- a/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java +++ b/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java @@ -8,58 +8,65 @@ import java.awt.Toolkit; import java.awt.TrayIcon; import java.net.URL; +import net.i2p.I2PAppContext; import net.i2p.desktopgui.i18n.DesktopguiTranslator; -import net.i2p.desktopgui.router.RouterManager; -import net.i2p.util.Log; +import net.i2p.util.SystemVersion; /** * Manages the tray icon life. */ -public abstract class TrayManager { +abstract class TrayManager { - private static TrayManager instance = null; + protected final I2PAppContext _appContext; ///The tray area, or null if unsupported - protected SystemTray tray = null; + protected SystemTray tray; ///Our tray icon, or null if unsupported - protected TrayIcon trayIcon = null; - private final static Log log = new Log(TrayManager.class); - + protected TrayIcon trayIcon; + /** * Instantiate tray manager. */ - protected TrayManager() {} - - protected static TrayManager getInstance() { - if(instance == null) { - boolean inI2P = RouterManager.inI2P(); - if(inI2P) { - instance = new InternalTrayManager(); - } - else { - instance = new ExternalTrayManager(); - } - } - return instance; + protected TrayManager(I2PAppContext ctx) { + _appContext = ctx; } - + /** * Add the tray icon to the system tray and start everything up. */ - protected void startManager() { + public synchronized void startManager() throws AWTException { if(SystemTray.isSupported()) { + // TODO figure out how to get menu to pop up on left-click + // left-click does nothing by default + // MouseListener, MouseEvent, ... tray = SystemTray.getSystemTray(); - trayIcon = new TrayIcon(getTrayImage(), "I2P", getMainMenu()); + // Windows typically has tooltips; Linux (at least Ubuntu) doesn't + String tooltip = SystemVersion.isWindows() ? _t("I2P: Right-click for menu") : null; + trayIcon = new TrayIcon(getTrayImage(), tooltip, getMainMenu()); trayIcon.setImageAutoSize(true); //Resize image to fit the system tray - try { - tray.add(trayIcon); - } catch (AWTException e) { - log.log(Log.WARN, "Problem creating system tray icon!", e); - } + tray.add(trayIcon); + // 16x16 on Windows, 24x24 on Linux, but that will probably vary + //System.out.println("Tray icon size is " + trayIcon.getSize()); + } else { + throw new AWTException("SystemTray not supported"); + } + } + + /** + * Remove the tray icon from the system tray + * + * @since 0.9.26 + */ + public synchronized void stopManager() { + if (tray != null && trayIcon != null) { + tray.remove(trayIcon); + tray = null; + trayIcon = null; } } - protected void languageChanged() { - trayIcon.setPopupMenu(getMainMenu()); + public synchronized void languageChanged() { + if (trayIcon != null) + trayIcon.setPopupMenu(getMainMenu()); } /** @@ -71,14 +78,17 @@ public abstract class TrayManager { /** * Get tray icon image from the desktopgui resources in the jar file. * @return image used for the tray icon + * @throws AWTException if image not found */ - private Image getTrayImage() { + private Image getTrayImage() throws AWTException { URL url = getClass().getResource("/desktopgui/resources/images/logo.png"); + if (url == null) + throw new AWTException("cannot load tray image"); Image image = Toolkit.getDefaultToolkit().getImage(url); return image; } - protected static String _t(String s) { - return DesktopguiTranslator._t(s); + protected String _t(String s) { + return DesktopguiTranslator._t(_appContext, s); } } diff --git a/apps/desktopgui/src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java b/apps/desktopgui/src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java index a697c5779..98e513eb3 100644 --- a/apps/desktopgui/src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java +++ b/apps/desktopgui/src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java @@ -13,8 +13,10 @@ package net.i2p.desktopgui.gui; import java.util.logging.Level; import java.util.logging.Logger; + import net.i2p.desktopgui.i18n.DesktopguiTranslator; import net.i2p.desktopgui.router.RouterManager; +import net.i2p.router.RouterContext; /** * @@ -22,9 +24,12 @@ import net.i2p.desktopgui.router.RouterManager; */ public class DesktopguiConfigurationFrame extends javax.swing.JFrame { + private final RouterContext _context; + /** Creates new form ConfigurationFrame */ - public DesktopguiConfigurationFrame() { + public DesktopguiConfigurationFrame(RouterContext ctx) { initComponents(); + _context = ctx; } /** This method is called from within the constructor to @@ -98,8 +103,8 @@ public class DesktopguiConfigurationFrame extends javax.swing.JFrame { configureDesktopgui(); }//GEN-LAST:event_okButtonMouseReleased - protected static String _t(String s) { - return DesktopguiTranslator._t(s); + private String _t(String s) { + return DesktopguiTranslator._t(_context, s); } private void configureDesktopgui() { @@ -114,7 +119,7 @@ public class DesktopguiConfigurationFrame extends javax.swing.JFrame { System.out.println("Enabling desktopgui"); } try { - RouterManager.getRouterContext().router().saveConfig(property, value); + _context.router().saveConfig(property, value); } catch (Exception ex) { Logger.getLogger(DesktopguiConfigurationFrame.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/apps/desktopgui/src/net/i2p/desktopgui/i18n/DesktopguiTranslator.java b/apps/desktopgui/src/net/i2p/desktopgui/i18n/DesktopguiTranslator.java index 3778c4ad9..9fae60ed1 100644 --- a/apps/desktopgui/src/net/i2p/desktopgui/i18n/DesktopguiTranslator.java +++ b/apps/desktopgui/src/net/i2p/desktopgui/i18n/DesktopguiTranslator.java @@ -7,20 +7,11 @@ public class DesktopguiTranslator { private static final String BUNDLE_NAME = "net.i2p.desktopgui.messages"; - private static I2PAppContext ctx; - - private static I2PAppContext getRouterContext() { - if(ctx == null) { - ctx = I2PAppContext.getCurrentContext(); - } - return ctx; - } - - public static String _t(String s) { - return Translate.getString(s, getRouterContext(), BUNDLE_NAME); + public static String _t(I2PAppContext ctx, String s) { + return Translate.getString(s, ctx, BUNDLE_NAME); } - public static String _t(String s, Object o) { - return Translate.getString(s, o, getRouterContext(), BUNDLE_NAME); + public static String _t(I2PAppContext ctx, String s, Object o) { + return Translate.getString(s, o, ctx, BUNDLE_NAME); } } diff --git a/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java b/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java index 82b36938a..9267bcef0 100644 --- a/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java +++ b/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java @@ -16,29 +16,9 @@ import net.i2p.util.Log; */ public class RouterManager { - private final static Log log = new Log(RouterManager.class); - private static I2PAppContext context = I2PAppContext.getCurrentContext(); - - public static I2PAppContext getAppContext() { - return context; - } - - public static RouterContext getRouterContext() throws Exception { - if(context.isRouterContext()) { - return (RouterContext) context; - } - else { - throw new Exception("No RouterContext available!"); - } - } - - private static Router getRouter() { - try { - return getRouterContext().router(); - } catch (Exception e) { - log.error("Failed to get router. Why did we request it if no RouterContext is available?", e); - return null; - } + /** @return non-null */ + private static I2PAppContext getAppContext() { + return I2PAppContext.getGlobalContext(); } /** @@ -53,9 +33,10 @@ public class RouterManager { //TODO: set/get PID String separator = System.getProperty("file.separator"); String location = getAppContext().getBaseDir().getAbsolutePath(); - - Runtime.getRuntime().exec(location + separator + "i2psvc " + location + separator + "wrapper.config"); + String[] args = new String[] { location + separator + "i2psvc", location + separator + "wrapper.config" }; + Runtime.getRuntime().exec(args); } catch (IOException e) { + Log log = getAppContext().logManager().getLog(RouterManager.class); log.log(Log.WARN, "Failed to start I2P", e); } } @@ -63,17 +44,14 @@ public class RouterManager { /** * Restart the running I2P instance. */ - public static void restart() { - if(inI2P()) { - getRouter().restart(); - } + public static void restart(RouterContext ctx) { + ctx.router().restart(); } /** * Stop the running I2P instance. */ - public static void shutDown() { - if(inI2P()) { + public static void shutDown(RouterContext ctx) { Thread t = new Thread(new Runnable() { @Override @@ -83,14 +61,6 @@ public class RouterManager { }); t.start(); - getRouter().shutdown(Router.EXIT_HARD); - } - } - - /** - * Check if we are running inside I2P. - */ - public static boolean inI2P() { - return context.isRouterContext(); + ctx.router().shutdown(Router.EXIT_HARD); } } diff --git a/apps/desktopgui/src/net/i2p/desktopgui/util/ConfigurationManager.java b/apps/desktopgui/src/net/i2p/desktopgui/util/ConfigurationManager.java deleted file mode 100644 index cc0516bd6..000000000 --- a/apps/desktopgui/src/net/i2p/desktopgui/util/ConfigurationManager.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.i2p.desktopgui.util; - -import java.util.HashMap; -import java.util.Map; - -/** - * Manage the configuration of desktopgui. - * @author mathias - * - */ -public class ConfigurationManager { - - private static ConfigurationManager instance; - ///Configurations with a String as value - private Map stringConfigurations = new HashMap(); - ///Configurations with a Boolean as value - private Map booleanConfigurations = new HashMap(); - - private ConfigurationManager() {} - - public static ConfigurationManager getInstance() { - if(instance == null) { - instance = new ConfigurationManager(); - } - return instance; - } - - /** - * Collects arguments of the form --word, --word=otherword and -blah - * to determine user parameters. - * @param args Command line arguments to the application - */ - public void loadArguments(String[] args) { - for(int i=0; i