You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
6.5 KiB
217 lines
6.5 KiB
/*
|
|
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
package java.awt;
|
|
|
|
import java.awt.event.*;
|
|
|
|
import sun.awt.AppContext;
|
|
|
|
abstract class ModalEventFilter implements EventFilter {
|
|
|
|
protected Dialog modalDialog;
|
|
protected boolean disabled;
|
|
|
|
protected ModalEventFilter(Dialog modalDialog) {
|
|
this.modalDialog = modalDialog;
|
|
disabled = false;
|
|
}
|
|
|
|
Dialog getModalDialog() {
|
|
return modalDialog;
|
|
}
|
|
|
|
public FilterAction acceptEvent(AWTEvent event) {
|
|
if (disabled || !modalDialog.isVisible()) {
|
|
return FilterAction.ACCEPT;
|
|
}
|
|
int eventID = event.getID();
|
|
if ((eventID >= MouseEvent.MOUSE_FIRST &&
|
|
eventID <= MouseEvent.MOUSE_LAST) ||
|
|
(eventID >= ActionEvent.ACTION_FIRST &&
|
|
eventID <= ActionEvent.ACTION_LAST) ||
|
|
eventID == WindowEvent.WINDOW_CLOSING)
|
|
{
|
|
Object o = event.getSource();
|
|
if (o instanceof sun.awt.ModalExclude) {
|
|
// Exclude this object from modality and
|
|
// continue to pump it's events.
|
|
} else if (o instanceof Component) {
|
|
Component c = (Component)o;
|
|
while ((c != null) && !(c instanceof Window)) {
|
|
c = c.getParent_NoClientCode();
|
|
}
|
|
if (c != null) {
|
|
return acceptWindow((Window)c);
|
|
}
|
|
}
|
|
}
|
|
return FilterAction.ACCEPT;
|
|
}
|
|
|
|
protected abstract FilterAction acceptWindow(Window w);
|
|
|
|
// When a modal dialog is hidden its modal filter may not be deleted from
|
|
// EventDispatchThread event filters immediately, so we need to mark the filter
|
|
// as disabled to prevent it from working. Simple checking for visibility of
|
|
// the modalDialog is not enough, as it can be hidden and then shown again
|
|
// with a new event pump and a new filter
|
|
void disable() {
|
|
disabled = true;
|
|
}
|
|
|
|
int compareTo(ModalEventFilter another) {
|
|
Dialog anotherDialog = another.getModalDialog();
|
|
// check if modalDialog is from anotherDialog's hierarchy
|
|
// or vice versa
|
|
Component c = modalDialog;
|
|
while (c != null) {
|
|
if (c == anotherDialog) {
|
|
return 1;
|
|
}
|
|
c = c.getParent_NoClientCode();
|
|
}
|
|
c = anotherDialog;
|
|
while (c != null) {
|
|
if (c == modalDialog) {
|
|
return -1;
|
|
}
|
|
c = c.getParent_NoClientCode();
|
|
}
|
|
// check if one dialog blocks (directly or indirectly) another
|
|
Dialog blocker = modalDialog.getModalBlocker();
|
|
while (blocker != null) {
|
|
if (blocker == anotherDialog) {
|
|
return -1;
|
|
}
|
|
blocker = blocker.getModalBlocker();
|
|
}
|
|
blocker = anotherDialog.getModalBlocker();
|
|
while (blocker != null) {
|
|
if (blocker == modalDialog) {
|
|
return 1;
|
|
}
|
|
blocker = blocker.getModalBlocker();
|
|
}
|
|
// compare modality types
|
|
return modalDialog.getModalityType().compareTo(anotherDialog.getModalityType());
|
|
}
|
|
|
|
static ModalEventFilter createFilterForDialog(Dialog modalDialog) {
|
|
switch (modalDialog.getModalityType()) {
|
|
case DOCUMENT_MODAL: return new DocumentModalEventFilter(modalDialog);
|
|
case APPLICATION_MODAL: return new ApplicationModalEventFilter(modalDialog);
|
|
case TOOLKIT_MODAL: return new ToolkitModalEventFilter(modalDialog);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static class ToolkitModalEventFilter extends ModalEventFilter {
|
|
|
|
private AppContext appContext;
|
|
|
|
ToolkitModalEventFilter(Dialog modalDialog) {
|
|
super(modalDialog);
|
|
appContext = modalDialog.appContext;
|
|
}
|
|
|
|
protected FilterAction acceptWindow(Window w) {
|
|
if (w.isModalExcluded(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE)) {
|
|
return FilterAction.ACCEPT;
|
|
}
|
|
if (w.appContext != appContext) {
|
|
return FilterAction.REJECT;
|
|
}
|
|
while (w != null) {
|
|
if (w == modalDialog) {
|
|
return FilterAction.ACCEPT_IMMEDIATELY;
|
|
}
|
|
w = w.getOwner();
|
|
}
|
|
return FilterAction.REJECT;
|
|
}
|
|
}
|
|
|
|
private static class ApplicationModalEventFilter extends ModalEventFilter {
|
|
|
|
private AppContext appContext;
|
|
|
|
ApplicationModalEventFilter(Dialog modalDialog) {
|
|
super(modalDialog);
|
|
appContext = modalDialog.appContext;
|
|
}
|
|
|
|
protected FilterAction acceptWindow(Window w) {
|
|
if (w.isModalExcluded(Dialog.ModalExclusionType.APPLICATION_EXCLUDE)) {
|
|
return FilterAction.ACCEPT;
|
|
}
|
|
if (w.appContext == appContext) {
|
|
while (w != null) {
|
|
if (w == modalDialog) {
|
|
return FilterAction.ACCEPT_IMMEDIATELY;
|
|
}
|
|
w = w.getOwner();
|
|
}
|
|
return FilterAction.REJECT;
|
|
}
|
|
return FilterAction.ACCEPT;
|
|
}
|
|
}
|
|
|
|
private static class DocumentModalEventFilter extends ModalEventFilter {
|
|
|
|
private Window documentRoot;
|
|
|
|
DocumentModalEventFilter(Dialog modalDialog) {
|
|
super(modalDialog);
|
|
documentRoot = modalDialog.getDocumentRoot();
|
|
}
|
|
|
|
protected FilterAction acceptWindow(Window w) {
|
|
// application- and toolkit-excluded windows are blocked by
|
|
// document-modal dialogs from their child hierarchy
|
|
if (w.isModalExcluded(Dialog.ModalExclusionType.APPLICATION_EXCLUDE)) {
|
|
Window w1 = modalDialog.getOwner();
|
|
while (w1 != null) {
|
|
if (w1 == w) {
|
|
return FilterAction.REJECT;
|
|
}
|
|
w1 = w1.getOwner();
|
|
}
|
|
return FilterAction.ACCEPT;
|
|
}
|
|
while (w != null) {
|
|
if (w == modalDialog) {
|
|
return FilterAction.ACCEPT_IMMEDIATELY;
|
|
}
|
|
if (w == documentRoot) {
|
|
return FilterAction.REJECT;
|
|
}
|
|
w = w.getOwner();
|
|
}
|
|
return FilterAction.ACCEPT;
|
|
}
|
|
}
|
|
}
|