JDK-4772092 : deadlock with JOptionPane.showInternalConfirmDialog and EventQueue
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.1
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-10-31
  • Updated: 2002-11-01
  • Resolved: 2002-11-01
Related Reports
Duplicate :  
Description

Name: rmT116609			Date: 10/31/2002


FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
There is a deadlock problem when using
JOPtionPane.showInternalConfirmDialog and
overriding java.awt.EventQueue

See attache code

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. compile TestWaitEventQueue.java
2. execute TestWaitEventQueue
3. click on button

when you try to use a Dialog over a JInternalFrame
and you have overridden EventQueue (as done in the
attached example), there is a deadlock !!

EXPECTED VERSUS ACTUAL BEHAVIOR :

There should be no deadlock !

ERROR MESSAGES/STACK TRACES THAT OCCUR :

GUI is freezing

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TestWaitEventQueue extends javax.swing.JFrame {

    private javax.swing.JDesktopPane m_theDeskTopPane;
    private javax.swing.JInternalFrame m_theNewFrame;

    public static void main(String[] args) {
        Toolkit theToolkit = Toolkit.getDefaultToolkit();
        EventQueue theWaitQueue = new WaitCursorEventQueue(500);
    	theToolkit.getSystemEventQueue().push(theWaitQueue);
        TestWaitEventQueue theFrame = new TestWaitEventQueue();
        Dimension theScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
        theFrame.setSize(theScreenSize.width - 100, theScreenSize.height - 100);
        theFrame.show();
    }
    
    public TestWaitEventQueue() {
        initComponents();
        addInternal();
    }
    
    private void initComponents() {
        m_theDeskTopPane = new javax.swing.JDesktopPane();

        setTitle("Test Event Queue");
        setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        getContentPane().add(m_theDeskTopPane, java.awt.BorderLayout.CENTER);

        pack();
    }

    private void addInternal() {
        m_theNewFrame = new javax.swing.JInternalFrame("child");
        m_theNewFrame.getContentPane().setLayout(new FlowLayout());
        JButton theButton = new JButton("Show Dialog");
        m_theNewFrame.getContentPane().add(theButton);
        theButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent p_theAE) {
                JOptionPane theOptionPane = new JOptionPane();
                int iSelectedValue = theOptionPane.showInternalConfirmDialog(
                    m_theNewFrame, "You won't ever see this",
                    "confirmation", JOptionPane.YES_NO_OPTION);

                if (iSelectedValue == JOptionPane.YES_OPTION) {
                    System.out.println("YES");
                } else {
                    System.out.println("NO");
                }
                System.out.println("DONE");
            }
        });
        m_theDeskTopPane.add(m_theNewFrame);
        m_theNewFrame.show();
        try {
            m_theNewFrame.setMaximum(true);
        } catch (java.beans.PropertyVetoException pe) {}
    }
    
}

class WaitCursorEventQueue extends EventQueue {

    private int m_iDelay;
    private WaitCursorTimer m_theWaitTimer;

    public WaitCursorEventQueue(int p_iDelay) {
        m_iDelay = p_iDelay;
        m_theWaitTimer = new WaitCursorTimer();
        m_theWaitTimer.setDaemon(true);
        m_theWaitTimer.start();
    }

    protected void dispatchEvent(AWTEvent p_theEvent) {
        m_theWaitTimer.startTimer(p_theEvent.getSource());
        try {
            super.dispatchEvent(p_theEvent);
	} finally {
            m_theWaitTimer.stopTimer();
	}
    }

    private class WaitCursorTimer extends Thread {
        private Object m_theSource;
        private Component m_theParent;
		
	synchronized void startTimer(Object p_theSource) {
            m_theSource = p_theSource;
            notify();
	}

	synchronized void stopTimer() {
            if (m_theParent == null)
                interrupt();
            else {
                m_theParent.setCursor(null);
		m_theParent = null;
            }
	}

        public synchronized void run() {
            while (true) {
                try {
                    //wait for notification from startTimer()
                    wait();

                    //wait for event processing to reach the threshold, or
                    //interruption from stopTimer()
                    wait(m_iDelay);

                    if (m_theSource instanceof Component)
                        m_theParent = SwingUtilities.getRoot(
                             (Component) m_theSource);
                    else
                        if (m_theSource instanceof MenuComponent) {
                            MenuContainer mParent =
                                ((MenuComponent) m_theSource).getParent();
                            if (mParent instanceof Component)
                                m_theParent =
                                  SwingUtilities.getRoot((Component) mParent);
                        }

                    if (m_theParent != null && m_theParent.isShowing())
                        m_theParent.setCursor(
                           Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                } catch (InterruptedException ie) {}
            }
        }
    }
}
---------- END SOURCE ----------

(Review ID: 166121) 
======================================================================

Comments
EVALUATION Name: osR10079 Date: 11/01/2002 The problem is reproducible with 1.4.1b21, but not reproducible with 1.4.2b03. After investigation i found that the cause of this problem was the same as for 4667544 (CSH Locks Application When Using Other Than Default Event Queue) and 4667544 was fixed in 1.4.2b02. So, we can close this bug as duplicate of 4667544. ###@###.### 2002-11-01 ======================================================================
01-11-2002