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 } |