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" <[email protected] > 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();



Reply via email to