jdk/src/share/classes/java/awt/Dialog.java
changeset 6484 f5dbd940a640
parent 5506 202f599c92aa
child 6636 a636784de382
equal deleted inserted replaced
6166:1ce7938efb03 6484:f5dbd940a640
   275      * @see #getTitle()
   275      * @see #getTitle()
   276      * @see #setTitle(String)
   276      * @see #setTitle(String)
   277      */
   277      */
   278     String title;
   278     String title;
   279 
   279 
   280     private transient volatile boolean keepBlockingEDT = false;
       
   281     private transient volatile boolean keepBlockingCT = false;
       
   282 
       
   283     private transient ModalEventFilter modalFilter;
   280     private transient ModalEventFilter modalFilter;
       
   281     private transient volatile SecondaryLoop secondaryLoop;
   284 
   282 
   285     /*
   283     /*
   286      * Indicates that this dialog is being hidden. This flag is set to true at
   284      * Indicates that this dialog is being hidden. This flag is set to true at
   287      * the beginning of hide() and to false at the end of hide().
   285      * the beginning of hide() and to false at the end of hide().
   288      *
   286      *
  1003      */
  1001      */
  1004     public void setVisible(boolean b) {
  1002     public void setVisible(boolean b) {
  1005         super.setVisible(b);
  1003         super.setVisible(b);
  1006     }
  1004     }
  1007 
  1005 
  1008     /**
       
  1009     * Stores the app context on which event dispatch thread the dialog
       
  1010     * is being shown. Initialized in show(), used in hideAndDisposeHandler()
       
  1011     */
       
  1012     transient private AppContext showAppContext;
       
  1013 
       
  1014    /**
  1006    /**
  1015      * Makes the {@code Dialog} visible. If the dialog and/or its owner
  1007      * Makes the {@code Dialog} visible. If the dialog and/or its owner
  1016      * are not yet displayable, both are made displayable.  The
  1008      * are not yet displayable, both are made displayable.  The
  1017      * dialog will be validated prior to being made visible.
  1009      * dialog will be validated prior to being made visible.
  1018      * If the dialog is already visible, this will bring the dialog
  1010      * If the dialog is already visible, this will bring the dialog
  1035     public void show() {
  1027     public void show() {
  1036         beforeFirstShow = false;
  1028         beforeFirstShow = false;
  1037         if (!isModal()) {
  1029         if (!isModal()) {
  1038             conditionalShow(null, null);
  1030             conditionalShow(null, null);
  1039         } else {
  1031         } else {
  1040             // Set this variable before calling conditionalShow(). That
  1032             AppContext showAppContext = AppContext.getAppContext();
  1041             // way, if the Dialog is hidden right after being shown, we
       
  1042             // won't mistakenly block this thread.
       
  1043             keepBlockingEDT = true;
       
  1044             keepBlockingCT = true;
       
  1045 
       
  1046             // Store the app context on which this dialog is being shown.
       
  1047             // Event dispatch thread of this app context will be sleeping until
       
  1048             // we wake it by any event from hideAndDisposeHandler().
       
  1049             showAppContext = AppContext.getAppContext();
       
  1050 
  1033 
  1051             AtomicLong time = new AtomicLong();
  1034             AtomicLong time = new AtomicLong();
  1052             Component predictedFocusOwner = null;
  1035             Component predictedFocusOwner = null;
  1053             try {
  1036             try {
  1054                 predictedFocusOwner = getMostRecentFocusOwner();
  1037                 predictedFocusOwner = getMostRecentFocusOwner();
  1055                 if (conditionalShow(predictedFocusOwner, time)) {
  1038                 if (conditionalShow(predictedFocusOwner, time)) {
  1056                     // We have two mechanisms for blocking: 1. If we're on the
       
  1057                     // EventDispatchThread, start a new event pump. 2. If we're
       
  1058                     // on any other thread, call wait() on the treelock.
       
  1059 
       
  1060                     modalFilter = ModalEventFilter.createFilterForDialog(this);
  1039                     modalFilter = ModalEventFilter.createFilterForDialog(this);
  1061 
  1040                     Conditional cond = new Conditional() {
  1062                     final Runnable pumpEventsForFilter = new Runnable() {
  1041                         @Override
  1063                         public void run() {
  1042                         public boolean evaluate() {
  1064                             EventDispatchThread dispatchThread =
  1043                             return windowClosingException == null;
  1065                                 (EventDispatchThread)Thread.currentThread();
       
  1066                             dispatchThread.pumpEventsForFilter(new Conditional() {
       
  1067                                 public boolean evaluate() {
       
  1068                                     synchronized (getTreeLock()) {
       
  1069                                         return keepBlockingEDT && windowClosingException == null;
       
  1070                                     }
       
  1071                                 }
       
  1072                             }, modalFilter);
       
  1073                         }
  1044                         }
  1074                     };
  1045                     };
  1075 
  1046 
  1076                     // if this dialog is toolkit-modal, the filter should be added
  1047                     // if this dialog is toolkit-modal, the filter should be added
  1077                     // to all EDTs (for all AppContexts)
  1048                     // to all EDTs (for all AppContexts)
  1094                         }
  1065                         }
  1095                     }
  1066                     }
  1096 
  1067 
  1097                     modalityPushed();
  1068                     modalityPushed();
  1098                     try {
  1069                     try {
  1099                         if (EventQueue.isDispatchThread()) {
  1070                         EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
  1100                             /*
  1071                         secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
  1101                              * dispose SequencedEvent we are dispatching on current
  1072                         if (!secondaryLoop.enter()) {
  1102                              * AppContext, to prevent us from hang.
  1073                             secondaryLoop = null;
  1103                              *
       
  1104                              */
       
  1105                             // BugId 4531693 (son@sparc.spb.su)
       
  1106                             SequencedEvent currentSequencedEvent = KeyboardFocusManager.
       
  1107                                 getCurrentKeyboardFocusManager().getCurrentSequencedEvent();
       
  1108                             if (currentSequencedEvent != null) {
       
  1109                                 currentSequencedEvent.dispose();
       
  1110                             }
       
  1111 
       
  1112                             /*
       
  1113                              * Event processing is done inside doPrivileged block so that
       
  1114                              * it wouldn't matter even if user code is on the stack
       
  1115                              * Fix for BugId 6300270
       
  1116                              */
       
  1117 
       
  1118                              AccessController.doPrivileged(new PrivilegedAction() {
       
  1119                                      public Object run() {
       
  1120                                         pumpEventsForFilter.run();
       
  1121                                         return null;
       
  1122                                      }
       
  1123                              });
       
  1124                         } else {
       
  1125                             synchronized (getTreeLock()) {
       
  1126                                 Toolkit.getEventQueue().postEvent(new PeerEvent(this,
       
  1127                                                                                 pumpEventsForFilter,
       
  1128                                                                                 PeerEvent.PRIORITY_EVENT));
       
  1129                                 while (keepBlockingCT && windowClosingException == null) {
       
  1130                                     try {
       
  1131                                         getTreeLock().wait();
       
  1132                                     } catch (InterruptedException e) {
       
  1133                                         break;
       
  1134                                     }
       
  1135                                 }
       
  1136                             }
       
  1137                         }
  1074                         }
  1138                     } finally {
  1075                     } finally {
  1139                         modalityPopped();
  1076                         modalityPopped();
  1140                     }
  1077                     }
  1141 
  1078 
  1192             windowClosingException.fillInStackTrace();
  1129             windowClosingException.fillInStackTrace();
  1193             windowClosingException.printStackTrace();
  1130             windowClosingException.printStackTrace();
  1194             windowClosingException = null;
  1131             windowClosingException = null;
  1195         }
  1132         }
  1196     }
  1133     }
  1197     final class WakingRunnable implements Runnable {
  1134 
  1198         public void run() {
       
  1199             synchronized (getTreeLock()) {
       
  1200                 keepBlockingCT = false;
       
  1201                 getTreeLock().notifyAll();
       
  1202             }
       
  1203         }
       
  1204     }
       
  1205     private void hideAndDisposePreHandler() {
  1135     private void hideAndDisposePreHandler() {
  1206         isInHide = true;
  1136         isInHide = true;
  1207         synchronized (getTreeLock()) {
  1137         synchronized (getTreeLock()) {
  1208             if (keepBlockingEDT) {
  1138             if (secondaryLoop != null) {
  1209                 modalHide();
  1139                 modalHide();
  1210                 // dialog can be shown and then disposed before its
  1140                 // dialog can be shown and then disposed before its
  1211                 // modal filter is created
  1141                 // modal filter is created
  1212                 if (modalFilter != null) {
  1142                 if (modalFilter != null) {
  1213                     modalFilter.disable();
  1143                     modalFilter.disable();
  1215                 modalDialogs.remove(this);
  1145                 modalDialogs.remove(this);
  1216             }
  1146             }
  1217         }
  1147         }
  1218     }
  1148     }
  1219     private void hideAndDisposeHandler() {
  1149     private void hideAndDisposeHandler() {
  1220         synchronized (getTreeLock()) {
  1150         if (secondaryLoop != null) {
  1221             if (keepBlockingEDT) {
  1151             secondaryLoop.exit();
  1222                 keepBlockingEDT = false;
  1152             secondaryLoop = null;
  1223                 PeerEvent wakingEvent = new PeerEvent(getToolkit(), new WakingRunnable(), PeerEvent.PRIORITY_EVENT);
       
  1224                 AppContext curAppContext = AppContext.getAppContext();
       
  1225                 if (showAppContext != curAppContext) {
       
  1226                     // Wake up event dispatch thread on which the dialog was
       
  1227                     // initially shown
       
  1228                     SunToolkit.postEvent(showAppContext, wakingEvent);
       
  1229                     showAppContext = null;
       
  1230                 } else {
       
  1231                     Toolkit.getEventQueue().postEvent(wakingEvent);
       
  1232                 }
       
  1233             }
       
  1234         }
  1153         }
  1235         isInHide = false;
  1154         isInHide = false;
  1236     }
  1155     }
  1237 
  1156 
  1238     /**
  1157     /**