JDK-6518753 : REGRESSION:Modal Internal Frames are broken in 1.6
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-01-29
  • Updated: 2011-03-07
  • Resolved: 2011-03-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u10Fixed 7 b09Fixed
Related Reports
Relates :  
Description
J2SE Version (please include all output from java -version flag):
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

Does this problem occur on J2SE 1.4.x or 5.0.x ?  Yes / No (pick one)
No

Operating System Configuration Information (be specific):
Microsoft Windows 2000 [Version 5.00.2195]

Modal Internal Frames are broken in 1.6

Opening a Modal Internal Frame from a Modal Internal Frame into a different Window than the original is causing Mouse Events not to be dispatched.

1) Run Code
(Two Frames with just buttons at the bottom should appear)

2) On the left Frame click on the 'Show Message in this Frame' button
(A dialog should appear in the left Frame and the right Frame should remain empty)
 
3) On the left Frame click on the 'Show Message in other Frame' button
(Now a dialog should appear in the right Frame with the text 'Test' and the other dialog should remain in the left Frame)

4) Observe that clicking OK with the Mouse no longer works (using the enter key still works)

import static java.awt.BorderLayout.*;
import static javax.swing.JFrame.*;
import static javax.swing.JOptionPane.*;
import java.awt.event.*;
import javax.swing.*;

public class Test {
 public static void main(String[] args) {
   final JDesktopPane desktop1 = new JDesktopPane();
   final JDesktopPane desktop2 = new JDesktopPane();
     JFrame frame1 = new JFrame("Frame 1");
   frame1.add(desktop1);
   frame1.add(new JButton(new AbstractAction("Show Message in this Frame") {
     public void actionPerformed(ActionEvent anEvent) {
       showInternalMessageDialog(desktop1, new JButton(new AbstractAction(
           "Show Message in other Frame") {
         public void actionPerformed(ActionEvent anEvent) {
           showInternalMessageDialog(desktop2, "Test");
         }
       }));
     }
   }), SOUTH);
   frame1.setDefaultCloseOperation(EXIT_ON_CLOSE);
   frame1.setBounds(50, 50, 300, 300);
   frame1.setVisible(true);
     JFrame frame2 = new JFrame("Frame 2");
   frame2.add(desktop2);
   frame2.add(new JButton(new AbstractAction("Show Message in this Frame") {
     public void actionPerformed(ActionEvent anEvent) {
       showInternalMessageDialog(desktop2, new JButton(new AbstractAction(
           "Show Message in other Frame") {
         public void actionPerformed(ActionEvent anEvent) {
           showInternalMessageDialog(desktop1, "Test");
         }
       }));
     }
   }), SOUTH);
   frame2.setDefaultCloseOperation(EXIT_ON_CLOSE);
   frame2.setBounds(400, 50, 300, 300);
   frame2.setVisible(true);
 }
}

Comments
SUGGESTED FIX *** /tmp/geta28989 2007-01-30 16:08:50.000000000 +0300 --- EventDispatchThread.java 2007-01-30 15:56:30.000000000 +0300 *************** *** 414,427 **** * KeyEvent is handled by using enqueueKeyEvent * in Dialog.show */ int eventID = event.getID(); ! if (((eventID >= MouseEvent.MOUSE_FIRST && ! eventID <= MouseEvent.MOUSE_LAST) && ! !(checkMouseEventForModalJInternalFrame((MouseEvent)event, modalComponent))) || ! (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 --- 399,420 ---- * KeyEvent is handled by using enqueueKeyEvent * in Dialog.show */ + if (Component.isInstanceOf(modalComponent, "javax.swing.JInternalFrame")) { + /* + * Modal internal frames are handled separately. If event is + * for some component from another heavyweight than modalComp, + * it is accepted. If heavyweight is the same - we still accept + * event and perform further filtering in LightweightDispatcher + */ + return FilterAction.ACCEPT; + } int eventID = event.getID(); ! boolean mouseEvent = (eventID >= MouseEvent.MOUSE_FIRST) && ! (eventID <= MouseEvent.MOUSE_LAST); ! boolean actionEvent = (eventID >= ActionEvent.ACTION_FIRST) && ! (eventID <= ActionEvent.ACTION_LAST); ! boolean windowClosingEvent = (eventID == WindowEvent.WINDOW_CLOSING); ! if (mouseEvent || actionEvent || windowClosingEvent) { Object o = event.getSource(); if (o instanceof sun.awt.ModalExclude) { // Exclude this object from modality and
30-01-2007

EVALUATION This bug is introduced with the fix for 4080029 (AWT modality improvement). Among many other things, this fix contains events filters which are used to filter some kinds of events for blocked windows. Event filters work the following way. Any event, to be accepted for dispatching, must be accepted by all filters. Prior to the fix only the last modal component was required to accept event. This is why when two internal frames are shown, they block each other's events. While working with this bug I have also found, that some additional events filtering is performed in LightweightDispatcher. This piece of code was introduced right for modal internal frames (bad design :( ), so I have decided to reuse it instead of totally refactoring modal internal frames code. So the fix is: don't filter events for modal internal frames in event filters, leave LightweightDispatcher filter only. See suggested fix for details.
30-01-2007