diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java
index ecb2d5217f6..3f6109a4120 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java
@@ -620,8 +620,7 @@ public class CInputMethod extends InputMethodAdapter {
retString[0] = new String(selectedText);
}}
}, fAwtFocussedComponent);
- } catch (InterruptedException ie) { ie.printStackTrace(); }
- catch (InvocationTargetException ite) { ite.printStackTrace(); }
+ } catch (InvocationTargetException ite) { ite.printStackTrace(); }
synchronized(retString) { return retString[0]; }
}
@@ -669,8 +668,7 @@ public class CInputMethod extends InputMethodAdapter {
}}
}, fAwtFocussedComponent);
- } catch (InterruptedException ie) { ie.printStackTrace(); }
- catch (InvocationTargetException ite) { ite.printStackTrace(); }
+ } catch (InvocationTargetException ite) { ite.printStackTrace(); }
synchronized(returnValue) { return returnValue; }
}
@@ -695,8 +693,7 @@ public class CInputMethod extends InputMethodAdapter {
returnValue[0] = fIMContext.getInsertPositionOffset();
}}
}, fAwtFocussedComponent);
- } catch (InterruptedException ie) { ie.printStackTrace(); }
- catch (InvocationTargetException ite) { ite.printStackTrace(); }
+ } catch (InvocationTargetException ite) { ite.printStackTrace(); }
returnValue[1] = fCurrentTextLength;
synchronized(returnValue) { return returnValue; }
@@ -743,8 +740,7 @@ public class CInputMethod extends InputMethodAdapter {
}
}}
}, fAwtFocussedComponent);
- } catch (InterruptedException ie) { ie.printStackTrace(); }
- catch (InvocationTargetException ite) { ite.printStackTrace(); }
+ } catch (InvocationTargetException ite) { ite.printStackTrace(); }
synchronized(rect) { return rect; }
}
@@ -764,8 +760,7 @@ public class CInputMethod extends InputMethodAdapter {
insertPositionOffset[0] = fIMContext.getInsertPositionOffset();
}}
}, fAwtFocussedComponent);
- } catch (InterruptedException ie) { ie.printStackTrace(); }
- catch (InvocationTargetException ite) { ite.printStackTrace(); }
+ } catch (InvocationTargetException ite) { ite.printStackTrace(); }
// This bit of gymnastics ensures that the returned location is within the composed text.
// If it falls outside that region, the input method will commit the text, which is inconsistent with native
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
index 8fca7df691d..97ff63228e9 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
@@ -884,7 +884,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
//Posting an empty to flush the EventQueue without blocking the main thread
}
}, target);
- } catch (InterruptedException | InvocationTargetException e) {
+ } catch (InvocationTargetException e) {
e.printStackTrace();
}
}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java
index 28acc26f6cc..6d843b88295 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java
@@ -97,6 +97,6 @@ public class CViewEmbeddedFrame extends EmbeddedFrame {
setVisible(true);
}
}, this);
- } catch (InterruptedException | InvocationTargetException ex) {}
+ } catch (InvocationTargetException ex) {}
}
}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
index d698845e558..959b03868fb 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
@@ -548,22 +548,18 @@ public final class LWCToolkit extends LWToolkit {
// Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop
// The InvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop
// Does not dispatch native events while in the loop
- public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException {
+ public static void invokeAndWait(Runnable runnable, Component component) throws InvocationTargetException {
final long mediator = createAWTRunLoopMediator();
InvocationEvent invocationEvent =
- new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event) {
- @Override
- public void dispatch() {
- try {
- super.dispatch();
- } finally {
+ new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(),
+ runnable,
+ () -> {
if (mediator != 0) {
stopAWTRunLoop(mediator);
}
- }
- }
- };
+ },
+ true);
if (component != null) {
AppContext appContext = SunToolkit.targetToAppContext(component);
diff --git a/jdk/src/share/classes/java/awt/EventQueue.java b/jdk/src/share/classes/java/awt/EventQueue.java
index d6a1dabfc72..8c144ebc889 100644
--- a/jdk/src/share/classes/java/awt/EventQueue.java
+++ b/jdk/src/share/classes/java/awt/EventQueue.java
@@ -1159,6 +1159,10 @@ public class EventQueue {
if (entry.event instanceof SentEvent) {
((SentEvent)entry.event).dispose();
}
+ if (entry.event instanceof InvocationEvent) {
+ AWTAccessor.getInvocationEventAccessor()
+ .dispose((InvocationEvent)entry.event);
+ }
if (prev == null) {
queues[i].head = entry.next;
} else {
diff --git a/jdk/src/share/classes/java/awt/event/InvocationEvent.java b/jdk/src/share/classes/java/awt/event/InvocationEvent.java
index 1f411e1ac1a..3f04a2316e8 100644
--- a/jdk/src/share/classes/java/awt/event/InvocationEvent.java
+++ b/jdk/src/share/classes/java/awt/event/InvocationEvent.java
@@ -25,6 +25,8 @@
package java.awt.event;
+import sun.awt.AWTAccessor;
+
import java.awt.ActiveEvent;
import java.awt.AWTEvent;
@@ -56,6 +58,15 @@ import java.awt.AWTEvent;
*/
public class InvocationEvent extends AWTEvent implements ActiveEvent {
+ static {
+ AWTAccessor.setInvocationEventAccessor(new AWTAccessor.InvocationEventAccessor() {
+ @Override
+ public void dispose(InvocationEvent invocationEvent) {
+ invocationEvent.finishedDispatching(false);
+ }
+ });
+ }
+
/**
* Marks the first integer id for the range of invocation event ids.
*/
@@ -78,11 +89,21 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
/**
* The (potentially null) Object whose notifyAll() method will be called
- * immediately after the Runnable.run() method has returned or thrown an exception.
+ * immediately after the Runnable.run() method has returned or thrown an exception
+ * or after the event was disposed.
*
* @see #isDispatched
*/
- protected Object notifier;
+ protected volatile Object notifier;
+
+ /**
+ * The (potentially null) Runnable whose run() method will be called
+ * immediately after the event was dispatched or disposed.
+ *
+ * @see #isDispatched
+ * @since 1.8
+ */
+ private final Runnable listener;
/**
* Indicates whether the run()
method of the runnable
@@ -147,7 +168,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* @see #InvocationEvent(Object, Runnable, Object, boolean)
*/
public InvocationEvent(Object source, Runnable runnable) {
- this(source, runnable, null, false);
+ this(source, INVOCATION_DEFAULT, runnable, null, null, false);
}
/**
@@ -171,7 +192,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* @param notifier The {@code Object} whose notifyAll
* method will be called after
* Runnable.run
has returned or
- * thrown an exception
+ * thrown an exception or after the event was
+ * disposed
* @param catchThrowables Specifies whether dispatch
* should catch Throwable when executing
* the Runnable
's run
@@ -185,7 +207,39 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
*/
public InvocationEvent(Object source, Runnable runnable, Object notifier,
boolean catchThrowables) {
- this(source, INVOCATION_DEFAULT, runnable, notifier, catchThrowables);
+ this(source, INVOCATION_DEFAULT, runnable, notifier, null, catchThrowables);
+ }
+
+ /**
+ * Constructs an InvocationEvent
with the specified
+ * source which will execute the runnable's run
+ * method when dispatched. If listener is non-null
,
+ * listener.run()
will be called immediately after
+ * run
has returned, thrown an exception or the event
+ * was disposed.
+ *
This method throws an IllegalArgumentException
+ * if source
is null
.
+ *
+ * @param source The Object
that originated
+ * the event
+ * @param runnable The Runnable
whose
+ * run
method will be
+ * executed
+ * @param listener The Runnable
Runnable whose
+ * run()
method will be called
+ * after the {@code InvocationEvent}
+ * was dispatched or disposed
+ * @param catchThrowables Specifies whether dispatch
+ * should catch Throwable when executing
+ * the Runnable
's run
+ * method, or should instead propagate those
+ * Throwables to the EventDispatchThread's
+ * dispatch loop
+ * @throws IllegalArgumentException if source
is null
+ */
+ public InvocationEvent(Object source, Runnable runnable, Runnable listener,
+ boolean catchThrowables) {
+ this(source, INVOCATION_DEFAULT, runnable, null, listener, catchThrowables);
}
/**
@@ -208,7 +262,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* @param notifier The Object
whose notifyAll
* method will be called after
* Runnable.run
has returned or
- * thrown an exception
+ * thrown an exception or after the event was
+ * disposed
* @param catchThrowables Specifies whether dispatch
* should catch Throwable when executing the
* Runnable
's run
@@ -221,13 +276,18 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
*/
protected InvocationEvent(Object source, int id, Runnable runnable,
Object notifier, boolean catchThrowables) {
+ this(source, id, runnable, notifier, null, catchThrowables);
+ }
+
+ private InvocationEvent(Object source, int id, Runnable runnable,
+ Object notifier, Runnable listener, boolean catchThrowables) {
super(source, id);
this.runnable = runnable;
this.notifier = notifier;
+ this.listener = listener;
this.catchExceptions = catchThrowables;
this.when = System.currentTimeMillis();
}
-
/**
* Executes the Runnable's run()
method and notifies the
* notifier (if any) when run()
has returned or thrown an exception.
@@ -251,13 +311,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
runnable.run();
}
} finally {
- dispatched = true;
-
- if (notifier != null) {
- synchronized (notifier) {
- notifier.notifyAll();
- }
- }
+ finishedDispatching(true);
}
}
@@ -330,6 +384,25 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
return dispatched;
}
+ /**
+ * Called when the event was dispatched or disposed
+ * @param dispatched true if the event was dispatched
+ * false if the event was disposed
+ */
+ private void finishedDispatching(boolean dispatched) {
+ this.dispatched = dispatched;
+
+ if (notifier != null) {
+ synchronized (notifier) {
+ notifier.notifyAll();
+ }
+ }
+
+ if (listener != null) {
+ listener.run();
+ }
+ }
+
/**
* Returns a parameter string identifying this event.
* This method is useful for event-logging and for debugging.
diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java
index 8cd84ab3d21..a00a23453fe 100644
--- a/jdk/src/share/classes/sun/awt/AWTAccessor.java
+++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java
@@ -31,6 +31,7 @@ import java.awt.*;
import java.awt.KeyboardFocusManager;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.event.InputEvent;
+import java.awt.event.InvocationEvent;
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import java.awt.peer.ComponentPeer;
@@ -720,6 +721,13 @@ public final class AWTAccessor {
void setPlatformResources(ResourceBundle bundle);
}
+ /*
+ * An accessor object for the InvocationEvent class
+ */
+ public interface InvocationEventAccessor {
+ void dispose(InvocationEvent event);
+ }
+
/*
* Accessor instances are initialized in the static initializers of
* corresponding AWT classes by using setters defined below.
@@ -748,6 +756,7 @@ public final class AWTAccessor {
private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor;
private static SequencedEventAccessor sequencedEventAccessor;
private static ToolkitAccessor toolkitAccessor;
+ private static InvocationEventAccessor invocationEventAccessor;
/*
* Set an accessor object for the java.awt.Component class.
@@ -1159,4 +1168,18 @@ public final class AWTAccessor {
return toolkitAccessor;
}
+
+ /*
+ * Get the accessor object for the java.awt.event.InvocationEvent class.
+ */
+ public static void setInvocationEventAccessor(InvocationEventAccessor invocationEventAccessor) {
+ AWTAccessor.invocationEventAccessor = invocationEventAccessor;
+ }
+
+ /*
+ * Set the accessor object for the java.awt.event.InvocationEvent class.
+ */
+ public static InvocationEventAccessor getInvocationEventAccessor() {
+ return invocationEventAccessor;
+ }
}