JDK-5079694 : JDialog doesn't respect setCursor
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0,5.0u17-crev,6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    linux,solaris_1,windows_2000,windows_xp,windows_vista linux,solaris_1,windows_2000,windows_xp,windows_vista
  • CPU: x86,sparc,itanium
  • Submitted: 2004-07-28
  • Updated: 2005-08-06
  • Resolved: 2005-08-06
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
6 b47Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Description
Name: rmT116609			Date: 07/28/2004


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

java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
When using a JDialog, setting a cusor on one if its child components (say a label added to it) - the cursor is ignored. This works fine with JFrame however.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When hovering the mouse over a central component (a JLabel in the BorderLayout.CENTER position), the mouse cursor should change from the pointer to a hand.
ACTUAL -
The cursor stay the same (e.g. a pointer) when the JDialog is used, but it works fine when a JFrame is used.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.LineBorder;

import junit.framework.TestCase;

/**
 * Test case to demonstrate problem/difference between JDialog and JFrame
 * cursor.
 */
public class JDialogCursor_TestCase extends TestCase
{
  public void testJDialogCursor()
  	throws Exception
  {
    JDialog dialog = new JDialog();
    dialog.setTitle("JDialog cursor test (fails)");
    dialog.setLayout(new BorderLayout());
    dialog.add(new JLabel("Close this dialog when ready to continue"), BorderLayout.NORTH);
    JLabel centerLabel = new JLabel("Cursor should be a hand in this label area");
    centerLabel.setBorder(new LineBorder(Color.BLACK));
    centerLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    dialog.add(centerLabel, BorderLayout.CENTER);
    dialog.setSize(400, 200);
    dialog.setVisible(true);
    while (dialog.isVisible())
    {
      Thread.sleep(1000);
    }
    dialog.dispose();
  }
  
  public void testJFrameCursor()
  	throws Exception
  {
    JFrame frame = new JFrame();
    frame.setTitle("JFrame cursor test (works)");
    frame.setLayout(new BorderLayout());
    frame.add(new JLabel("Close this frame when ready to continue"), BorderLayout.NORTH);
    JLabel centerLabel = new JLabel("Cursor should be a hand in this label area");
    centerLabel.setBorder(new LineBorder(Color.BLACK));
    centerLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    frame.add(centerLabel, BorderLayout.CENTER);
    frame.setSize(400, 200);
    frame.setVisible(true);
    while (frame.isVisible())
    {
      Thread.sleep(1000);
    }
    frame.dispose();
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use JFrame instead of JDialog. However, JFrame does not have the modality control like a JDialog does.
(Incident Review ID: 277202) 
======================================================================

Comments
SUGGESTED FIX ------- Component.java ------- *** - Fri Jul 15 23:24:37 2005 --- Component.java Fri Jul 15 23:16:47 2005 *************** *** 1071,1077 **** * are visible, <code>false</code> otherwise */ boolean isRecursivelyVisible() { ! return visible && (parent == null || parent.isRecursivelyVisible()); } /** --- 1071,1077 ---- * are visible, <code>false</code> otherwise */ boolean isRecursivelyVisible() { ! return visible && (this instanceof Window || parent == null || parent.isRecursivelyVisible()); } /** ###@###.### 2005-07-15 19:26:01 GMT
15-07-2005

WORK AROUND Use a dialog with a visible owner. (This entails usage of a constructor with the owner agrument instead of the no-arg one.) ###@###.### 2005-1-12 11:39:50 GMT
12-01-2005

EVALUATION While the submitter unfortunately provided the test case in a non-runnable format (based on their own test framework) there was enough information to do some diagnosis. The two methods testJDialogCursor and testJFrameCursor can each independently by separated and put into a main method. In any case, my testing revealed the following: When using JDialog, setCursor only works when the dialog's owner is visible on the screen. I determined this by using a JDialog with a JFrame parent. If the JFrame was showing, the cursor worked - if not, it didn't. In the case of Swing, JDialogs use a hidden shared owner frame and this is why this test case is not working. This is a regression in tiger. ###@###.### 2004-07-28 AWT toplevels and components show cursor independently of visibility state of the parent. I suspect this is because of the error in light-weight cursor tracking mechanism, probably somewhere we erronously cross the boundaries of toplevel hierarchy. ###@###.### 2004-07-29 Name: ag153227 Date: 07/29/2004 This regression was introduced with the fixes for the bugs 4311614 and 4923145. When the cursor is above JDialog's lightweight child, Container.findComponentAt(cursor position) returns null since JDialog is not recursively visible: JDialog's parent is SwingUtilities.SharedOwnerFrame which is invisible. Container.findComponentAt() should determine recursive visibility of a top-level merely as its visibility, without taking into consideration visibility of its parent. ###@###.### ======================================================================
30-07-2004