<AWT Dev> Fwd: Found and solved a bug on Cursor Management on Windows platforms

Morvan Le Mescam morvan.lemescam at gmail.com
Mon Apr 22 09:32:37 PDT 2013

Dear all,

When developping a Swing client, I face the following problem :
When setting the hand cursor on Windows, I noticed that the default system
cursor was not used.

I analysed the problem and found the rrot cause.
I also made a correction and tested it on Windows 7.

This is my analyse :

When reading Java source code, it is obvious that on Windows, Java does not
use System resources.

In the code (from *jdk\src\windows\native\sun\windows\awt_Cursor.cpp* )
bellow :

AwtCursor * AwtCursor::*CreateSystemCursor*(jobject jCursor)


    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jint type = env->GetIntField(jCursor, AwtCursor::typeID);

    DASSERT(type != java_awt_Cursor_CUSTOM_CURSOR);

    LPCTSTR winCursor;

    switch (type) {

      case java_awt_Cursor_DEFAULT_CURSOR:


        winCursor = IDC_ARROW;


      case java_awt_Cursor_CROSSHAIR_CURSOR:

        winCursor = IDC_CROSS;



*      case java_awt_Cursor_HAND_CURSOR:*

*        winCursor = TEXT("HAND_CURSOR");*

*        break;*

      case java_awt_Cursor_MOVE_CURSOR:

        winCursor = IDC_SIZEALL;



*    HCURSOR hCursor = ::LoadCursor(NULL, winCursor);*

    if (*hCursor == NULL*) {

        /* Not a system cursor, check for resource. */

        *hCursor = ::LoadCursor(AwtToolkit::GetInstance().GetModuleHandle(),

*                               winCursor);*


    if (hCursor == NULL) {

        hCursor = ::LoadCursor(NULL, IDC_ARROW);

        DASSERT(hCursor != NULL);


    AwtCursor *awtCursor = new AwtCursor(env, hCursor, jCursor);

    setPData(jCursor, ptr_to_jlong(awtCursor));

    return awtCursor;


In the case of the HAND_CURSOR (*in red*),  Java will try to load the
cursor from the system (*in blue*).

If it fails (*hCursor == NULL*) then it will try to load the cursor from
its own resource (*in orange*) :

*hCursor = ::LoadCursor(AwtToolkit::GetInstance().GetModuleHandle(),*

*                               winCursor);*

In our case, if we check in the AWTToolkit module resources, in *
jdk\src\windows\native\sun\windows\awr.rc*, we find the following content :

#include "windows.h"

// Need 2 defines so macro argument to XSTR will get expanded before

#define XSTR(x) STR(x)

#define STR(x)  #x





And we find that java.exe embed its own hand cursor, in *
jdk\src\windows\native\sun\windows\hand.cur* : The “famous” hand that it is
displayed instead of our system cursor.

This is the correction :

, I made the correction into the JRE source code :

      case java_awt_Cursor_HAND_CURSOR:

        /* MLM change winCursor = TEXT("HAND_CURSOR"); */

        winCursor = IDC_HAND;


I could compile and regenerate a JRE with this change :

D:\Work\Current\openjdk\build\windows-amd64\bin>java -version

openjdk version "1.7.0-u6-unofficial"

OpenJDK Runtime Environment (build 1.7.0-u6-unofficial-b24)

OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)

And this works !

If I change the hand cursor at System level, Java takes it into account.
Last but not least question:

Why did a Sun developper, one day :  winCursor = TEXT("HAND_CURSOR");

This seems so not consistent with other part of the code... So there is
probably a good reason. Perhaps the hand cursor was not existant on Windows
platform when this was done ?


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20130422/0b1221c8/attachment.html 

More information about the awt-dev mailing list