Changeset 75d6df77


Ignore:
Timestamp:
May 5, 2016 1:13:44 PM (4 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
8c1f7a4
Parents:
16ff3e3
Message:

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
Location:
apps/desktopgui
Files:
6 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • apps/desktopgui/build.xml

    r16ff3e3 r75d6df77  
    66        <property name="dist"  location="dist"/>
    77        <property name="jar" value="desktopgui.jar"/>
    8         <property name="resources" value="resources"/>
    98        <property name="javadoc" value="javadoc"/>
    109        <property name="javac.compilerargs" value=""/>
     
    3736                </classpath>
    3837            </javac>
    39             <copy todir="${build}/desktopgui/${resources}">
    40                 <fileset dir="${resources}" />
    41             </copy>
    4238        </target>
    4339
     
    7773                <!-- set if unset -->
    7874                <property name="workspace.changes.tr" value="" />
     75                <!-- ideal for linux: 24x24, but transparency doesn't work -->
     76                <copy tofile="${build}/desktopgui/resources/images/logo.png" file="../../installer/resources/themes/console/images/itoopie_xsm.png" />
    7977                <jar basedir="${build}" excludes="messages-src/**" destfile="${dist}/${jar}">
    8078                        <manifest>
  • apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java

    r16ff3e3 r75d6df77  
    99import javax.swing.SwingWorker;
    1010
     11import net.i2p.I2PAppContext;
    1112import net.i2p.desktopgui.router.RouterManager;
    12 import net.i2p.util.Log;
    1313
    14 public class ExternalTrayManager extends TrayManager {
     14/**
     15 *  When started before the router, e.g. with
     16 *  java -cp i2p.jar:desktopgui.jar net.i2p.desktopgui.Main
     17 *
     18 *  No access to context, very limited abilities.
     19 *  Not fully supported.
     20 */
     21class ExternalTrayManager extends TrayManager {
    1522       
    16     private final static Log log = new Log(ExternalTrayManager.class);
    17 
    18     protected ExternalTrayManager() {}
     23    public ExternalTrayManager(I2PAppContext ctx) {
     24        super(ctx);
     25    }
    1926
    2027    @Override
  • apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java

    r16ff3e3 r75d6df77  
    1212import net.i2p.desktopgui.util.BrowseException;
    1313import net.i2p.desktopgui.util.I2PDesktop;
     14import net.i2p.router.RouterContext;
    1415import net.i2p.util.Log;
    1516
    16 public class InternalTrayManager extends TrayManager {
     17/**
     18 *  java -cp i2p.jar:desktopgui.jar net.i2p.desktopgui.Main
     19 *
     20 *  Full access to router context.
     21 */
     22class InternalTrayManager extends TrayManager {
    1723       
    18         private final static Log log = new Log(InternalTrayManager.class);
     24    private final RouterContext _context;
     25    private final Log log;
    1926
    20     protected InternalTrayManager() {}
     27    public InternalTrayManager(RouterContext ctx) {
     28        super(ctx);
     29        _context = ctx;
     30        log = ctx.logManager().getLog(InternalTrayManager.class);
     31    }
    2132
    2233    @Override
     
    5768                    @Override
    5869                    protected Object doInBackground() throws Exception {
    59                         new DesktopguiConfigurationFrame().setVisible(true);
     70                        new DesktopguiConfigurationFrame(_context).setVisible(true);
    6071                        return null;
    6172                    }
     
    7485                    @Override
    7586                    protected Object doInBackground() throws Exception {
    76                         RouterManager.restart();
     87                        RouterManager.restart(_context);
    7788                        return null;
    7889                    }
     
    92103                    @Override
    93104                    protected Object doInBackground() throws Exception {
    94                         RouterManager.shutDown();
     105                        RouterManager.shutDown(_context);
    95106                        return null;
    96107                    }
  • apps/desktopgui/src/net/i2p/desktopgui/Main.java

    r16ff3e3 r75d6df77  
    88import javax.swing.UIManager;
    99import javax.swing.UnsupportedLookAndFeelException;
     10
     11import net.i2p.I2PAppContext;
     12import net.i2p.app.ClientAppManager;
     13import net.i2p.app.ClientAppState;
     14import static net.i2p.app.ClientAppState.*;
    1015import net.i2p.desktopgui.router.RouterManager;
    1116import net.i2p.desktopgui.util.*;
     17import net.i2p.router.RouterContext;
     18import net.i2p.router.app.RouterApp;
    1219import net.i2p.util.Log;
    1320import net.i2p.util.Translate;
     
    1724 * The main class of the application.
    1825 */
    19 public class Main {
     26public class Main implements RouterApp {
     27
     28    private final I2PAppContext _appContext;
     29    private final RouterContext _context;
     30    private final ClientAppManager _mgr;
     31    private final Log log;
     32    private ClientAppState _state = UNINITIALIZED;
     33    private TrayManager _trayManager;
     34
     35    /**
     36     *  @since 0.9.26
     37     */
     38    public Main(RouterContext ctx, ClientAppManager mgr, String args[]) {
     39        _appContext = _context = ctx;
     40        _mgr = mgr;
     41        log = _appContext.logManager().getLog(Main.class);
     42        _state = INITIALIZED;
     43    }
     44
     45    /**
     46     *  @since 0.9.26
     47     */
     48    public Main() {
     49        _appContext = I2PAppContext.getGlobalContext();
     50        if (_appContext instanceof RouterContext)
     51            _context = (RouterContext) _appContext;
     52        else
     53            _context = null;
     54        _mgr = null;
     55        log = _appContext.logManager().getLog(Main.class);
     56        _state = INITIALIZED;
     57    }
    2058   
    21     ///Manages the lifetime of the tray icon.
    22     private TrayManager trayManager = null;
    23     private final static Log log = new Log(Main.class);
    24 
    2559    /**
    2660     * Start the tray icon code (loads tray icon in the tray area).
    27      * @throws Exception
    28      */
    29     public void startUp() throws Exception {
    30         trayManager = TrayManager.getInstance();
     61     * @throws AWTException on startup error, including systray not supported
     62     */
     63    private synchronized void startUp() throws Exception {
     64        final TrayManager trayManager;
     65        if (_context != null)
     66            trayManager = new InternalTrayManager(_context);
     67        else
     68            trayManager = new ExternalTrayManager(_appContext);
    3169        trayManager.startManager();
     70        _trayManager = trayManager;
     71        changeState(RUNNING);
     72        if (_mgr != null)
     73            _mgr.register(this);
    3274       
    33         if(RouterManager.inI2P()) {
    34             RouterManager.getRouterContext().addPropertyCallback(new I2PPropertyCallback() {
     75        if (_context != null) {
     76            _context.addPropertyCallback(new I2PPropertyCallback() {
    3577
    3678                @Override
     
    4688   
    4789    public static void main(String[] args) {
    48         beginStartup(args);
     90        Main main = new Main();
     91        main.beginStartup(args);
    4992    }
    5093
    5194    /**
    5295     * Main method launching the application.
    53      */
    54     public static void beginStartup(String[] args) {
     96     *
     97     * @param args unused
     98     */
     99    private void beginStartup(String[] args) {
     100        changeState(STARTING);
     101        String headless = System.getProperty("java.awt.headless");
     102        boolean isHeadless = Boolean.parseBoolean(headless);
     103        if (isHeadless) {
     104                log.warn("Headless environment: not starting desktopgui!");
     105            changeState(START_FAILED, "Headless environment: not starting desktopgui!", null);
     106            return;
     107        }
    55108        try {
    56             String headless = System.getProperty("java.awt.headless");
    57             boolean isHeadless = Boolean.parseBoolean(headless);
    58             if(isHeadless) {
    59                 log.warn("Headless environment: not starting desktopgui!");
    60                 return;
    61             }
    62         }
    63         catch(Exception e) {
     109            //UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
     110            //for (int i = 0; i < lafs.length; i++) {
     111            //    System.out.println("LAF " + i + ": " + lafs[i].getName() + ' ' + lafs[i].getClassName());
     112            //}
     113            String laf = UIManager.getSystemLookAndFeelClassName();
     114            //System.out.println("Default: " + laf);
     115            UIManager.setLookAndFeel(laf);
     116            //laf = UIManager.getCrossPlatformLookAndFeelClassName();
     117            //System.out.println("Cross-Platform: " + laf);
     118            //UIManager.setLookAndFeel(laf);
     119            //UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
     120        } catch (ClassNotFoundException ex) {
     121            log.log(Log.ERROR, null, ex);
     122        } catch (InstantiationException ex) {
     123            log.log(Log.ERROR, null, ex);
     124        } catch (IllegalAccessException ex) {
     125            log.log(Log.ERROR, null, ex);
     126        } catch (UnsupportedLookAndFeelException ex) {
     127            log.log(Log.ERROR, null, ex);
     128        } catch (Error ex) {
     129            // on permissions error (different user)
     130            // Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable.
     131            log.log(Log.ERROR, "No permissions? Different user?", ex);
     132            changeState(START_FAILED, "No permissions? Different user?", new RuntimeException(ex));
    64133            return;
    65134        }
    66         try {
    67             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    68         } catch (ClassNotFoundException ex) {
    69             log.log(Log.ERROR, null, ex);
    70         } catch (InstantiationException ex) {
    71             log.log(Log.ERROR, null, ex);
    72         } catch (IllegalAccessException ex) {
    73             log.log(Log.ERROR, null, ex);
    74         } catch (UnsupportedLookAndFeelException ex) {
    75             log.log(Log.ERROR, null, ex);
    76         }
    77135       
    78         ConfigurationManager.getInstance().loadArguments(args);
     136        // TODO process args with getopt if needed
    79137       
    80         final Main main = new Main();
    81        
    82         main.launchForeverLoop();
     138        if (_context == null)
     139            launchForeverLoop();
    83140        //We'll be doing GUI work, so let's stay in the event dispatcher thread.
    84141        SwingUtilities.invokeLater(new Runnable() {
     
    87144            public void run() {
    88145                try {
    89                     main.startUp();
    90                 }
    91                 catch(Exception e) {
     146                    startUp();
     147                } catch(Exception e) {
    92148                    log.error("Failed while running desktopgui!", e);
     149                    changeState(START_FAILED, "Failed while running desktopgui!", e);
    93150                }
    94151               
     
    103160     * More info: http://java.sun.com/javase/6/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown
    104161     */
    105     public void launchForeverLoop() {
     162    private static void launchForeverLoop() {
    106163       Runnable r = new Runnable() {
    107164            public void run() {
     
    115172            }
    116173        };
    117         Thread t = new Thread(r);
     174        Thread t = new Thread(r, "DesktopGUI spinner");
    118175        t.setDaemon(false);
    119176        t.start();
    120177    }
    121    
     178
     179    /////// ClientApp methods
     180
     181    /** @since 0.9.26 */
     182    public synchronized void startup() {
     183        beginStartup(null);
     184    }
     185
     186    /** @since 0.9.26 */
     187    public synchronized void shutdown(String[] args) {
     188        if (_state == STOPPED)
     189            return;
     190        changeState(STOPPING);
     191        if (_trayManager != null)
     192            _trayManager.stopManager();
     193        changeState(STOPPED);
     194    }
     195
     196    /** @since 0.9.26 */
     197    public synchronized ClientAppState getState() {
     198        return _state;
     199    }
     200
     201    /** @since 0.9.26 */
     202    public String getName() {
     203        return "desktopgui";
     204    }
     205
     206    /** @since 0.9.26 */
     207    public String getDisplayName() {
     208        return "Desktop GUI";
     209    }
     210
     211    /////// end ClientApp methods
     212
     213    /** @since 0.9.26 */
     214    private void changeState(ClientAppState state) {
     215        changeState(state, null, null);
     216    }
     217
     218    /** @since 0.9.26 */
     219    private synchronized void changeState(ClientAppState state, String msg, Exception e) {
     220        _state = state;
     221        if (_mgr != null)
     222            _mgr.notify(this, state, msg, e);
     223        if (_context == null) {
     224            if (msg != null)
     225                System.out.println(state + ": " + msg);
     226            if (e != null)
     227                e.printStackTrace();
     228        }
     229    }
    122230}
  • apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java

    r16ff3e3 r75d6df77  
    99import java.net.URL;
    1010
     11import net.i2p.I2PAppContext;
    1112import net.i2p.desktopgui.i18n.DesktopguiTranslator;
    12 import net.i2p.desktopgui.router.RouterManager;
    13 import net.i2p.util.Log;
     13import net.i2p.util.SystemVersion;
    1414
    1515/**
    1616 * Manages the tray icon life.
    1717 */
    18 public abstract class TrayManager {
     18abstract class TrayManager {
    1919
    20     private static TrayManager instance = null;
     20    protected final I2PAppContext _appContext;
    2121    ///The tray area, or null if unsupported
    22     protected SystemTray tray = null;
     22    protected SystemTray tray;
    2323    ///Our tray icon, or null if unsupported
    24     protected TrayIcon trayIcon = null;
    25     private final static Log log = new Log(TrayManager.class);
    26    
     24    protected TrayIcon trayIcon;
     25
    2726    /**
    2827     * Instantiate tray manager.
    2928     */
    30     protected TrayManager() {}
     29    protected TrayManager(I2PAppContext ctx) {
     30        _appContext = ctx;
     31    }
    3132   
    32     protected static TrayManager getInstance() {
    33         if(instance == null) {
    34             boolean inI2P = RouterManager.inI2P();
    35             if(inI2P) {
    36                 instance = new InternalTrayManager();
    37             }
    38             else {
    39                 instance = new ExternalTrayManager();
    40             }
     33    /**
     34     * Add the tray icon to the system tray and start everything up.
     35     */
     36    public synchronized void startManager()  throws AWTException {
     37        if(SystemTray.isSupported()) {
     38            // TODO figure out how to get menu to pop up on left-click
     39            // left-click does nothing by default
     40            // MouseListener, MouseEvent, ...
     41            tray = SystemTray.getSystemTray();
     42            // Windows typically has tooltips; Linux (at least Ubuntu) doesn't
     43            String tooltip = SystemVersion.isWindows() ? _t("I2P: Right-click for menu") : null;
     44            trayIcon = new TrayIcon(getTrayImage(), tooltip, getMainMenu());
     45            trayIcon.setImageAutoSize(true); //Resize image to fit the system tray
     46            tray.add(trayIcon);
     47            // 16x16 on Windows, 24x24 on Linux, but that will probably vary
     48            //System.out.println("Tray icon size is " + trayIcon.getSize());
     49        } else {
     50            throw new AWTException("SystemTray not supported");
    4151        }
    42         return instance;
    4352    }
    4453
    4554    /**
    46      * Add the tray icon to the system tray and start everything up.
     55     * Remove the tray icon from the system tray
     56     *
     57     * @since 0.9.26
    4758     */
    48     protected void startManager() {
    49         if(SystemTray.isSupported()) {
    50             tray = SystemTray.getSystemTray();
    51             trayIcon = new TrayIcon(getTrayImage(), "I2P", getMainMenu());
    52             trayIcon.setImageAutoSize(true); //Resize image to fit the system tray
    53             try {
    54                 tray.add(trayIcon);
    55             } catch (AWTException e) {
    56                 log.log(Log.WARN, "Problem creating system tray icon!", e);
    57             }
     59    public synchronized void stopManager() {
     60        if (tray != null && trayIcon != null) {
     61            tray.remove(trayIcon);
     62            tray = null;
     63            trayIcon = null;
    5864        }
    5965    }
    6066   
    61     protected void languageChanged() {
    62         trayIcon.setPopupMenu(getMainMenu());
     67    public synchronized void languageChanged() {
     68        if (trayIcon != null)
     69            trayIcon.setPopupMenu(getMainMenu());
    6370    }
    6471   
     
    7279     * Get tray icon image from the desktopgui resources in the jar file.
    7380     * @return image used for the tray icon
     81     * @throws AWTException if image not found
    7482     */
    75     private Image getTrayImage() {
     83    private Image getTrayImage() throws AWTException {
    7684        URL url = getClass().getResource("/desktopgui/resources/images/logo.png");
     85        if (url == null)
     86            throw new AWTException("cannot load tray image");
    7787        Image image = Toolkit.getDefaultToolkit().getImage(url);
    7888        return image;
    7989    }
    8090   
    81     protected static String _t(String s) {
    82         return DesktopguiTranslator._t(s);
     91    protected String _t(String s) {
     92        return DesktopguiTranslator._t(_appContext, s);
    8393    }
    8494}
  • apps/desktopgui/src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java

    r16ff3e3 r75d6df77  
    1414import java.util.logging.Level;
    1515import java.util.logging.Logger;
     16
    1617import net.i2p.desktopgui.i18n.DesktopguiTranslator;
    1718import net.i2p.desktopgui.router.RouterManager;
     19import net.i2p.router.RouterContext;
    1820
    1921/**
     
    2325public class DesktopguiConfigurationFrame extends javax.swing.JFrame {
    2426
     27    private final RouterContext _context;
     28
    2529    /** Creates new form ConfigurationFrame */
    26     public DesktopguiConfigurationFrame() {
     30    public DesktopguiConfigurationFrame(RouterContext ctx) {
    2731        initComponents();
     32        _context = ctx;
    2833    }
    2934
     
    99104    }//GEN-LAST:event_okButtonMouseReleased
    100105
    101     protected static String _t(String s) {
    102         return DesktopguiTranslator._t(s);
     106    private String _t(String s) {
     107        return DesktopguiTranslator._t(_context, s);
    103108    }
    104109
     
    115120        }
    116121        try {
    117             RouterManager.getRouterContext().router().saveConfig(property, value);
     122            _context.router().saveConfig(property, value);
    118123        } catch (Exception ex) {
    119124            Logger.getLogger(DesktopguiConfigurationFrame.class.getName()).log(Level.SEVERE, null, ex);
  • apps/desktopgui/src/net/i2p/desktopgui/i18n/DesktopguiTranslator.java

    r16ff3e3 r75d6df77  
    88    private static final String BUNDLE_NAME = "net.i2p.desktopgui.messages";
    99   
    10     private static I2PAppContext ctx;
    11    
    12     private static I2PAppContext getRouterContext() {
    13         if(ctx == null) {
    14             ctx = I2PAppContext.getCurrentContext();
    15         }
    16         return ctx;
    17     }
    18    
    19     public static String _t(String s) {
    20         return Translate.getString(s, getRouterContext(), BUNDLE_NAME);
     10    public static String _t(I2PAppContext ctx, String s) {
     11        return Translate.getString(s, ctx, BUNDLE_NAME);
    2112    }
    2213
    23     public static String _t(String s, Object o) {
    24         return Translate.getString(s, o, getRouterContext(), BUNDLE_NAME);
     14    public static String _t(I2PAppContext ctx, String s, Object o) {
     15        return Translate.getString(s, o, ctx, BUNDLE_NAME);
    2516    }
    2617}
  • apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java

    r16ff3e3 r75d6df77  
    1717public class RouterManager {
    1818       
    19         private final static Log log = new Log(RouterManager.class);
    20         private static I2PAppContext context = I2PAppContext.getCurrentContext();
    21        
    22         public static I2PAppContext getAppContext() {
    23                 return context;
    24         }
    25        
    26         public static RouterContext getRouterContext() throws Exception {
    27                 if(context.isRouterContext()) {
    28                         return (RouterContext) context;
    29                 }
    30                 else {
    31                         throw new Exception("No RouterContext available!");
    32                 }
    33         }
    34        
    35         private static Router getRouter() {
    36                 try {
    37                         return getRouterContext().router();
    38                 } catch (Exception e) {
    39                 log.error("Failed to get router. Why did we request it if no RouterContext is available?", e);
    40             return null;
    41         }
     19    /** @return non-null */
     20    private static I2PAppContext getAppContext() {
     21        return I2PAppContext.getGlobalContext();
    4222    }
    4323   
     
    5434            String separator = System.getProperty("file.separator");
    5535            String location = getAppContext().getBaseDir().getAbsolutePath();
    56            
    57             Runtime.getRuntime().exec(location + separator + "i2psvc " + location + separator + "wrapper.config");
     36            String[] args = new String[] { location + separator + "i2psvc", location + separator + "wrapper.config" };
     37            Runtime.getRuntime().exec(args);
    5838        } catch (IOException e) {
     39            Log log = getAppContext().logManager().getLog(RouterManager.class);
    5940            log.log(Log.WARN, "Failed to start I2P", e);
    6041        }
     
    6445     * Restart the running I2P instance.
    6546     */
    66     public static void restart() {
    67         if(inI2P()) {
    68             getRouter().restart();
    69         }
     47    public static void restart(RouterContext ctx) {
     48        ctx.router().restart();
    7049    }
    7150
     
    7352     * Stop the running I2P instance.
    7453     */
    75     public static void shutDown() {
    76         if(inI2P()) {
     54    public static void shutDown(RouterContext ctx) {
    7755            Thread t = new Thread(new Runnable() {
    7856
     
    8462            });
    8563            t.start();
    86             getRouter().shutdown(Router.EXIT_HARD);
    87         }
    88     }
    89    
    90     /**
    91      * Check if we are running inside I2P.
    92      */
    93     public static boolean inI2P() {
    94         return context.isRouterContext();
     64            ctx.router().shutdown(Router.EXIT_HARD);
    9565    }
    9666}
  • apps/desktopgui/src/net/i2p/desktopgui/util/I2PDesktop.java

    r16ff3e3 r75d6df77  
    44import java.awt.Desktop.Action;
    55import java.net.URI;
    6 import net.i2p.util.Log;
    76
    87public class I2PDesktop {
    9    
    10     private final static Log log = new Log(I2PDesktop.class);
    118   
    129    public static void browse(String url) throws BrowseException {
Note: See TracChangeset for help on using the changeset viewer.