JDK-4132824 : setCursor doesn't always set the cursor correctly
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.6,1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: generic,windows_95,windows_nt
  • CPU: generic,x86
  • Submitted: 1998-04-27
  • Updated: 1998-09-29
  • Resolved: 1998-09-29
Related Reports
Relates :  
Description
Hi guys,

Here is a test case showing how setCursor sometimes fails miserably.
The goal was to set the cursor to busy for the entire app by 
doing setCursor on the top level frame and then recursively visiting
each child and doing a setCursor on it. The first comment in the
test program discribes how this fails.

===========================================================================

/*
  This test shows that the setCursor method fails to change the visual
  appearance of the cursor in some cases. The goal here was to change
  the cursor for the entire application to a busy cursor. The actionPerformed
  gets executed if the user hits the Enter key when the focus is on the JTextField
  or if the user clicks on the "Connect" button. The cursor is set to busy
  for the entire application by doing a setCursor on the top JFrame and then
  recursively going down the tree and calling setCursor for each Component.
  This works just fine if you hit enter on the JTextField. However, if you
  click the mouse on the "Connect" button, the JTextField and the JButton
  get the busy cursor, but the JLabel and the JFrame do not. To test it,
  click the button and then move the cursor around the app, seeing that
  it switches back and forth from busy to arrow.

  I tried doing the call to the recursive setCursor in an invokeLater,
  but the behavior was the same.
*/


import com.sun.java.swing.JButton;
import com.sun.java.swing.JFrame;
import com.sun.java.swing.JLabel;
import com.sun.java.swing.JTextField;
import com.sun.java.swing.UIManager;
import com.sun.java.swing.UnsupportedLookAndFeelException;

import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.FlowLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestCursors implements  ActionListener {

  JFrame     myFrame;
  JButton    connectButton;

  public static void main(String[] args)
  {
           
    // Set the windows look and feel

    try {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (ClassNotFoundException ex) {
    } catch (IllegalAccessException ex) {
    } catch (InstantiationException ex) {
    } catch (UnsupportedLookAndFeelException ex) {
    }
      TestCursors t3gc = new TestCursors();
      t3gc.lookupViaDialog();
  }

  public TestCursors()  { }

  private void lookupViaDialog()
  {
    myFrame = new JFrame("WebLogic Tengah Server Login");

    Container bg = myFrame.getContentPane();
    bg.setLayout( new FlowLayout() );

    JLabel usernameLabel = new JLabel("User name");
    bg.add(usernameLabel);
    JTextField usernameField = new JTextField("xxx",20);

    bg.add(usernameField);

    connectButton = new JButton("Connect");

    bg.add(connectButton);

    connectButton.addActionListener(this);
    usernameField.addActionListener(this);

    myFrame.setSize(400,70);
    myFrame.setVisible(true);
    return ;
  }

  public void actionPerformed(ActionEvent ae) {

    // Set the busy cursor
    // I tried doing the setCursor in a run method, executed with invokeLater,
    // but it did not change the behavior at all.

    setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ), myFrame );

    connectButton.setEnabled(false);
    
    return;
  }

  static public void setCursor(Cursor crsr, Component cmp) {

    // This routine sets the Cursor crsr on Component cmp and all of its children.
    // If cmp is the top level Component, the effect is setting the busy cursor on the
    // entire application.

    cmp.setCursor(crsr);
    if (cmp instanceof Container) {
      Component[] kids = ((Container)cmp).getComponents();
      for (int i = 0 ; i < kids.length ; i++) {
        setCursor(crsr,kids[i]);
      }
    }
    return;
  }

}

Comments
EVALUATION There is a bug with lightweight components where the cursor is only updated on mouse events. If there are no mouse events the cursor will not be updated, which is not what one wants typically with the busy cursor. timothy.prinzing@eng 1998-05-28
28-05-1998