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