Fwd: Found and solved a bug on Cursor Management on Windows platforms (original) (raw)
Morvan Le Mescam morvan.lemescam at gmail.com
Mon Apr 22 09:32:37 PDT 2013
- Previous message: hg: jdk8/awt/jdk: 8008366: [macosx] ActionListener called twice for JMenuItem using ScreenMenuBar
- Next message: Fwd: Found and solved a bug on Cursor Management on Windows platforms
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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:
default:
winCursor = IDC_ARROW;
break;
case java_awt_Cursor_CROSSHAIR_CURSOR:
winCursor = IDC_CROSS;
break;
[…]
case java_awt_Cursor_HAND_CURSOR:*
winCursor = TEXT("HAND_CURSOR");*
break;* case java_awt_Cursor_MOVE_CURSOR: winCursor = IDC_SIZEALL; break;
}
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 quoting.
#define XSTR(x) STR(x)
#define STR(x) #x
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
HAND_CURSOR CURSOR DISCARDABLE "hand.cur"
AWT_ICON ICON DISCARDABLE "awt.ico"
CHECK_BITMAP BITMAP DISCARDABLE "check.bmp"
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;
break;
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 ?
Regards
Morvan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20130422/0b1221c8/attachment.html
- Previous message: hg: jdk8/awt/jdk: 8008366: [macosx] ActionListener called twice for JMenuItem using ScreenMenuBar
- Next message: Fwd: Found and solved a bug on Cursor Management on Windows platforms
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]