pivot-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Brown <gkbr...@mac.com>
Subject Re: new DesktopApplicationContext
Date Sat, 27 Jun 2009 13:55:18 GMT
Another option is to create a bootstrap application that can be used  
to load other applications, and start this as the main app in  
DesktopApplicationContext. We have talked about creating such an app  
(e.g. the "Pivot Desktop Environment") - it would play a similar role  
to the Explorer (i.e. the desktop) in Windows and the Finder in OS X.  
It would launch each application using a separate class loader so  
every application would get its own namespace. It is a pretty  
interesting concept when combined with DesktopApplicationContext's new  
full screen mode.

However, if your requirements are simpler, you might not need  
something that sophisticated.


On Jun 26, 2009, at 10:35 PM, Greg Brown wrote:

> It's an interesting concept, but I'd like to understand the use case  
> a little better. Why do you need this functionality? And might it  
> possibly be better served by creating another concrete  
> ApplicationContext subclass, rather than modifying  
> DesktopApplicationContext?
>
> Greg
>
>
> On Friday, June 26, 2009, at 07:16PM, "Edgar Merino" <donvodka@gmail.com 
> > wrote:
>> Hello,
>>
>>   I've just changed the code in the DesktopApplicationContext (diff
>> attached), it doesn't abuse of static code that much anymore (hence
>> there can be many DesktopApplicationContext's, useful for a wtkx gui
>> visualizer I'll implement). There are only a few things that need  
>> to be
>> fixed (explained in the TODO's), but are minor. This would be the  
>> usage
>> of the new DesktopApplicationContext:
>>
>>   public static void main(String[] args) {
>>      new DesktopApplicationContext().open(new MyApplication());
>>   }
>>
>>   Note that I didn't provide any support for launching applications
>> from the command line using this new context, but that should be
>> extremely easy to implement (I don't really use that feature... but  
>> feel
>> free to create your own class for that purpose).
>>
>>
>> Hope you find this useful as much as I do,
>> Edgar Merino
>>
>> # This patch file was generated by NetBeans IDE
>> # This patch can be applied using context Tools: Apply Diff Patch  
>> action on respective folder.
>> # It uses platform neutral UTF-8 encoding.
>> # Above lines and this line are ignored by the patching process.
>> --- /home/oso/Programaci��n/java/pivot-wtk-svn/src/main/java/org/ 
>> apache/pivot/wtk/DesktopAppContext.java
>> +++ /home/oso/Programaci��n/java/pivot-wtk-svn/src/main/java/org/ 
>> apache/pivot/wtk/DesktopApplicationContext.java
>> @@ -30,24 +30,26 @@
>> import java.net.URL;
>>
>> import org.apache.pivot.collections.HashMap;
>> +import org.apache.pivot.collections.Map;
>> import org.apache.pivot.collections.immutable.ImmutableMap;
>> import org.apache.pivot.wtk.media.Image;
>> import org.apache.pivot.wtk.media.Picture;
>>
>> -
>> /**
>> * Application context used to execute applications in a native frame
>> * window.
>> *
>> * @author gbrown
>> + * @author emerino
>> */
>> -public final class DesktopAppContext extends ApplicationContext {
>> -    private static class HostFrame extends java.awt.Frame {
>> +public final class DesktopApplicationContext extends  
>> ApplicationContext {
>> +
>> +    private class HostFrame extends java.awt.Frame {
>> +
>>        private static final long serialVersionUID = 0;
>>
>>        private HostFrame() {
>> -            enableEvents(AWTEvent.WINDOW_EVENT_MASK
>> -                | AWTEvent.WINDOW_STATE_EVENT_MASK);
>> +            enableEvents(AWTEvent.WINDOW_EVENT_MASK |  
>> AWTEvent.WINDOW_STATE_EVENT_MASK);
>>
>>            // Disable focus traversal keys
>>            setFocusTraversalKeysEnabled(false);
>> @@ -60,133 +62,111 @@
>>        public void update(Graphics graphics) {
>>            paint(graphics);
>>        }
>> +    }
>>
>> -        @Override
>> -        public void processWindowEvent(WindowEvent event) {
>> -            super.processWindowEvent(event);
>> +    private class WindowEventListener implements  
>> java.awt.event.WindowListener {
>>
>> -            if (this == windowedHostFrame) {
>> -                switch(event.getID()) {
>> -                    case WindowEvent.WINDOW_OPENED: {
>> -                         
>> applicationContext.getDisplayHost().requestFocus();
>> +        public void windowOpened(WindowEvent e) {
>> +            getDisplayHost().requestFocus();
>>
>>                        createTimer();
>>
>>                        try {
>> -                             
>> application.startup(applicationContext.getDisplay(),
>> +                application.startup(getDisplay(),
>>                                new ImmutableMap<String,  
>> String>(properties));
>> -                        } catch(Exception exception) {
>> +            } catch (Exception exception) {
>>                            exception.printStackTrace();
>>                            String message = exception.getMessage();
>>                            if (message == null) {
>>                                message =  
>> exception.getClass().getName();
>>                            }
>>
>> -                            Alert.alert(MessageType.ERROR,  
>> message, applicationContext.getDisplay());
>> +                Alert.alert(MessageType.ERROR, message,  
>> getDisplay());
>>                        }
>>
>> -                        break;
>> +
>>                    }
>>
>> -                    case WindowEvent.WINDOW_CLOSING: {
>> -                        exit();
>> -                        break;
>> +        public void windowClosing(WindowEvent e) {
>> +            close();
>>                    }
>> -                }
>> -            }
>> -        }
>>
>> -        @Override
>> -        protected void processWindowStateEvent(WindowEvent event) {
>> -            super.processWindowStateEvent(event);
>> -
>> -            if (this == windowedHostFrame) {
>> -                switch(event.getID()) {
>> -                    case WindowEvent.WINDOW_ICONIFIED: {
>> +        public void windowIconified(WindowEvent e) {
>>                        try {
>>                            application.suspend();
>> -                        } catch(Exception exception) {
>> +            } catch (Exception exception) {
>>                            exception.printStackTrace();
>>                            Alert.alert(MessageType.ERROR,  
>> exception.getMessage(),
>> -                                applicationContext.getDisplay());
>> +                        getDisplay());
>>                        }
>> -
>> -                        break;
>>                    }
>>
>> -                    case WindowEvent.WINDOW_DEICONIFIED: {
>> +        public void windowDeiconified(WindowEvent e) {
>>                        try {
>>                            application.resume();
>> -                        } catch(Exception exception) {
>> +            } catch (Exception exception) {
>>                            exception.printStackTrace();
>>                            Alert.alert(MessageType.ERROR,  
>> exception.getMessage(),
>> -                                applicationContext.getDisplay());
>> +                        getDisplay());
>>                        }
>> +        }
>>
>> -                        break;
>> +        public void windowActivated(WindowEvent e) {
>> +            //ignore
>>                    }
>> +
>> +        public void windowClosed(WindowEvent e) {
>> +            //ignore
>>                }
>> +
>> +        public void windowDeactivated(WindowEvent e) {
>> +            //ignore
>>            }
>>        }
>> -    }
>>
>> -    private static DesktopApplicationContext applicationContext =  
>> null;
>> -    private static HashMap<String, String> properties = null;
>> -    private static Application application = null;
>> -
>> -    private static HostFrame windowedHostFrame = new HostFrame();
>> -    private static HostFrame fullScreenHostFrame = null;
>> -
>>    private static final String DEFAULT_HOST_FRAME_TITLE = "Pivot";
>> +    private final HostFrame windowedHostFrame;
>> +    private final HostFrame fullScreenHostFrame;
>> +    private Map<String, String> properties;
>> +    private boolean opened; //only one application running per  
>> DesktopApplicationContext
>> +                            //instance at the same time
>> +    private Application application;
>>
>> -    private static final String X_ARGUMENT = "x";
>> -    private static final String Y_ARGUMENT = "y";
>> -    private static final String WIDTH_ARGUMENT = "width";
>> -    private static final String HEIGHT_ARGUMENT = "height";
>> -    private static final String CENTER_ARGUMENT = "center";
>> -    private static final String RESIZABLE_ARGUMENT = "resizable";
>> +    public DesktopApplicationContext() {
>> +        windowedHostFrame = new HostFrame();
>> +        fullScreenHostFrame = new HostFrame();
>>
>> -    private static final String FULL_SCREEN_ARGUMENT = "fullScreen";
>> -
>> -    /**
>> -     * Terminates the application context.
>> -     */
>> -    public static void exit() {
>> -        boolean shutdown = true;
>> -
>> -        try {
>> -            shutdown = application.shutdown(true);
>> -        } catch(Exception exception) {
>> -            exception.printStackTrace();
>> -            Alert.alert(MessageType.ERROR, exception.getMessage(),
>> -                applicationContext.getDisplay());
>> +        windowedHostFrame.addWindowListener(new  
>> WindowEventListener());
>>        }
>>
>> -        if (shutdown) {
>> -            destroyTimer();
>> -            windowedHostFrame.dispose();
>> -            fullScreenHostFrame.dispose();
>> -            System.exit(0);
>> +    public java.awt.Frame getWindowedHostFrame() {
>> +        return windowedHostFrame;
>>        }
>> -    }
>>
>> -    public static java.awt.Frame getHostFrame() {
>> -            return windowedHostFrame;
>> +    public void open(Application application) {
>> +        open(application, new HashMap<String, String>());
>>        }
>>
>>    /**
>>     * Primary aplication entry point.
>>     *
>> +     * TODO: provide a means to set WindowedHostFrameProperties  
>> externally,
>> +     *       without having to do that directly on the HostFrame
>> +     *
>>     * @param args
>>     */
>> -    public static void main(String[] args) {
>> -        if (application != null) {
>> +    public void open(Application application, Map<String, String>  
>> properties) {
>> +        if (application == null) {
>> +            throw new IllegalArgumentException("Application cannot  
>> be null");
>> +        }
>> +
>> +        if (opened) {
>>            throw new IllegalStateException();
>>        }
>>
>> -        // Get the application class name and startup properties
>> -        String applicationClassName = null;
>> -        properties = new HashMap<String, String>();
>> +        opened = true;
>> +        this.application = application;
>> +        this.properties = properties;
>>
>>        int x = 0;
>>        int y = 0;
>> @@ -196,58 +176,28 @@
>>        boolean resizable = true;
>>        boolean fullScreen = false;
>>
>> -        for (int i = 0, n = args.length; i < n; i++) {
>> -            String arg = args[i];
>> +        windowedHostFrame.setSize(width, height);
>> +        windowedHostFrame.setResizable(resizable);
>>
>> -            if (i == 0) {
>> -                applicationClassName = arg;
>> +        //////////////////////////////////////////
>> +        if (center) {
>> +            java.awt.Dimension screenSize =  
>> java.awt.Toolkit.getDefaultToolkit().getScreenSize();
>> +            windowedHostFrame.setLocation((screenSize.width -  
>> width) / 2, (screenSize.height - height) / 2);
>>            } else {
>> -                String[] property;
>> -                if (arg.startsWith("--")) {
>> -                    arg = arg.substring(2);
>> -                    property = arg.split("=");
>> -                } else {
>> -                    property = arg.split(":");
>> +            windowedHostFrame.setLocation(x, y);
>>                }
>>
>> -                if (property.length == 2) {
>> -                    String key = property[0];
>> -                    String value = property[1];
>> -
>> -                    if (key.equals(X_ARGUMENT)) {
>> -                        x = Integer.parseInt(value);
>> -                    } else if (key.equals(Y_ARGUMENT)) {
>> -                        y = Integer.parseInt(value);
>> -                    } else if (key.equals(WIDTH_ARGUMENT)) {
>> -                        width = Integer.parseInt(value);
>> -                    } else if (key.equals(HEIGHT_ARGUMENT)) {
>> -                        height = Integer.parseInt(value);
>> -                    } else if (key.equals(CENTER_ARGUMENT)) {
>> -                        center = Boolean.parseBoolean(value);
>> -                    } else if (key.equals(RESIZABLE_ARGUMENT)) {
>> -                        resizable = Boolean.parseBoolean(value);
>> -                    } else if (key.equals(FULL_SCREEN_ARGUMENT)) {
>> -                        fullScreen = Boolean.parseBoolean(value);
>> -                    } else {
>> -                        properties.put(key, value);
>> -                    }
>> -                } else {
>> -                    System.err.println(arg + " is not a valid  
>> startup property.");
>> -                }
>> -            }
>> -        }
>> -
>>        // Set the origin
>>        try {
>>            // Load the JNLP classes dynamically because they are  
>> only available
>>            // when run via javaws
>>            Class<?> serviceManagerClass =  
>> Class.forName("javax.jnlp.ServiceManager");
>> -            Method lookupMethod =  
>> serviceManagerClass.getMethod("lookup", new Class<?>[]  
>> {String.class});
>> +            Method lookupMethod =  
>> serviceManagerClass.getMethod("lookup", new Class<?>[] 
>> {String.class});
>>            Object basicService = lookupMethod.invoke(null,  
>> "javax.jnlp.BasicService");
>>
>>            Class<?> basicServiceClass =  
>> Class.forName("javax.jnlp.BasicService");
>> -            Method getCodeBaseMethod =  
>> basicServiceClass.getMethod("getCodeBase", new Class<?>[] {});
>> -            URL codeBase =  
>> (URL)getCodeBaseMethod.invoke(basicService);
>> +            Method getCodeBaseMethod =  
>> basicServiceClass.getMethod("getCodeBase", new Class<?>[]{});
>> +            URL codeBase = (URL)  
>> getCodeBaseMethod.invoke(basicService);
>>
>>            if (codeBase != null) {
>>                origin = new URL(codeBase.getProtocol(),  
>> codeBase.getHost(), codeBase.getPort(), "");
>> @@ -262,60 +212,28 @@
>>
>>            try {
>>                origin = userHome.toURI().toURL();
>> -            } catch(MalformedURLException exception) {
>> +            } catch (MalformedURLException exception) {
>>                // No-op
>>            }
>>        }
>>
>> -        // Create the application context
>> -        applicationContext = new DesktopApplicationContext();
>> -
>> -        // Load the application
>> -        if (applicationClassName == null) {
>> -            System.err.println("Application class name is  
>> required.");
>> -        } else {
>> -            try {
>> -                Class<?> applicationClass =  
>> Class.forName(applicationClassName);
>> -                application =  
>> (Application)applicationClass.newInstance();
>> -            } catch(Exception exception) {
>> -                Alert.alert(MessageType.ERROR,  
>> exception.getMessage(),
>> -                    applicationContext.getDisplay());
>> -                exception.printStackTrace();
>> -            }
>> -        }
>> -
>> -        DisplayHost displayHost =  
>> applicationContext.getDisplayHost();
>> -
>>        // Create the windowed host frame
>> -        //windowedHostFrame = new HostFrame();
>> -        windowedHostFrame.add(displayHost);
>> +        windowedHostFrame.add(getDisplayHost());
>>
>>        windowedHostFrame.setTitle(DEFAULT_HOST_FRAME_TITLE);
>>
>> -        windowedHostFrame.setSize(width, height);
>> -        windowedHostFrame.setResizable(resizable);
>> -
>> -        if (center) {
>> -            java.awt.Dimension screenSize =  
>> java.awt.Toolkit.getDefaultToolkit().getScreenSize();
>> -            windowedHostFrame.setLocation((screenSize.width -  
>> width) / 2, (screenSize.height - height) / 2);
>> -        } else {
>> -            windowedHostFrame.setLocation(x, y);
>> -        }
>> -
>>        // Add a key listener to the display host to toggle between  
>> full-screen
>>        // and windowed mode
>> -        displayHost.addKeyListener(new KeyAdapter() {
>> +        getDisplayHost().addKeyListener(new KeyAdapter() {
>> +
>>            public void keyPressed(KeyEvent keyEvent) {
>> -                if (keyEvent.getKeyCode() == KeyEvent.VK_F
>> -                    && (keyEvent.getModifiersEx() &  
>> KeyEvent.CTRL_DOWN_MASK) > 0
>> -                    && (keyEvent.getModifiersEx() &  
>> KeyEvent.SHIFT_DOWN_MASK) > 0) {
>> +                if (keyEvent.getKeyCode() == KeyEvent.VK_F &&  
>> (keyEvent.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) > 0 &&  
>> (keyEvent.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) > 0) {
>>                    setFullScreen(!isFullScreen());
>>                }
>>            }
>>        });
>>
>>        // Create the full-screen host frame
>> -        fullScreenHostFrame = new HostFrame();
>>        fullScreenHostFrame.setUndecorated(true);
>>
>>        // Hook into OS X application menu
>> @@ -328,27 +246,28 @@
>>                Class<?> eawtApplicationEventClass =  
>> Class.forName("com.apple.eawt.ApplicationEvent");
>>
>>                Method setEnabledAboutMenuMethod =  
>> eawtApplicationClass.getMethod("setEnabledAboutMenu",
>> -                    new Class<?>[] {Boolean.TYPE});
>> +                        new Class<?>[]{Boolean.TYPE});
>>
>>                Method addApplicationListenerMethod =  
>> eawtApplicationClass.getMethod("addApplicationListener",
>> -                    new Class<?>[] {eawtApplicationListenerClass});
>> +                        new Class<?>[] 
>> {eawtApplicationListenerClass});
>>
>>                final Method setHandledMethod =  
>> eawtApplicationEventClass.getMethod("setHandled",
>> -                    new Class<?>[] {Boolean.TYPE});
>> +                        new Class<?>[]{Boolean.TYPE});
>>
>>                // Create the proxy handler
>>                InvocationHandler handler = new InvocationHandler() {
>> +
>>                    public Object invoke(Object proxy, Method  
>> method, Object[] args)
>>                        throws Throwable {
>>                        String methodName = method.getName();
>> -                        if (methodName.equals("handleAbout"))  {
>> +                        if (methodName.equals("handleAbout")) {
>>                            handleAbout();
>>                        } else if (methodName.equals("handleQuit")) {
>> -                            exit();
>> +                            close();
>>                        }
>>
>>                        // Invoke setHandled(true)
>> -                        setHandledMethod.invoke(args[0], new  
>> Object[] {true});
>> +                        setHandledMethod.invoke(args[0], new  
>> Object[]{true});
>>
>>                        return null;
>>                    }
>> @@ -364,8 +283,8 @@
>>                        new Class[]{eawtApplicationListenerClass},  
>> handler);
>>
>>                // Invoke the addApplicationListener() method with  
>> the proxy listener
>> -                 
>> addApplicationListenerMethod.invoke(eawtApplication, new Object[]  
>> {eawtApplicationListener});
>> -            } catch(Throwable throwable) {
>> +                 
>> addApplicationListenerMethod.invoke(eawtApplication, new Object[] 
>> {eawtApplicationListener});
>> +            } catch (Throwable throwable) {
>>                System.err.println(throwable);
>>            }
>>        }
>> @@ -374,8 +293,10 @@
>>        windowedHostFrame.setVisible(true);
>>
>>        Window.getWindowClassListeners().add(new  
>> WindowClassListener() {
>> +
>>            public void activeWindowChanged(Window  
>> previousActiveWindow) {
>>                ApplicationContext.queueCallback(new Runnable() {
>> +
>>                    public void run() {
>>                        Window activeWindow =  
>> Window.getActiveWindow();
>>
>> @@ -387,7 +308,7 @@
>>
>>                            Image rootIcon = rootOwner.getIcon();
>>                            if (rootIcon instanceof Picture) {
>> -                                Picture rootPicture =  
>> (Picture)rootIcon;
>> +                                Picture rootPicture = (Picture)  
>> rootIcon;
>>                                 
>> windowedHostFrame.setIconImage(rootPicture.getBufferedImage());
>>                            }
>>                        }
>> @@ -401,43 +322,51 @@
>>    }
>>
>>    /**
>> -     * Utility method to make it easier to define <tt>main()</tt>  
>> entry-points
>> -     * into applications. For example:
>> +     * Terminates the application context.
>>     *
>> -     * <code>
>> -     * public class MyApp implements Application {
>> -     *   public static void main(String[] args) throws Exception {
>> -     *     DesktopApplicationContext.main(MyApp.class, args);
>> -     *   }
>> -     * }
>> -     * </code>
>> -     *
>> -     * @param applicationClass
>> -     * @param applicationArgs
>> +     * TODO: the DesktopApplicationContext instance may be reused,  
>> don't exit
>>     */
>> -    public static final void main(Class<? extends Application>  
>> applicationClass,
>> -        String[] applicationArgs) {
>> -        String[] args = new String[applicationArgs.length + 1];
>> -        System.arraycopy(applicationArgs, 0, args, 1,  
>> applicationArgs.length);
>> -        args[0] = applicationClass.getName();
>> -        main(args);
>> +    public void close() {
>> +        boolean shutdown = true;
>> +
>> +        try {
>> +            shutdown = application.shutdown(true);
>> +        } catch (Exception exception) {
>> +            exception.printStackTrace();
>> +            Alert.alert(MessageType.ERROR, exception.getMessage(),  
>> getDisplay());
>>    }
>>
>> +        opened = false;
>> +
>> +        if (shutdown) {
>> +            destroyTimer();
>> +            windowedHostFrame.dispose();
>> +            fullScreenHostFrame.dispose();
>> +            System.exit(0);
>> +        }
>> +    }
>> +
>> +    public boolean isOpened() {
>> +        return opened;
>> +    }
>> +
>>    /**
>>     * Invokes the application's about handler. The application must  
>> implement
>>     * the {@link Application.About} interface.
>> +     *
>> +     * TODO: handle ClassCastException
>>     */
>> -    public static void handleAbout() {
>> +    public void handleAbout() {
>>        assert (application instanceof Application.About);
>>
>> -        Application.About aboutApplication =  
>> (Application.About)application;
>> +        Application.About aboutApplication = (Application.About)  
>> application;
>>        aboutApplication.handleAbout();
>>    }
>>
>>    /**
>>     * Returns the full-screen mode flag.
>>     */
>> -    public static boolean isFullScreen() {
>> +    public boolean isFullScreen() {
>>        return (!windowedHostFrame.isVisible());
>>    }
>>
>> @@ -446,9 +375,9 @@
>>     *
>>     * @param fullScreen
>>     */
>> -    public static void setFullScreen(boolean fullScreen) {
>> +    public void setFullScreen(boolean fullScreen) {
>>        if (fullScreen != isFullScreen()) {
>> -            DisplayHost displayHost =  
>> applicationContext.getDisplayHost();
>> +            DisplayHost displayHost = getDisplayHost();
>>
>>            GraphicsDevice graphicsDevice =
>>                 
>> windowedHostFrame.getGraphicsConfiguration().getDevice();
>>
>>


Mime
View raw message