29 import com.sun.javafx.css.StyleManager;
30 import com.sun.javafx.runtime.SystemProperties;
31
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.security.AccessControlContext;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Set;
38 import java.util.concurrent.CopyOnWriteArraySet;
39 import java.util.concurrent.CountDownLatch;
40 import java.util.concurrent.atomic.AtomicBoolean;
41 import java.util.concurrent.atomic.AtomicInteger;
42
43 import javafx.application.Application;
44 import javafx.application.ConditionalFeature;
45
46 import com.sun.javafx.tk.TKListener;
47 import com.sun.javafx.tk.TKStage;
48 import com.sun.javafx.tk.Toolkit;
49 import com.sun.javafx.util.ModuleHelper;
50 import javafx.beans.property.BooleanProperty;
51 import javafx.beans.property.SimpleBooleanProperty;
52 import javafx.scene.Scene;
53
54 import java.security.AccessController;
55 import java.security.AllPermission;
56 import java.security.PrivilegedAction;
57
58 public class PlatformImpl {
59
60 private static AtomicBoolean initialized = new AtomicBoolean(false);
61 private static AtomicBoolean platformExit = new AtomicBoolean(false);
62 private static AtomicBoolean toolkitExit = new AtomicBoolean(false);
63 private static CountDownLatch startupLatch = new CountDownLatch(1);
64 private static AtomicBoolean listenersRegistered = new AtomicBoolean(false);
65 private static TKListener toolkitListener = null;
66 private static volatile boolean implicitExit = true;
67 private static boolean taskbarApplication = true;
68 private static boolean contextual2DNavigation;
69 private static AtomicInteger pendingRunnables = new AtomicInteger(0);
235 });
236
237 //Initialize the thread merging mechanism
238 if (isThreadMerged) {
239 installFwEventQueue();
240 }
241 }
242
243 private static void installFwEventQueue() {
244 invokeSwingFXUtilsMethod("installFwEventQueue");
245 }
246
247 private static void removeFwEventQueue() {
248 invokeSwingFXUtilsMethod("removeFwEventQueue");
249 }
250
251 private static void invokeSwingFXUtilsMethod(final String methodName) {
252 //Use reflection in case we are running compact profile
253 try {
254 Class swingFXUtilsClass = Class.forName("javafx.embed.swing.SwingFXUtils");
255 Object thisModule = ModuleHelper.getModule(PlatformImpl.class);
256 Object targetModule = ModuleHelper.getModule(swingFXUtilsClass);
257 ModuleHelper.addReads(thisModule, targetModule);
258
259 Method installFwEventQueue = swingFXUtilsClass.getDeclaredMethod(methodName);
260 AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
261 installFwEventQueue.setAccessible(true);
262 return null;
263 });
264
265 waitForStart();
266 installFwEventQueue.invoke(null);
267
268 } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
269 throw new RuntimeException("Property javafx.embed.singleThread is not supported");
270 } catch (InvocationTargetException e) {
271 throw new RuntimeException(e);
272 }
273 }
274
275 private static void waitForStart() {
276 // If the startup runnable has not yet been called, then wait it.
277 // Note that we check the count before calling await() to avoid
278 // the try/catch which is unnecessary after startup.
|
29 import com.sun.javafx.css.StyleManager;
30 import com.sun.javafx.runtime.SystemProperties;
31
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.security.AccessControlContext;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Set;
38 import java.util.concurrent.CopyOnWriteArraySet;
39 import java.util.concurrent.CountDownLatch;
40 import java.util.concurrent.atomic.AtomicBoolean;
41 import java.util.concurrent.atomic.AtomicInteger;
42
43 import javafx.application.Application;
44 import javafx.application.ConditionalFeature;
45
46 import com.sun.javafx.tk.TKListener;
47 import com.sun.javafx.tk.TKStage;
48 import com.sun.javafx.tk.Toolkit;
49 import javafx.beans.property.BooleanProperty;
50 import javafx.beans.property.SimpleBooleanProperty;
51 import javafx.scene.Scene;
52
53 import java.security.AccessController;
54 import java.security.AllPermission;
55 import java.security.PrivilegedAction;
56
57 public class PlatformImpl {
58
59 private static AtomicBoolean initialized = new AtomicBoolean(false);
60 private static AtomicBoolean platformExit = new AtomicBoolean(false);
61 private static AtomicBoolean toolkitExit = new AtomicBoolean(false);
62 private static CountDownLatch startupLatch = new CountDownLatch(1);
63 private static AtomicBoolean listenersRegistered = new AtomicBoolean(false);
64 private static TKListener toolkitListener = null;
65 private static volatile boolean implicitExit = true;
66 private static boolean taskbarApplication = true;
67 private static boolean contextual2DNavigation;
68 private static AtomicInteger pendingRunnables = new AtomicInteger(0);
234 });
235
236 //Initialize the thread merging mechanism
237 if (isThreadMerged) {
238 installFwEventQueue();
239 }
240 }
241
242 private static void installFwEventQueue() {
243 invokeSwingFXUtilsMethod("installFwEventQueue");
244 }
245
246 private static void removeFwEventQueue() {
247 invokeSwingFXUtilsMethod("removeFwEventQueue");
248 }
249
250 private static void invokeSwingFXUtilsMethod(final String methodName) {
251 //Use reflection in case we are running compact profile
252 try {
253 Class swingFXUtilsClass = Class.forName("javafx.embed.swing.SwingFXUtils");
254 Method installFwEventQueue = swingFXUtilsClass.getDeclaredMethod(methodName);
255 AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
256 installFwEventQueue.setAccessible(true);
257 return null;
258 });
259
260 waitForStart();
261 installFwEventQueue.invoke(null);
262
263 } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
264 throw new RuntimeException("Property javafx.embed.singleThread is not supported");
265 } catch (InvocationTargetException e) {
266 throw new RuntimeException(e);
267 }
268 }
269
270 private static void waitForStart() {
271 // If the startup runnable has not yet been called, then wait it.
272 // Note that we check the count before calling await() to avoid
273 // the try/catch which is unnecessary after startup.
|