摘抄自Window类 /** * Releases all of the native screen resources used by this * <code>Window</code>, its subcomponents, and all of its owned * children. That is, the resources for these <code>Component</code>s * will be destroyed, any memory they consume will be returned to the * OS, and they will be ed as undisplayable. * <p> * The <code>Window</code> and its subcomponents can be made displayable * again by rebuilding the native resources with a subsequent call to * <code>pack</code> or <code>show</code>. The states of the recreated * <code>Window</code> and its subcomponents will be identical to the * states of these objects at the point where the <code>Window</code> * was disposed (not accounting for additional modifications between * those actions). * <p> * <b>Note</b>: When the last displayable window * within the Java virtual machine (VM) is disposed of, the VM may * terminate. See <a href="doc-files/AWTThreadIssues.html#Autoshutdown"> * AWT Threading Issues</a> for more information. * @see Component#isDisplayable * @see #pack * @see #show */ public void dispose() { doDispose(); } /* * Fix for 4872170. * If dispose() is called on parent then its children have to be disposed as well * as reported in javadoc. So we need to implement this functionality even if a * child overrides dispose() in a wrong way without calling super.dispose(). */ void disposeImpl() { dispose(); if (getPeer() != null) { doDispose(); } } void doDispose() { class DisposeAction implements Runnable { public void run() { // Check if this window is the fullscreen window for the // device. Exit the fullscreen mode prior to disposing // of the window if that's the case. GraphicsDevice gd = getGraphicsConfiguration().getDevice(); if (gd.getFullScreenWindow() == Window.this) { gd.setFullScreenWindow(null); }
Object[] ownedWindowArray; synchronized(ownedWindowList) { ownedWindowArray = new Object[ownedWindowList.size()]; ownedWindowList.copyInto(ownedWindowArray); } for (int i = 0; i < ownedWindowArray.length; i++) { Window child = (Window) (((WeakReference) (ownedWindowArray[i])).get()); if (child != null) { child.disposeImpl(); } } hide(); beforeFirstShow = true; removeNotify(); synchronized (inputContextLock) { if (inputContext != null) { inputContext.dispose(); inputContext = null; } } clearCurrentFocusCycleRootOnHide(); } } DisposeAction action = new DisposeAction(); if (EventQueue.isDispatchThread()) { action.run(); } else { try { EventQueue.invokeAndWait(action); } catch (InterruptedException e) { System.err.println("Disposal was interrupted:"); e.printStackTrace(); } catch (InvocationTargetException e) { System.err.println("Exception during disposal:"); e.printStackTrace(); } } // Execute outside the Runnable because postWindowEvent is // synchronized on (this). We don't need to synchronize the call // on the EventQueue anyways. postWindowEvent(WindowEvent.WINDOW_CLOSED); }
/**
* Releases all of the native screen resources used by this
* <code>Window</code>, its subcomponents, and all of its owned
* children. That is, the resources for these <code>Component</code>s
* will be destroyed, any memory they consume will be returned to the
* OS, and they will be ed as undisplayable.
* <p>
* The <code>Window</code> and its subcomponents can be made displayable
* again by rebuilding the native resources with a subsequent call to
* <code>pack</code> or <code>show</code>. The states of the recreated
* <code>Window</code> and its subcomponents will be identical to the
* states of these objects at the point where the <code>Window</code>
* was disposed (not accounting for additional modifications between
* those actions).
* <p>
* <b>Note</b>: When the last displayable window
* within the Java virtual machine (VM) is disposed of, the VM may
* terminate. See <a href="doc-files/AWTThreadIssues.html#Autoshutdown">
* AWT Threading Issues</a> for more information.
* @see Component#isDisplayable
* @see #pack
* @see #show
*/
public void dispose() {
doDispose();
} /*
* Fix for 4872170.
* If dispose() is called on parent then its children have to be disposed as well
* as reported in javadoc. So we need to implement this functionality even if a
* child overrides dispose() in a wrong way without calling super.dispose().
*/
void disposeImpl() {
dispose();
if (getPeer() != null) {
doDispose();
}
} void doDispose() {
class DisposeAction implements Runnable {
public void run() {
// Check if this window is the fullscreen window for the
// device. Exit the fullscreen mode prior to disposing
// of the window if that's the case.
GraphicsDevice gd = getGraphicsConfiguration().getDevice();
if (gd.getFullScreenWindow() == Window.this) {
gd.setFullScreenWindow(null);
}
Object[] ownedWindowArray;
synchronized(ownedWindowList) {
ownedWindowArray = new Object[ownedWindowList.size()];
ownedWindowList.copyInto(ownedWindowArray);
}
for (int i = 0; i < ownedWindowArray.length; i++) {
Window child = (Window) (((WeakReference)
(ownedWindowArray[i])).get());
if (child != null) {
child.disposeImpl();
}
}
hide();
beforeFirstShow = true;
removeNotify();
synchronized (inputContextLock) {
if (inputContext != null) {
inputContext.dispose();
inputContext = null;
}
}
clearCurrentFocusCycleRootOnHide();
}
}
DisposeAction action = new DisposeAction();
if (EventQueue.isDispatchThread()) {
action.run();
}
else {
try {
EventQueue.invokeAndWait(action);
}
catch (InterruptedException e) {
System.err.println("Disposal was interrupted:");
e.printStackTrace();
}
catch (InvocationTargetException e) {
System.err.println("Exception during disposal:");
e.printStackTrace();
}
}
// Execute outside the Runnable because postWindowEvent is
// synchronized on (this). We don't need to synchronize the call
// on the EventQueue anyways.
postWindowEvent(WindowEvent.WINDOW_CLOSED);
}