src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java

Print this page




 594         CallableWrapper(final Callable<T> callable) {
 595             this.callable = callable;
 596         }
 597 
 598         @Override
 599         public void run() {
 600             try {
 601                 object = callable.call();
 602             } catch (final Exception e) {
 603                 this.e = e;
 604             }
 605         }
 606 
 607         public T getResult() throws Exception {
 608             if (e != null) throw e;
 609             return object;
 610         }
 611     }
 612 
 613     /**
 614      * Kicks an event over to the appropriate eventqueue and waits for it to
 615      * finish To avoid deadlocking, we manually run the NSRunLoop while waiting
 616      * Any selector invoked using ThreadUtilities performOnMainThread will be
 617      * processed in doAWTRunLoop The InvocationEvent will call
 618      * LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual
 619      * runloop Does not dispatch native events while in the loop
 620      */
 621     public static void invokeAndWait(Runnable runnable, Component component)
 622             throws InvocationTargetException {
 623         final long mediator = createAWTRunLoopMediator();
 624 

 625         InvocationEvent invocationEvent =
 626                 new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(),
 627                         runnable,
 628                         () -> {
 629                             if (mediator != 0) {
 630                                 stopAWTRunLoop(mediator);
 631                             }
 632                         },
 633                         true);
 634 
 635         if (component != null) {
 636             AppContext appContext = SunToolkit.targetToAppContext(component);
 637             SunToolkit.postEvent(appContext, invocationEvent);
 638 
 639             // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock
 640             SunToolkit.flushPendingEvents(appContext);
 641         } else {
 642             // This should be the equivalent to EventQueue.invokeAndWait
 643             ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent);
 644         }
 645 
 646         doAWTRunLoop(mediator, false);
 647 
 648         Throwable eventException = invocationEvent.getException();
 649         if (eventException != null) {
 650             if (eventException instanceof UndeclaredThrowableException) {
 651                 eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable();
 652             }
 653             throw new InvocationTargetException(eventException);
 654         }
 655     }
 656 
 657     public static void invokeLater(Runnable event, Component component)
 658             throws InvocationTargetException {
 659         final InvocationEvent invocationEvent =
 660                 new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event);
 661 
 662         if (component != null) {
 663             final AppContext appContext = SunToolkit.targetToAppContext(component);
 664             SunToolkit.postEvent(appContext, invocationEvent);
 665 


 666             // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock
 667             SunToolkit.flushPendingEvents(appContext);
 668         } else {
 669             // This should be the equivalent to EventQueue.invokeAndWait
 670             ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent);
 671         }
 672 
 673         final Throwable eventException = invocationEvent.getException();








 674         if (eventException == null) return;
 675 
 676         if (eventException instanceof UndeclaredThrowableException) {
 677             throw new InvocationTargetException(((UndeclaredThrowableException)eventException).getUndeclaredThrowable());
 678         }
 679         throw new InvocationTargetException(eventException);
 680     }
 681 
 682     /**
 683      * Schedules a {@code Runnable} execution on the Appkit thread after a delay
 684      * @param r a {@code Runnable} to execute
 685      * @param delay a delay in milliseconds
 686      */
 687     native static void performOnMainThreadAfterDelay(Runnable r, long delay);
 688 
 689     // This exists purely to get around permissions issues with getSystemEventQueueImpl
 690     EventQueue getSystemEventQueueForInvokeAndWait() {
 691         return getSystemEventQueueImpl();
 692     }
 693 
 694 // DnD support
 695 
 696     @Override
 697     public DragSourceContextPeer createDragSourceContextPeer(
 698             DragGestureEvent dge) throws InvalidDnDOperationException {
 699         return CDragSourceContextPeer.createDragSourceContextPeer(dge);
 700     }
 701 
 702     @Override
 703     public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
 704             Class<T> abstractRecognizerClass, DragSource ds, Component c,
 705             int srcActions, DragGestureListener dgl) {
 706         DragGestureRecognizer dgr = null;
 707 
 708         // Create a new mouse drag gesture recognizer if we have a class match:
 709         if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass))
 710             dgr = new CMouseDragGestureRecognizer(ds, c, srcActions, dgl);
 711 
 712         return (T)dgr;
 713     }




 594         CallableWrapper(final Callable<T> callable) {
 595             this.callable = callable;
 596         }
 597 
 598         @Override
 599         public void run() {
 600             try {
 601                 object = callable.call();
 602             } catch (final Exception e) {
 603                 this.e = e;
 604             }
 605         }
 606 
 607         public T getResult() throws Exception {
 608             if (e != null) throw e;
 609             return object;
 610         }
 611     }
 612 
 613     /**
 614      * Kicks an event over to the appropriate event queue and waits for it to
 615      * finish To avoid deadlocking, we manually run the NSRunLoop while waiting
 616      * Any selector invoked using ThreadUtilities performOnMainThread will be
 617      * processed in doAWTRunLoop The InvocationEvent will call
 618      * LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual
 619      * run loop. Does not dispatch native events while in the loop
 620      */
 621     public static void invokeAndWait(Runnable runnable, Component component)
 622             throws InvocationTargetException {
 623         Objects.requireNonNull(component, "Null component provided to invokeAndWait");
 624 
 625         long mediator = createAWTRunLoopMediator();
 626         InvocationEvent invocationEvent =
 627                 new InvocationEvent(component,
 628                         runnable,
 629                         () -> {
 630                             if (mediator != 0) {
 631                                 stopAWTRunLoop(mediator);
 632                             }
 633                         },
 634                         true);
 635 

 636         AppContext appContext = SunToolkit.targetToAppContext(component);
 637         SunToolkit.postEvent(appContext, invocationEvent);

 638         // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock
 639         SunToolkit.flushPendingEvents(appContext);





 640         doAWTRunLoop(mediator, false);
 641 
 642         checkException(invocationEvent);






 643     }
 644 
 645     public static void invokeLater(Runnable event, Component component)
 646             throws InvocationTargetException {
 647         Objects.requireNonNull(component, "Null component provided to invokeLater");

 648 
 649         InvocationEvent invocationEvent = new InvocationEvent(component, event);


 650 
 651         AppContext appContext = SunToolkit.targetToAppContext(component);
 652         SunToolkit.postEvent(SunToolkit.targetToAppContext(component), invocationEvent);
 653         // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock
 654         SunToolkit.flushPendingEvents(appContext);
 655 
 656         checkException(invocationEvent);

 657     }
 658 
 659     /**
 660      * Checks if exception occurred while {@code InvocationEvent} was processed and rethrows it as
 661      * an {@code InvocationTargetException}
 662      *
 663      * @param event the event to check for an exception
 664      * @throws InvocationTargetException if exception occurred when event was processed
 665      */
 666     private static void checkException(InvocationEvent event) throws InvocationTargetException {
 667         Throwable eventException = event.getException();
 668         if (eventException == null) return;
 669 
 670         if (eventException instanceof UndeclaredThrowableException) {
 671             eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable();
 672         }
 673         throw new InvocationTargetException(eventException);
 674     }
 675 
 676     /**
 677      * Schedules a {@code Runnable} execution on the Appkit thread after a delay
 678      * @param r a {@code Runnable} to execute
 679      * @param delay a delay in milliseconds
 680      */
 681     native static void performOnMainThreadAfterDelay(Runnable r, long delay);
 682 





 683 // DnD support
 684 
 685     @Override
 686     public DragSourceContextPeer createDragSourceContextPeer(
 687             DragGestureEvent dge) throws InvalidDnDOperationException {
 688         return CDragSourceContextPeer.createDragSourceContextPeer(dge);
 689     }
 690 
 691     @Override
 692     public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
 693             Class<T> abstractRecognizerClass, DragSource ds, Component c,
 694             int srcActions, DragGestureListener dgl) {
 695         DragGestureRecognizer dgr = null;
 696 
 697         // Create a new mouse drag gesture recognizer if we have a class match:
 698         if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass))
 699             dgr = new CMouseDragGestureRecognizer(ds, c, srcActions, dgl);
 700 
 701         return (T)dgr;
 702     }