Author: smartini
Date: Thu Oct 27 15:46:12 2011
New Revision: 1189813

URL: http://svn.apache.org/viewvc?rev=1189813&view=rev
Log:
PIVOT-700

Added:
    pivot/trunk/tests/src/org/apache/pivot/tests/SplashScreenTest.java
    pivot/trunk/tests/src/org/apache/pivot/tests/splash.bxml
    pivot/trunk/tests/src/org/apache/pivot/tests/splash.png   (with props)
Modified:
    pivot/trunk/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java

Added: pivot/trunk/tests/src/org/apache/pivot/tests/SplashScreenTest.java
URL: 
http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/SplashScreenTest.java?rev=1189813&view=auto
==============================================================================
--- pivot/trunk/tests/src/org/apache/pivot/tests/SplashScreenTest.java (added)
+++ pivot/trunk/tests/src/org/apache/pivot/tests/SplashScreenTest.java Thu Oct 
27 15:46:12 2011
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.tests;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.SplashScreen;
+import java.util.Date;
+import java.util.Random;
+
+import org.apache.pivot.beans.BXMLSerializer;
+import org.apache.pivot.collections.Map;
+import org.apache.pivot.util.concurrent.Task;
+import org.apache.pivot.util.concurrent.TaskExecutionException;
+import org.apache.pivot.util.concurrent.TaskListener;
+import org.apache.pivot.wtk.Application;
+import org.apache.pivot.wtk.Container;
+import org.apache.pivot.wtk.DesktopApplicationContext;
+import org.apache.pivot.wtk.Display;
+import org.apache.pivot.wtk.Meter;
+import org.apache.pivot.wtk.Orientation;
+import org.apache.pivot.wtk.TaskAdapter;
+import org.apache.pivot.wtk.Window;
+
+/**
+ * Test Application for demonstrating the <code>--preserveSplashScreen</code>
+ * Pivot startup property.<br/>
+ *
+ * This desktop application simulates some task processing while a SplashScreen
+ * is displayed, before forcing the Pivot host window to become visible which 
in
+ * turn hides the SplashScreen.<br/>The progress of the simulated tasks is 
shown
+ * using a Pivot Meter that paints onto the SplashScreen as the tasks
+ * 'complete'. <br/><br/>
+ *
+ * If <code>--preserveSplashScreen</code> is set to <code>true</code> and there
+ * is a SplashScreen, DesktopApplicationContext will not make the Pivot host
+ * window visible until
+ * {@link DesktopApplicationContext#replaceSplashScreen(Display)
+ * replaceSplashScreen(Display)} is called.<br/><br/>
+ *
+ * If <code>--preserveSplashScreen</code> is set to <code>false</code>, is not
+ * supplied, or there is no SplashScreen, DesktopApplicationContext make the
+ * Pivot host window visible as normal. Any calls to
+ * {@link DesktopApplicationContext#replaceSplashScreen(Display)
+ * replaceSplashScreen(Display)} will have no effect.<br/><br/>
+ *
+ * <b>Example usage</b> (all one line)
+ * <pre>
+ * java -classpath bin;
+ *      -splash:bin/org/apache/pivot/tests/splash.png
+ *      org.apache.pivot.tests.SplashScreenTest
+ *      --preserveSplashScreen=true
+ *      --fullScreen=false
+ * </pre>
+ *
+ * @see SplashScreen
+ * @see DesktopApplicationContext#replaceSplashScreen(Display)
+ * @see DesktopApplicationContext#PRESERVE_SPLASH_SCREEN_ARGUMENT
+ */
+public class SplashScreenTest implements Application {
+
+    private static class SplashScreenProgressOverlay {
+        private final SplashScreen splashScreen;
+        private final Meter meter = new Meter(Orientation.HORIZONTAL);
+        private Graphics2D graphics;
+
+        private SplashScreenProgressOverlay() {
+            this.splashScreen = SplashScreen.getSplashScreen();
+            if (splashScreen != null) {
+                configureMeter(256, 16);
+                configureGraphics();
+            }
+            else {
+                System.err.println("Splash Screen not found");
+            }
+        }
+
+        // Increment the Meter by a percentage supplied as a double between
+        // 0.0 and and 1.0 (representing 0% and 100% respectively)
+        private void increment(final double increment) {
+            if (splashScreen == null) {
+                return ;
+            }
+
+            double percentage = meter.getPercentage() + increment;
+            meter.setPercentage(Math.min(percentage, 1.0f));
+            if (splashScreen != null) {
+                meter.paint(graphics);
+                splashScreen.update();
+            }
+            System.out.println(String.format("Completed : %3.0f%%", 
getPercentage() * 100));
+        }
+
+        private double getPercentage() {
+            return meter.getPercentage();
+        }
+
+        private void configureMeter(final int width, final int height) {
+            meter.setSize(width, height);
+            meter.setPercentage(0);
+            meter.getStyles().put("gridFrequency", 1);
+        }
+
+        // Align the Meter on the SplashScreen, centered horizontally,
+        // 10 pixels from the bottom edge
+        private void configureGraphics() {
+            Rectangle splash = splashScreen.getBounds();
+            int x = ((splash.width - meter.getBounds().width) / 2);
+            int y = (splash.height - meter.getBounds().height - 10);
+            graphics = splashScreen.createGraphics();
+            graphics.translate(x, y);
+        }
+    }
+
+
+    @Override
+    public void startup(final Display display, Map<String, String> properties) 
throws Exception {
+
+        System.out.println("Startup the application at " + new Date());
+        System.out.println("To show the Splash Screen, remember to run with 
the arguments: "
+            + "-splash:/org/apache/pivot/tests/splash.png "
+            + "--preserveSplashScreen=true "
+            + ", or no splash screen will be shown"
+        );
+
+        // Create a Task that will load a BXML file and simulate some other
+        // processing while updating a progress meter on the SplashScreen
+        final Task<Void> prepareApplicationTask = new Task<Void>() {
+            final SplashScreenProgressOverlay progressOverlay = new 
SplashScreenProgressOverlay();
+
+            @Override
+            public Void execute() throws TaskExecutionException {
+                // Load the main BXML
+                progressOverlay.increment(0);
+                loadBXML(display, 0.1);
+
+                // Simulate other tasks until the progress meter has been 
filled
+                final Random random = new Random();
+                while (progressOverlay.getPercentage() < 1.0) {
+                    // Short random sleep to simulate some processing
+                    try {
+                        Thread.sleep(random.nextInt(50) + 100);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    // Update the progress meter by a random amount
+                    progressOverlay.increment((1 + random.nextInt(10)) / 
100.0);
+                }
+                return null;
+            }
+
+            // Load the Pivot UI
+            private void loadBXML(final Display display, final double weight) {
+                try {
+                    Window window = (Window) new 
BXMLSerializer().readObject(this.getClass().getResource(
+                        "splash.bxml"));
+                    window.open(display);
+                    progressOverlay.increment(weight);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        };
+
+        // Hide the SplashScreen when the Task finishes by making the Pivot 
host
+        // window visible.
+        final TaskListener<Void> taskListener = new TaskListener<Void>() {
+            @Override
+            public void taskExecuted(Task<Void> task) {
+                finished();
+            }
+
+            @Override
+            public void executeFailed(Task<Void> task) {
+                System.err.println(String.format("Failed\n%s", 
task.getFault()));
+                task.getFault().printStackTrace();
+                finished();
+            }
+
+            private void finished() {
+                DesktopApplicationContext.replaceSplashScreen(display);
+            }
+        };
+
+        // Run the Task asynchronously
+        prepareApplicationTask.execute(new TaskAdapter<Void>(taskListener));
+    }
+
+
+    public static void main(String[] args) {
+        // Allow the BXML to be loaded on a background thread
+        Container.setEventDispatchThreadChecker(null);
+
+        // Start the application
+        DesktopApplicationContext.main(SplashScreenTest.class, args);
+    }
+
+
+    @Override
+    public boolean shutdown(boolean optional) throws Exception {
+        System.out.println("Shutdown the application at " + new Date());
+        return false;
+    }
+
+    @Override
+    public void suspend() throws Exception {
+    }
+
+    @Override
+    public void resume() throws Exception {
+    }
+}

Added: pivot/trunk/tests/src/org/apache/pivot/tests/splash.bxml
URL: 
http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/splash.bxml?rev=1189813&view=auto
==============================================================================
--- pivot/trunk/tests/src/org/apache/pivot/tests/splash.bxml (added)
+++ pivot/trunk/tests/src/org/apache/pivot/tests/splash.bxml Thu Oct 27 
15:46:12 2011
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you under the Apache License,
+Version 2.0 (the "License"); you may not use this file except in
+compliance with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<Window title="Hello BXML!" maximized="true"
+    xmlns:bxml="http://pivot.apache.org/bxml";
+    xmlns="org.apache.pivot.wtk">
+    <Label text="Splash Screen Test"
+        styles="{font:'Arial bold 24', color:'#ff0000', 
+        horizontalAlignment:'center', verticalAlignment:'center'}"
+    />
+</Window>

Added: pivot/trunk/tests/src/org/apache/pivot/tests/splash.png
URL: 
http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/splash.png?rev=1189813&view=auto
==============================================================================
Binary file - no diff available.

Propchange: pivot/trunk/tests/src/org/apache/pivot/tests/splash.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: 
pivot/trunk/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java
URL: 
http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java?rev=1189813&r1=1189812&r2=1189813&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java 
(original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java Thu 
Oct 27 15:46:12 2011
@@ -20,6 +20,7 @@ import java.awt.AWTEvent;
 import java.awt.Graphics;
 import java.awt.GraphicsDevice;
 import java.awt.GraphicsEnvironment;
+import java.awt.SplashScreen;
 import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowEvent;
@@ -373,6 +374,7 @@ public final class DesktopApplicationCon
     public static final String MAXIMIZED_ARGUMENT = "maximized";
     public static final String UNDECORATED_ARGUMENT = "undecorated";
     public static final String FULL_SCREEN_ARGUMENT = "fullScreen";
+    public static final String PRESERVE_SPLASH_SCREEN_ARGUMENT = 
"preserveSplashScreen";
     public static final String ORIGIN_ARGUMENT = "origin";
 
     private static final String INVALID_PROPERTY_FORMAT_MESSAGE = "\"%s\" is 
not a valid startup "
@@ -471,6 +473,7 @@ public final class DesktopApplicationCon
         boolean maximized = false;
         boolean undecorated = false;
         boolean fullScreen = false;
+        boolean preserveSplashScreen = false;
 
         try {
             Preferences preferences = 
Preferences.userNodeForPackage(DesktopApplicationContext.class);
@@ -527,6 +530,8 @@ public final class DesktopApplicationCon
                             undecorated = Boolean.parseBoolean(value);
                         } else if (key.equals(FULL_SCREEN_ARGUMENT)) {
                             fullScreen = Boolean.parseBoolean(value);
+                        } else if 
(key.equals(PRESERVE_SPLASH_SCREEN_ARGUMENT)) {
+                            preserveSplashScreen = Boolean.parseBoolean(value);
                         } else if (key.equals(ORIGIN_ARGUMENT)) {
                             origin = new URL(value);
                         } else {
@@ -607,8 +612,11 @@ public final class DesktopApplicationCon
             // Initialize OS-specific extensions
             initializeOSExtensions();
 
-            // Show the appropriate host window
-            setFullScreen(fullScreen);
+            // Don't make the window visible if there is a SplashScreen that 
the
+            // application intends to use
+            boolean visible = (!preserveSplashScreen || 
SplashScreen.getSplashScreen() == null);
+            // Initial configuration of the windows
+            setFullScreen(fullScreen, visible);
 
             // Start the application in a callback to allow the host window to
             // open first
@@ -715,6 +723,10 @@ public final class DesktopApplicationCon
      * @param fullScreen
      */
     public static void setFullScreen(boolean fullScreen) {
+        setFullScreen(fullScreen, true);
+    }
+
+    private static void setFullScreen(boolean fullScreen, boolean visible) {
         GraphicsDevice graphicsDevice = 
windowedHostFrame.getGraphicsConfiguration().getDevice();
 
         if (fullScreen) {
@@ -725,11 +737,19 @@ public final class DesktopApplicationCon
 
             windowedHostFrame.setVisible(false);
 
-            graphicsDevice.setFullScreenWindow(fullScreenHostFrame);
+            // Setting the full screen window now will cause a SplashScreen to
+            // be dismissed, so don't do so if the --preserveSplashScreen
+            // startup property was true, and a SplashScreen was supplied.
+            // When the SplashScreen needs to be dismissed, users can call
+            // replaceSplashScreen(Display) which will set the full screen
+            // window, if required.
+            if (visible) {
+                graphicsDevice.setFullScreenWindow(fullScreenHostFrame);
+            }
 
             fullScreenHostFrame.add(primaryDisplayHost);
             fullScreenHostFrame.setTitle(windowedHostFrame.getTitle());
-            fullScreenHostFrame.setVisible(true);
+            fullScreenHostFrame.setVisible(visible);
         } else {
             // Go to windowed mode
             if (fullScreenHostFrame.isVisible()) {
@@ -742,13 +762,33 @@ public final class DesktopApplicationCon
 
             windowedHostFrame.add(primaryDisplayHost);
             windowedHostFrame.setTitle(fullScreenHostFrame.getTitle());
-            windowedHostFrame.setVisible(true);
+            windowedHostFrame.setVisible(visible);
         }
 
         primaryDisplayHost.requestFocusInWindow();
     }
 
     /**
+     * Gets the window hosting the specified Display and makes it visible.</br>
+     * This will cause a visible {@link SplashScreen} to be closed.<br/> It is
+     * intended to be called one time when the Pivot application has 
initialised
+     * its UI and the SplashScreen is ready to be dismissed, but can be safely
+     * called regardless of whether there is now, or used to be, a visible
+     * SplashScreen.
+     *
+     * @param display Display to make visible
+     * @see java.awt.SplashScreen
+     */
+    public static void replaceSplashScreen(Display display) {
+        java.awt.Window hostWindow = display.getHostWindow();
+        GraphicsDevice device = 
windowedHostFrame.getGraphicsConfiguration().getDevice();
+        if ((hostWindow == fullScreenHostFrame) && 
(device.getFullScreenWindow() == null)) {
+            device.setFullScreenWindow(fullScreenHostFrame);
+        }
+        hostWindow.setVisible(true);
+    }
+
+    /**
      * Sizes the window's native host frame to match its preferred size.
      *
      * @param window


Reply via email to