summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java56
1 files changed, 54 insertions, 2 deletions
diff --git a/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java b/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java
index c3301a9..feee512 100644
--- a/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java
+++ b/src/classes/share/com/sun/j3d/exp/swing/JCanvas3D.java
@@ -56,6 +56,11 @@ import javax.swing.event.AncestorListener;
import com.sun.j3d.exp.swing.impl.AutoOffScreenCanvas3D;
+// EP
+import java.lang.reflect.Field;
+import java.util.Map;
+// EP
+
/**
* This class provides a lightweight capability to Java 3D. The component
@@ -608,7 +613,7 @@ public class JCanvas3D extends JPanel implements AncestorListener {
// to wait for the readback of the off-screen buffer to complete.
// The total time is MAX_WAIT_LOOPS * MAX_WAIT_TIME msec.
private static final int MAX_WAIT_LOOPS = 5;
- private static final long MAX_WAIT_TIME = 100;
+ private static final long MAX_WAIT_TIME = 10; // EP: Used to be 100;
/**
* the bufferedImage that will be displayed as the result
@@ -659,6 +664,10 @@ public class JCanvas3D extends JPanel implements AncestorListener {
*/
boolean waitingForSwap;
+ // EP
+ Object mainThreadContext;
+ // EP
+
/**
* Creates a new instance of JCanvas3D. Resize mode is set
* to RESIZE_IMMEDIATELY and validation delay to 100ms.
@@ -674,6 +683,15 @@ public class JCanvas3D extends JPanel implements AncestorListener {
imageReadyBis = false;
waitingForSwap = false;
addNotifyFlag = false;
+
+ // EP
+ try {
+ // Retrieve main thread AppContext instance by reflection
+ this.mainThreadContext = Class.forName("sun.awt.AppContext").getMethod("getAppContext").invoke(null);
+ } catch (Throwable ex) {
+ // Let's consider app context is not necessary for the program
+ }
+ // EP
}
/**
@@ -728,6 +746,11 @@ public class JCanvas3D extends JPanel implements AncestorListener {
if (false == waitingForSwap) {
// System.err.println("repaint " + System.currentTimeMillis());
+
+ // EP
+ checkAppContext();
+ // EP
+
this.lwCanvas.repaint();
} else {
notify();
@@ -737,6 +760,33 @@ public class JCanvas3D extends JPanel implements AncestorListener {
}
}
+ // EP
+ /**
+ * Checks that app context is correct.
+ */
+ private void checkAppContext() {
+ if (this.mainThreadContext != null) {
+ try {
+ // Check by reflection that sun.awt.AppContext.getAppContext() doesn't return null
+ // (required by ImageIO.write() and other JMF internal calls) to apply workaround proposed at
+ // http://stackoverflow.com/questions/17223304/appcontext-is-null-from-rmi-thread-with-java-7-update-25
+ Class<?> appContextClass = Class.forName("sun.awt.AppContext");
+ if (appContextClass.getMethod("getAppContext").invoke(null) == null) {
+ Field field = appContextClass.getDeclaredField("threadGroup2appContext");
+ field.setAccessible(true);
+ Map threadGroup2appContext = (Map)field.get(null);
+ ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
+ threadGroup2appContext.put(currentThreadGroup, this.mainThreadContext);
+ }
+ } catch (Throwable ex) {
+ // Let's consider app context is not necessary for the program
+ }
+ // Don't need mainThreadContext anymore
+ this.mainThreadContext = null;
+ }
+ }
+ // EP
+
/**
* Overriden so that the JComponent can access it.
*
@@ -822,7 +872,9 @@ public class JCanvas3D extends JPanel implements AncestorListener {
if (!imageReadyBis && --counter <= 0) {
//if i've waited too long for the canvas to be there, let us declare it crashed.
- System.err.println("CANVAS CRASHED!!!");
+ // EP
+ // System.err.println("CANVAS CRASHED!!!");
+ // EP
canvasCrashed = true;
return;
}