aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Vanek <[email protected]>2012-11-02 12:22:09 +0100
committerJiri Vanek <[email protected]>2012-11-02 12:22:09 +0100
commit489f58fa0aa123f73f9903180691ac4531d1d989 (patch)
tree3ca320545e62c6463dd94b962aff134d4c00aab1
parent70681430e560a92c59175e7894ccc7820b33ee71 (diff)
Splashscreen integrated to javaws and plugin
-rw-r--r--ChangeLog37
-rw-r--r--Makefile.am2
-rw-r--r--NEWS1
-rw-r--r--launcher/javaws.in12
-rw-r--r--netx/javaws_splash.pngbin0 -> 12142 bytes
-rw-r--r--netx/net/sourceforge/jnlp/GuiLaunchHandler.java63
-rw-r--r--netx/net/sourceforge/jnlp/JNLPSplashScreen.java107
-rw-r--r--netx/net/sourceforge/jnlp/Launcher.java75
-rw-r--r--netx/net/sourceforge/jnlp/NetxPanel.java36
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginAppletViewer.java181
-rw-r--r--tests/reproducers/simple/CountingApplet1/resources/ParallelAppletsTest_1_x_2.html2
-rw-r--r--tests/reproducers/simple/simpletest1/resources/netxPlugin.pngbin0 -> 47818 bytes
12 files changed, 416 insertions, 100 deletions
diff --git a/ChangeLog b/ChangeLog
index 6daf009..97bfa21 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2012-11-02 Jiri Vanek <[email protected]>
+
+ Splashscreen integrated to javaws and plugin
+ * Makefile.am: (edit_launcher_script) added JAVAWS_SPLASH_LOCATION
+ substitution for installed javaws_splash.png.
+ (install-exec-loca) added installation of javaws_splash.png.
+ * NEWS: mentioned splashscreen
+ * launcher/javaws.in: added SPLASH_LOCATION, as path to image with "java"
+ splash which s then shown until internal vector one appear.
+ * netx/net/sourceforge/jnlp/GuiLaunchHandler.java: splashScreen made volatile,
+ (launchInitialized) splashscreen is created and shown
+ * netx/net/sourceforge/jnlp/JNLPSplashScreen.java: (setSplashImageURL)
+ splash bg image is loaded from given url or default is used if not found
+ or not specified by jnlp/applet. (correctSize) width is calculated from
+ bg image or default is used when no image set. Splash is centered to
+ primary monitor.
+ * netx/net/sourceforge/jnlp/Launcher.java: (launchApplet) and
+ (launchApplication) enriched by handling of splashs.
+ (launchError) overloaded and is now handling forwarding of errors to
+ splash. All relevant calls of launchError enriched by appletInstance.
+ * netx/net/sourceforge/jnlp/NetxPanel.java: is now implementing
+ SplashController.This is done by setting and wrapping of splashController
+ variable.
+ * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java: is now handling
+ splashscreen for applets in browsers.
+ (framePanel) is now providing panel to be processed (PluginAppletViewer)
+ is now invoking SplashCreator. (replaceSplash) new method which replace
+ splashscreen with error splashscreen. (removeSplash) new method to remove
+ splash when loading is done. (update) is added to call paint directly
+ (SplashCreator) new internal runnable to create splash
+ * tests/reproducers/simple/CountingApplet1/resources/ParallelAppletsTest_1_x_2.html:
+ second jar made XslowX to track two FIXME introduced in this patch -
+ Launcher's createApplet and PluginAppletViewer's framePanel.
+ * netx/javaws_splash.png: Binary image to be shown before java is launched
+ * tests/reproducers/simple/simpletest1/resources/netxPlugin.png: Binary image
+ to ne used for testing custom splashscreens
+
2012-10-31 Jana Fabrikova <[email protected]>
*tests/reproducers/simple/JSToJGet/testcases/JSToJGetTest.java:
diff --git a/Makefile.am b/Makefile.am
index 89579c7..563a477 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -178,6 +178,7 @@ itweb_settings:= $(shell echo itweb-settings | sed '@program_transform_name@')
edit_launcher_script = sed \
-e 's|[@]LAUNCHER_BOOTCLASSPATH[@]|$(LAUNCHER_BOOTCLASSPATH)|g' \
-e 's|[@]JAVAWS_BIN_LOCATION[@]|$(bindir)/$(javaws)|g' \
+ -e 's|[@]JAVAWS_SPLASH_LOCATION[@]|$(datadir)/$(PACKAGE_NAME)/javaws_splash.png|g' \
-e 's|[@]ITWEB_SETTINGS_BIN_LOCATION[@]|$(bindir)/$(itweb_settings)|g' \
-e 's|[@]JAVA[@]|$(JAVA)|g' \
-e 's|[@]JRE[@]|$(SYSTEM_JRE_DIR)|g'
@@ -208,6 +209,7 @@ if ENABLE_PLUGIN
${INSTALL_DATA} $(abs_top_builddir)/liveconnect/lib/classes.jar $(DESTDIR)$(datadir)/$(PACKAGE_NAME)/plugin.jar
endif
${INSTALL_DATA} $(NETX_DIR)/lib/classes.jar $(DESTDIR)$(datadir)/$(PACKAGE_NAME)/netx.jar
+ ${INSTALL_DATA} $(NETX_SRCDIR)/javaws_splash.png $(DESTDIR)$(datadir)/$(PACKAGE_NAME)/javaws_splash.png
${INSTALL_PROGRAM} launcher.build/$(javaws) $(DESTDIR)$(bindir)
${INSTALL_DATA} extra-lib/about.jar $(DESTDIR)$(datadir)/$(PACKAGE_NAME)/about.jar
${INSTALL_PROGRAM} launcher.build/$(itweb_settings) $(DESTDIR)$(bindir)
diff --git a/NEWS b/NEWS
index 26cbd0b..a829e1e 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ GX - http://bugs.gentoo.org/show_bug.cgi?id=X
CVE-XXXX-YYYY: http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY
New in release 1.4 (2012-XX-XX):
+* Splash screen for javaws and plugin
* Security updates
- CVE-2012-3422, RH840592: Potential read from an uninitialized memory location
- CVE-2012-3423, RH841345: Incorrect handling of not 0-terminated strings
diff --git a/launcher/javaws.in b/launcher/javaws.in
index e0e0fca..ae9a24d 100644
--- a/launcher/javaws.in
+++ b/launcher/javaws.in
@@ -5,6 +5,7 @@ LAUNCHER_BOOTCLASSPATH=@LAUNCHER_BOOTCLASSPATH@
LAUNCHER_FLAGS=-Xms8m
CLASSNAME=net.sourceforge.jnlp.runtime.Boot
BINARY_LOCATION=@JAVAWS_BIN_LOCATION@
+SPLASH_LOCATION=@JAVAWS_SPLASH_LOCATION@
PROGRAM_NAME=javaws
CP=@JRE@/lib/rt.jar
@@ -15,6 +16,10 @@ COMMAND=()
i=0
j=0
+SPLASH="false"
+if [ "x$ICEDTEA_WEB_SPLASH" = "x" ] ; then
+SPLASH="true"
+fi;
while [ "$#" -gt "0" ]; do
case "$1" in
-J*)
@@ -24,6 +29,9 @@ while [ "$#" -gt "0" ]; do
*)
ARGS[$j]="$1"
j=$((j+1))
+ if [ "$1" = "-headless" ] ; then
+ SPLASH="false"
+ fi
;;
esac
shift
@@ -32,6 +40,10 @@ done
k=0
COMMAND[k]="${JAVA}"
k=$((k+1))
+if [ "$SPLASH" = "true" ] ; then
+COMMAND[k]="-splash:${SPLASH_LOCATION}"
+k=$((k+1))
+fi;
COMMAND[k]="${LAUNCHER_BOOTCLASSPATH}"
k=$((k+1))
COMMAND[k]="${LAUNCHER_FLAGS}"
diff --git a/netx/javaws_splash.png b/netx/javaws_splash.png
new file mode 100644
index 0000000..62111e9
--- /dev/null
+++ b/netx/javaws_splash.png
Binary files differ
diff --git a/netx/net/sourceforge/jnlp/GuiLaunchHandler.java b/netx/net/sourceforge/jnlp/GuiLaunchHandler.java
index ad8ba96..74960f0 100644
--- a/netx/net/sourceforge/jnlp/GuiLaunchHandler.java
+++ b/netx/net/sourceforge/jnlp/GuiLaunchHandler.java
@@ -1,5 +1,5 @@
/* GuiLaunchHandler.java
- Copyright (C) 2011 Red Hat, Inc.
+ Copyright (C) 2012 Red Hat, Inc.
This file is part of IcedTea.
@@ -54,7 +54,7 @@ import net.sourceforge.jnlp.util.BasicExceptionDialog;
*/
public class GuiLaunchHandler extends AbstractLaunchHandler {
- private JNLPSplashScreen splashScreen = null;
+ private volatile JNLPSplashScreen splashScreen = null;
private final Object mutex = new Object();
private UpdatePolicy policy = UpdatePolicy.ALWAYS;
@@ -80,10 +80,11 @@ public class GuiLaunchHandler extends AbstractLaunchHandler {
}
private void closeSplashScreen() {
- synchronized(mutex) {
+ synchronized (mutex) {
if (splashScreen != null) {
if (splashScreen.isSplashScreenValid()) {
splashScreen.setVisible(false);
+ splashScreen.stopAnimation();
}
splashScreen.dispose();
}
@@ -102,40 +103,56 @@ public class GuiLaunchHandler extends AbstractLaunchHandler {
@Override
public void launchInitialized(final JNLPFile file) {
-
+
int preferredWidth = 500;
int preferredHeight = 400;
final URL splashImageURL = file.getInformation().getIconLocation(
IconDesc.SPLASH, preferredWidth, preferredHeight);
+ final ResourceTracker resourceTracker = new ResourceTracker(true);
if (splashImageURL != null) {
- final ResourceTracker resourceTracker = new ResourceTracker(true);
resourceTracker.addResource(splashImageURL, file.getFileVersion(), null, policy);
- synchronized(mutex) {
- try {
- SwingUtilities.invokeAndWait(new Runnable() {
- @Override
- public void run() {
- splashScreen = new JNLPSplashScreen(resourceTracker, file);
- }
- });
- } catch (InterruptedException ie) {
- // Wait till splash screen is created
- while (splashScreen == null);
- } catch (InvocationTargetException ite) {
- ite.printStackTrace();
- }
+ }
+ synchronized (mutex) {
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ splashScreen = new JNLPSplashScreen(resourceTracker, file);
+ }
+ });
+ } catch (InterruptedException ie) {
+ // Wait till splash screen is created
+ while (splashScreen == null);
+ } catch (InvocationTargetException ite) {
+ ite.printStackTrace();
+ }
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
- splashScreen.setSplashImageURL(splashImageURL);
+ @Override
+ public void run() {
+ splashScreen.setSplashImageURL(splashImageURL);
+ }
+ });
+ } catch (InterruptedException ie) {
+ // Wait till splash screen is created
+ while (!splashScreen.isSplashImageLoaded());
+ } catch (InvocationTargetException ite) {
+ ite.printStackTrace();
}
+
+
}
-
+
SwingUtilities.invokeLater(new Runnable() {
+
@Override
public void run() {
- if (splashImageURL != null) {
- synchronized(mutex) {
+ if (splashScreen != null) {
+ synchronized (mutex) {
if (splashScreen.isSplashScreenValid()) {
splashScreen.setVisible(true);
}
diff --git a/netx/net/sourceforge/jnlp/JNLPSplashScreen.java b/netx/net/sourceforge/jnlp/JNLPSplashScreen.java
index 212696a..77698db 100644
--- a/netx/net/sourceforge/jnlp/JNLPSplashScreen.java
+++ b/netx/net/sourceforge/jnlp/JNLPSplashScreen.java
@@ -43,19 +43,16 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
-import java.awt.Toolkit;
import java.io.IOException;
import java.net.URL;
-
import javax.imageio.ImageIO;
import javax.swing.JDialog;
-
import net.sourceforge.jnlp.cache.ResourceTracker;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
-import net.sourceforge.jnlp.util.ImageResources;
import net.sourceforge.jnlp.splashscreen.SplashPanel;
import net.sourceforge.jnlp.splashscreen.SplashUtils;
import net.sourceforge.jnlp.splashscreen.parts.InformationElement;
+import net.sourceforge.jnlp.util.ImageResources;
public class JNLPSplashScreen extends JDialog {
@@ -68,6 +65,7 @@ public class JNLPSplashScreen extends JDialog {
public static final int DEF_WIDTH=635;
public static final int DEF_HEIGHT=480;
private SplashPanel componetSplash;
+ private boolean splashImageLoaded=false;
public JNLPSplashScreen(ResourceTracker resourceTracker, final JNLPFile file) {
@@ -78,61 +76,86 @@ public class JNLPSplashScreen extends JDialog {
// JNLP file.
this.resourceTracker = resourceTracker;
-
- this.file=file;
+ this.file=file;
}
public void setSplashImageURL(URL url) {
- splashImageUrl = url;
- splashImage = null;
+ splashImageLoaded = false;
try {
- splashImage = ImageIO.read(resourceTracker
- .getCacheFile(splashImageUrl));
- if (splashImage == null) {
- if (JNLPRuntime.isDebug()) {
- System.err.println("Error loading splash image: " + url);
+ if (url != null) {
+ splashImageUrl = url;
+ splashImage = null;
+ try {
+ splashImage = ImageIO.read(resourceTracker.getCacheFile(splashImageUrl));
+ if (splashImage == null) {
+ if (JNLPRuntime.isDebug()) {
+ System.err.println("Error loading splash image: " + url);
+ }
+ }
+ } catch (IOException e) {
+ if (JNLPRuntime.isDebug()) {
+ System.err.println("Error loading splash image: " + url);
+ }
+ splashImage = null;
+ } catch (IllegalArgumentException argumentException) {
+ if (JNLPRuntime.isDebug()) {
+ System.err.println("Error loading splash image: " + url);
+ }
+ splashImage = null;
}
- return;
}
- } catch (IOException e) {
- if (JNLPRuntime.isDebug()) {
- System.err.println("Error loading splash image: " + url);
- }
- splashImage = null;
- return;
- } catch (IllegalArgumentException argumentException) {
- if (JNLPRuntime.isDebug()) {
- System.err.println("Error loading splash image: " + url);
+
+ if (splashImage == null) {
+ this.setLayout(new BorderLayout());
+ SplashPanel splash = SplashUtils.getSplashScreen(DEF_WIDTH, DEF_HEIGHT);
+ if (splash != null) {
+ splash.startAnimation();
+ splash.setInformationElement(InformationElement.createFromJNLP(file));
+ this.add(splash.getSplashComponent());
+ this.componetSplash = splash;
+ }
}
- splashImage = null;
- return;
+ correctSize();
+ } finally {
+ splashImageLoaded = true;
}
+ }
- correctSize();
+ public boolean isSplashImageLoaded() {
+ return splashImageLoaded;
}
+
public boolean isSplashScreenValid() {
- return (splashImage != null);
+ return (splashImage != null) || (componetSplash != null);
}
private void correctSize() {
-
- Insets insets = getInsets();
- int minimumWidth = splashImage.getWidth(null) + insets.left
- + insets.right;
- int minimumHeight = splashImage.getHeight(null) + insets.top
- + insets.bottom;
- setMinimumSize(new Dimension(minimumWidth, minimumHeight));
-
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- setLocation((screenSize.width - minimumWidth) / 2,
- (screenSize.height - minimumHeight) / 2);
+ int minimumWidth = DEF_WIDTH;
+ int minimumHeight = DEF_HEIGHT;
+ if (splashImage != null) {
+ Insets insets = getInsets();
+ minimumWidth = splashImage.getWidth(null) + insets.left
+ + insets.right;
+ minimumHeight = splashImage.getHeight(null) + insets.top
+ + insets.bottom;
+ }
+ setMinimumSize(new Dimension(0, 0));
+ setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
+ setSize(new Dimension(minimumWidth, minimumHeight));
+ setPreferredSize(new Dimension(minimumWidth, minimumHeight));
+ // Centering to middle of Toolkit.getDefaultToolkit().getScreenSize()
+ // centers to the middle of all monitors. Let's center to the middle
+ // of the primary monitor instead.
+ // TODO center on the 'current' monitor to meet user expectation
+ setLocationRelativeTo(null);
}
@Override
public void paint(Graphics g) {
if (splashImage == null) {
+ super.paint(g);
return;
}
@@ -141,4 +164,12 @@ public class JNLPSplashScreen extends JDialog {
g2.drawImage(splashImage, getInsets().left, getInsets().top, null);
}
+
+ public boolean isCustomSplashscreen() {
+ return (componetSplash!=null);
+ }
+
+ public void stopAnimation() {
+ if (isCustomSplashscreen()) componetSplash.stopAnimation();
+ }
}
diff --git a/netx/net/sourceforge/jnlp/Launcher.java b/netx/net/sourceforge/jnlp/Launcher.java
index 1692b0e..c6712cd 100644
--- a/netx/net/sourceforge/jnlp/Launcher.java
+++ b/netx/net/sourceforge/jnlp/Launcher.java
@@ -20,6 +20,7 @@ import static net.sourceforge.jnlp.runtime.Translator.R;
import java.applet.Applet;
import java.awt.Container;
+import java.awt.SplashScreen;
import java.io.File;
import java.lang.reflect.Method;
import java.net.InetAddress;
@@ -42,6 +43,8 @@ import net.sourceforge.jnlp.services.ServiceUtil;
import javax.swing.SwingUtilities;
import javax.swing.text.html.parser.ParserDelegator;
+import net.sourceforge.jnlp.runtime.AppletEnvironment;
+import net.sourceforge.jnlp.splashscreen.SplashUtils;
import sun.awt.SunToolkit;
@@ -543,6 +546,12 @@ public class Launcher {
}
if (JNLPRuntime.getForksAllowed() && file.needsNewVM()) {
+ if (!JNLPRuntime.isHeadless()){
+ SplashScreen sp = SplashScreen.getSplashScreen();
+ if (sp!=null) {
+ sp.close();
+ }
+ }
List<String> netxArguments = new LinkedList<String>();
netxArguments.add("-Xnofork");
netxArguments.addAll(JNLPRuntime.getInitialArguments());
@@ -652,25 +661,42 @@ public class Launcher {
* @param enableCodeBase whether to add the codebase URL to the classloader
*/
protected ApplicationInstance launchApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
- if (!file.isApplet())
+ if (!file.isApplet()) {
throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LNotApplet"), R("LNotAppletInfo")));
-
+ }
+
+ if (JNLPRuntime.getForksAllowed() && file.needsNewVM()) {
+ if (!JNLPRuntime.isHeadless()) {
+ SplashScreen sp = SplashScreen.getSplashScreen();
+ if (sp != null) {
+ sp.close();
+ }
+ }
+ }
+ if (handler != null) {
+ handler.launchInitialized(file);
+ }
+
+ AppletInstance applet = null;
try {
ServiceUtil.checkExistingSingleInstance(file);
- AppletInstance applet = createApplet(file, enableCodeBase, cont);
+ applet = createApplet(file, enableCodeBase, cont);
applet.initialize();
-
applet.getAppletEnvironment().startApplet(); // this should be a direct call to applet instance
return applet;
} catch (InstanceExistsException ieex) {
if (JNLPRuntime.isDebug()) {
System.out.println("Single instance applet is already running.");
}
- throw launchError(new LaunchException(file, ieex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LSingleInstanceExists")));
+ throw launchError(new LaunchException(file, ieex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LSingleInstanceExists")), applet);
} catch (LaunchException lex) {
- throw launchError(lex);
+ throw launchError(lex, applet);
} catch (Exception ex) {
- throw launchError(new LaunchException(file, ex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LCouldNotLaunchInfo")));
+ throw launchError(new LaunchException(file, ex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LCouldNotLaunchInfo")), applet);
+ }finally{
+ if (handler != null) {
+ handler.launchStarting(applet);
+ }
}
}
@@ -678,13 +704,13 @@ public class Launcher {
* Gets an ApplicationInstance, but does not launch the applet.
*/
protected ApplicationInstance getApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
- if (!file.isApplet())
+ if (!file.isApplet()) {
throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LNotApplet"), R("LNotAppletInfo")));
-
+ }
+ AppletInstance applet = null;
try {
ServiceUtil.checkExistingSingleInstance(file);
-
- AppletInstance applet = createApplet(file, enableCodeBase, cont);
+ applet = createApplet(file, enableCodeBase, cont);
applet.initialize();
return applet;
@@ -692,11 +718,11 @@ public class Launcher {
if (JNLPRuntime.isDebug()) {
System.out.println("Single instance applet is already running.");
}
- throw launchError(new LaunchException(file, ieex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LSingleInstanceExists")));
+ throw launchError(new LaunchException(file, ieex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LSingleInstanceExists")), applet);
} catch (LaunchException lex) {
- throw launchError(lex);
+ throw launchError(lex, applet);
} catch (Exception ex) {
- throw launchError(new LaunchException(file, ex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LCouldNotLaunchInfo")));
+ throw launchError(new LaunchException(file, ex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LCouldNotLaunchInfo")), applet);
}
}
@@ -715,8 +741,13 @@ public class Launcher {
*
* @param enableCodeBase whether to add the code base URL to the classloader
*/
- protected AppletInstance createApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
- try {
+ //FIXME - when multiple applets are on one page, this method is visited simultaneously
+ //and then appelts creates in little bit strange manner. This issue is visible with
+ //randomly showing/notshowing spalshscreens.
+ //See also PluginAppletViewer.framePanel
+ protected AppletInstance createApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
+ AppletInstance appletInstance = null;
+ try {
JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
if (enableCodeBase) {
@@ -730,7 +761,6 @@ public class Launcher {
// appletInstance is needed by ServiceManager when looking up
// services. This could potentially be done in applet constructor
// so initialize appletInstance before creating applet.
- AppletInstance appletInstance;
if (cont == null)
appletInstance = new AppletInstance(file, group, loader, null);
else
@@ -751,7 +781,7 @@ public class Launcher {
return appletInstance;
} catch (Exception ex) {
- throw launchError(new LaunchException(file, ex, R("LSFatal"), R("LCInit"), R("LInitApplet"), R("LInitAppletInfo")));
+ throw launchError(new LaunchException(file, ex, R("LSFatal"), R("LCInit"), R("LInitApplet"), R("LInitAppletInfo")), appletInstance);
}
}
@@ -822,6 +852,13 @@ public class Launcher {
* caller.
*/
private LaunchException launchError(LaunchException ex) {
+ return launchError(ex, null);
+ }
+
+ private LaunchException launchError(LaunchException ex, AppletInstance applet) {
+ if (applet != null) {
+ SplashUtils.showErrorCaught(ex, applet);
+ }
if (handler != null)
handler.launchError(ex);
@@ -861,7 +898,7 @@ public class Launcher {
new ParserDelegator();
}
- /**
+ /**
* This runnable is used to call the appropriate launch method
* for the application, applet, or installer in its thread group.
*/
diff --git a/netx/net/sourceforge/jnlp/NetxPanel.java b/netx/net/sourceforge/jnlp/NetxPanel.java
index 59c3ce0..f6496b6 100644
--- a/netx/net/sourceforge/jnlp/NetxPanel.java
+++ b/netx/net/sourceforge/jnlp/NetxPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Red Hat, Inc.
+ * Copyright 2012 Red Hat, Inc.
* This file is part of IcedTea, http://icedtea.classpath.org
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -22,7 +22,6 @@
package net.sourceforge.jnlp;
-import net.sourceforge.jnlp.AppletLog;
import net.sourceforge.jnlp.runtime.AppletInstance;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
@@ -32,6 +31,8 @@ import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import net.sourceforge.jnlp.splashscreen.SplashController;
+import net.sourceforge.jnlp.splashscreen.SplashPanel;
import sun.applet.AppletViewerPanel;
import sun.awt.SunToolkit;
@@ -42,10 +43,11 @@ import sun.awt.SunToolkit;
*
* @author Francis Kung <[email protected]>
*/
-public class NetxPanel extends AppletViewerPanel {
+public class NetxPanel extends AppletViewerPanel implements SplashController {
private PluginBridge bridge = null;
private boolean exitOnFailure = true;
private AppletInstance appInst = null;
+ private SplashController splashController;
private boolean appletAlive;
private final String uKey;
@@ -232,4 +234,32 @@ public class NetxPanel extends AppletViewerPanel {
SunToolkit.createNewAppContext();
}
}
+
+
+
+
+ public void setAppletViewerFrame(SplashController framePanel) {
+ splashController=framePanel;
+ }
+
+ @Override
+ public void removeSplash() {
+ splashController.removeSplash();
+ }
+
+ @Override
+ public void replaceSplash(SplashPanel r) {
+ splashController.replaceSplash(r);
+ }
+
+ @Override
+ public int getSplashWidth() {
+ return splashController.getSplashWidth();
+ }
+
+ @Override
+ public int getSplashHeigth() {
+ return splashController.getSplashHeigth();
+ }
+
}
diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
index b901074..974c2e4 100644
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
@@ -76,6 +76,7 @@ import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
+import java.awt.Component;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
@@ -93,10 +94,8 @@ import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
-import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -115,6 +114,11 @@ import sun.awt.X11.XEmbeddedFrame;
import sun.misc.Ref;
import com.sun.jndi.toolkit.url.UrlUtil;
+import java.util.Hashtable;
+import java.util.Vector;
+import net.sourceforge.jnlp.splashscreen.SplashController;
+import net.sourceforge.jnlp.splashscreen.SplashPanel;
+import net.sourceforge.jnlp.splashscreen.SplashUtils;
/**
* Lets us construct one using unix-style one shot behaviors
@@ -141,11 +145,15 @@ class PluginAppletPanelFactory {
// isn't the case, the awt eventqueue thread's context classloader
// won't be set to a JNLPClassLoader, and when an applet class needs
// to be loaded from the awt eventqueue, it won't be found.
+ final int width = Integer.parseInt(atts.get("width"));
+ final int height = Integer.parseInt(atts.get("height"));
Thread panelInit = new Thread(panel.getThreadGroup(), new Runnable() {
@Override public void run() {
panel.createNewAppContext();
// create the frame.
- PluginAppletViewer.framePanel(identifier, handle, panel);
+ PluginDebug.debug("X and Y are: " + width + " " + height);
+ panel.setAppletViewerFrame(PluginAppletViewer.framePanel(identifier,handle, width, height, panel));
+
panel.init();
// Start the applet
initEventQueue(panel);
@@ -185,7 +193,7 @@ class PluginAppletPanelFactory {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- panel.getParent().setSize(Integer.valueOf(atts.get("width")), Integer.valueOf(atts.get("height")));
+ panel.getParent().setSize(width, height);
}
});
} catch (InvocationTargetException ite) {
@@ -198,6 +206,8 @@ class PluginAppletPanelFactory {
ie.printStackTrace();
}
+ panel.removeSplash();
+
AppletSecurityContextManager.getSecurityContext(0).associateSrc(panel.getAppletClassLoader(), doc);
AppletSecurityContextManager.getSecurityContext(0).associateInstance(identifier, panel.getAppletClassLoader());
@@ -271,7 +281,7 @@ class PluginAppletPanelFactory {
// FIXME: declare JSProxy implementation
@SuppressWarnings("serial")
public class PluginAppletViewer extends XEmbeddedFrame
- implements AppletContext, Printable {
+ implements AppletContext, Printable, SplashController {
/**
* Enumerates the current status of an applet
@@ -323,26 +333,36 @@ public class PluginAppletViewer extends XEmbeddedFrame
private Image bufFrameImg;
private Graphics bufFrameImgGraphics;
+
+ private SplashPanel splashPanel;
+
/**
* Null constructor to allow instantiation via newInstance()
*/
public PluginAppletViewer() {
}
- public static void framePanel(int identifier, long handle, NetxPanel panel) {
+ //FIXME - when multiple applets are on one page, this method is visited simultaneously
+ //and then appelts creates in little bit strange manner. This issue is visible with
+ //randomly showing/notshowing spalshscreens.
+ //See also Launcher.createApplet
+ public static PluginAppletViewer framePanel(int identifier,long handle, int width, int height, NetxPanel panel) {
PluginDebug.debug("Framing ", panel);
-
- // SecurityManager MUST be set, and only privileged code may call reFrame()
+
+ // SecurityManager MUST be set, and only privileged code may call framePanel()
System.getSecurityManager().checkPermission(new AllPermission());
PluginAppletViewer appletFrame = new PluginAppletViewer(handle, identifier, panel);
-
- appletFrame.add("Center", panel);
- appletFrame.pack();
-
+
appletFrame.appletEventListener = new AppletEventListener(appletFrame, appletFrame);
panel.addAppletListener(appletFrame.appletEventListener);
+ // Clear references, if any
+ if (applets.containsKey(identifier)) {
+ PluginAppletViewer oldFrame = applets.get(identifier);
+ oldFrame.remove(panel);
+ panel.removeAppletListener(oldFrame.appletEventListener);
+ }
appletsLock.lock();
applets.put(identifier, appletFrame);
@@ -350,6 +370,7 @@ public class PluginAppletViewer extends XEmbeddedFrame
appletsLock.unlock();
PluginDebug.debug(panel, " framed");
+ return appletFrame;
}
/**
@@ -383,9 +404,88 @@ public class PluginAppletViewer extends XEmbeddedFrame
};
addWindowListener(windowEventListener);
+ final AppletPanel fPanel = panel;
+ try {
+ SwingUtilities.invokeAndWait(new SplashCreator(fPanel));
+ } catch (Exception e) {
+ e.printStackTrace(); // Not much we can do other than print
+ }
+
+ }
+
+ public void replaceSplash(final SplashPanel newSplash) {
+ if (splashPanel == null) {
+ return;
+ }
+ if (newSplash == null) {
+ removeSplash();
+ return;
+ }
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ public void run() {
+ splashPanel.getSplashComponent().setVisible(false);
+ splashPanel.stopAnimation();
+ remove(splashPanel.getSplashComponent());
+ newSplash.setPercentage(splashPanel.getPercentage());
+ newSplash.setSplashWidth(splashPanel.getSplashWidth());
+ newSplash.setSplashHeight(splashPanel.getSplashHeight());
+ newSplash.adjustForSize();
+ splashPanel = newSplash;
+ add("Center", splashPanel.getSplashComponent());
+ pack();
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace(); // Not much we can do other than print
+ }
+ }
+
+ @Override
+ public void removeSplash() {
+ if (splashPanel == null) {
+ return;
+ }
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ public void run() {
+ splashPanel.getSplashComponent().setVisible(false);
+ splashPanel.stopAnimation();
+ remove(splashPanel.getSplashComponent());
+ splashPanel = null;
+ remove(panel);
+ // Re-add the applet to notify container
+ add(panel);
+ panel.setVisible(true);
+ pack();
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace(); // Not much we can do other than print
+ }
+ }
+ @Override
+ public int getSplashWidth() {
+ if (splashPanel != null) {
+ return splashPanel.getSplashWidth();
+ } else {
+ return -1;
+ }
}
+ @Override
+ public int getSplashHeigth() {
+ if (splashPanel != null) {
+ return splashPanel.getSplashHeight();
+ } else {
+ return -1;
+ }
+ }
+
+
private static class AppletEventListener implements AppletListener {
final Frame frame;
final PluginAppletViewer appletViewer;
@@ -401,7 +501,6 @@ public class PluginAppletViewer extends XEmbeddedFrame
panelLock.lock();
panelLive.signalAll();
panelLock.unlock();
-
switch (evt.getID()) {
case AppletPanel.APPLET_RESIZE: {
if (src != null) {
@@ -436,6 +535,23 @@ public class PluginAppletViewer extends XEmbeddedFrame
break;
}
+ case AppletPanel.APPLET_START: {
+ if (src.status != AppletPanel.APPLET_INIT && src.status != AppletPanel.APPLET_STOP) {
+ String s="Applet started, but but reached invalid state";
+ PluginDebug.debug(s);
+ SplashPanel sp=SplashUtils.getErrorSplashScreen(appletViewer.panel.getWidth(), appletViewer.panel.getHeight(), new Exception(s));
+ appletViewer.replaceSplash(sp);
+ }
+
+ break;
+ }
+ case AppletPanel.APPLET_ERROR: {
+ String s="Undefined error causing applet not to staart appeared";
+ PluginDebug.debug(s);
+ SplashPanel sp=SplashUtils.getErrorSplashScreen(appletViewer.panel.getWidth(), appletViewer.panel.getHeight(), new Exception(s));
+ appletViewer.replaceSplash(sp);
+ break;
+ }
}
}
}
@@ -517,6 +633,8 @@ public class PluginAppletViewer extends XEmbeddedFrame
waitForAppletInit(applets.get(identifier).panel);
// Should we proceed with reframing?
+ PluginDebug.debug("Init complete");
+
if (updateStatus(identifier, PAV_INIT_STATUS.REFRAME_COMPLETE).equals(PAV_INIT_STATUS.INACTIVE)) {
destroyApplet(identifier);
return;
@@ -656,6 +774,8 @@ public class PluginAppletViewer extends XEmbeddedFrame
*/
public static void waitForAppletInit(NetxPanel panel) {
+ PluginDebug.debug("Waiting for applet init");
+
// Wait till initialization finishes
long maxTimeToSleep = APPLET_TIMEOUT;
@@ -2103,7 +2223,7 @@ public class PluginAppletViewer extends XEmbeddedFrame
* the parent class's update() just does a couple of checks (both of
* which are accounted for) and then calls paint anyway.
*/
- public void update(Graphics g) {
+ public void paint(Graphics g) {
// If the image or the graphics don't exist, create new ones
if (bufFrameImg == null || bufFrameImgGraphics == null) {
@@ -2112,12 +2232,20 @@ public class PluginAppletViewer extends XEmbeddedFrame
}
// Paint off-screen
- paint(bufFrameImgGraphics);
+ for (Component c: this.getComponents()) {
+ c.paint(bufFrameImgGraphics);
+ }
// Draw the painted image
g.drawImage(bufFrameImg, 0, 0, this);
}
-
+
+
+ @Override
+ public void update(Graphics g) {
+ paint(g);
+ }
+
/**
* Waits on a given condition queue until timeout.
*
@@ -2151,4 +2279,25 @@ public class PluginAppletViewer extends XEmbeddedFrame
// Return the difference
return System.nanoTime() - sleepStart;
}
+
+ private class SplashCreator implements Runnable {
+
+ private final AppletPanel fPanel;
+
+ public SplashCreator(AppletPanel fPanel) {
+ this.fPanel = fPanel;
+ }
+
+ public void run() {
+ add("Center", fPanel);
+ fPanel.setVisible(false);
+ splashPanel = SplashUtils.getSplashScreen(fPanel.getWidth(), fPanel.getHeight());
+ if (splashPanel != null) {
+ splashPanel.startAnimation();
+ PluginDebug.debug("Added splash " + splashPanel);
+ add("Center", splashPanel.getSplashComponent());
+ }
+ pack();
+ }
+ }
}
diff --git a/tests/reproducers/simple/CountingApplet1/resources/ParallelAppletsTest_1_x_2.html b/tests/reproducers/simple/CountingApplet1/resources/ParallelAppletsTest_1_x_2.html
index 23e06f6..7c0a6dd 100644
--- a/tests/reproducers/simple/CountingApplet1/resources/ParallelAppletsTest_1_x_2.html
+++ b/tests/reproducers/simple/CountingApplet1/resources/ParallelAppletsTest_1_x_2.html
@@ -36,7 +36,7 @@ exception statement from your version.
-->
<html><head></head><body bgcolor="blue">
-<p><applet code="CountingApplet1.class" archive="CountingApplet1.jar" codebase="." width="50" height="100">
+<p><applet code="CountingApplet1.class" archive="XslowXCountingApplet1.jar" codebase="." width="50" height="100">
</applet></p>
<p><applet code="CountingApplet2.class" archive="CountingApplet2.jar" codebase="." width="100" height="50">
</applet></p>
diff --git a/tests/reproducers/simple/simpletest1/resources/netxPlugin.png b/tests/reproducers/simple/simpletest1/resources/netxPlugin.png
new file mode 100644
index 0000000..e05a856
--- /dev/null
+++ b/tests/reproducers/simple/simpletest1/resources/netxPlugin.png
Binary files differ