-
Bug
-
Resolution: Duplicate
-
P3
-
11, 15
ADDITIONAL SYSTEM INFORMATION :
Windows 10
A DESCRIPTION OF THE PROBLEM :
The hotspot is in the wrong position, even in the latest available JDK version15 EA Build 6.
It is reproducible every time on a screen having scaling set to 200% (probably on all scaling levels >100%).
Constructing the cursor sized according to Toolkit.getBestCursorSize() fixes the problem. However, the hotspot should also be set correctly when the image is smaller.
It is quite apparent from the JDK source code
https://github.com/openjdk/jdk/blob/6bab0f539fba8fb441697846347597b4a0ade428/src/java.desktop/share/classes/sun/awt/CustomCursor.java
that the cursor image is scaled in certain cases (line 71), but the hotspot is not scaled accordingly.
Fixing this should be quite trivial. Please solve this problem after being open for 4 years.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the attached test program and click into the opened window.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The rectangles drawn on click should appear at the very center of the haircross.
ACTUAL -
The drawn rectangles appear in the top left quadrant, off the center of the haircross.
(Too bad not screenshots can be submitted here.)
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
public class CustomCursorHotspot {
public static void main(String[] args)
{
Dimension bestCursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(32, 32);
assert bestCursorSize.width == bestCursorSize.height;
final int cursorSize = 32; // this triggers the bug
//final int cursorSize = bestCursorSize.width; // this is the workaround
// construct framed haircross
BufferedImage bufferedImage = new BufferedImage(cursorSize, cursorSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D bg = bufferedImage.createGraphics();
bg.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
bg.clearRect(0, 0, cursorSize, cursorSize);
bg.setColor(Color.BLACK);
bg.drawRect(0, 0, cursorSize - 1, cursorSize - 1);
bg.setStroke(new BasicStroke(2));
bg.drawLine(cursorSize / 2, 0, cursorSize / 2, cursorSize);
bg.drawLine(0, cursorSize / 2, cursorSize, cursorSize / 2);
Frame frame = new Frame();
frame.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
bufferedImage, new Point(cursorSize / 2, cursorSize / 2), "haircross"));
frame.setSize(new Dimension(500, 500));
frame.setVisible(true);
frame.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
Graphics graphics = frame.getGraphics();
graphics.setColor(Color.RED);
graphics.drawRect(e.getX() - 1, e.getY() - 1, 3, 3);
}
@Override
public void mousePressed(MouseEvent e) { }
@Override
public void mouseReleased(MouseEvent e) { }
@Override
public void mouseEntered(MouseEvent e) { }
@Override
public void mouseExited(MouseEvent e) { }
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Provide the cursor image in a size matching Toolkit.getBestCursorSize().
To test this, uncomment the second line setting cursorSize, and comment out the first one.
FREQUENCY : always
Windows 10
A DESCRIPTION OF THE PROBLEM :
The hotspot is in the wrong position, even in the latest available JDK version15 EA Build 6.
It is reproducible every time on a screen having scaling set to 200% (probably on all scaling levels >100%).
Constructing the cursor sized according to Toolkit.getBestCursorSize() fixes the problem. However, the hotspot should also be set correctly when the image is smaller.
It is quite apparent from the JDK source code
https://github.com/openjdk/jdk/blob/6bab0f539fba8fb441697846347597b4a0ade428/src/java.desktop/share/classes/sun/awt/CustomCursor.java
that the cursor image is scaled in certain cases (line 71), but the hotspot is not scaled accordingly.
Fixing this should be quite trivial. Please solve this problem after being open for 4 years.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the attached test program and click into the opened window.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The rectangles drawn on click should appear at the very center of the haircross.
ACTUAL -
The drawn rectangles appear in the top left quadrant, off the center of the haircross.
(Too bad not screenshots can be submitted here.)
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
public class CustomCursorHotspot {
public static void main(String[] args)
{
Dimension bestCursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(32, 32);
assert bestCursorSize.width == bestCursorSize.height;
final int cursorSize = 32; // this triggers the bug
//final int cursorSize = bestCursorSize.width; // this is the workaround
// construct framed haircross
BufferedImage bufferedImage = new BufferedImage(cursorSize, cursorSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D bg = bufferedImage.createGraphics();
bg.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
bg.clearRect(0, 0, cursorSize, cursorSize);
bg.setColor(Color.BLACK);
bg.drawRect(0, 0, cursorSize - 1, cursorSize - 1);
bg.setStroke(new BasicStroke(2));
bg.drawLine(cursorSize / 2, 0, cursorSize / 2, cursorSize);
bg.drawLine(0, cursorSize / 2, cursorSize, cursorSize / 2);
Frame frame = new Frame();
frame.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
bufferedImage, new Point(cursorSize / 2, cursorSize / 2), "haircross"));
frame.setSize(new Dimension(500, 500));
frame.setVisible(true);
frame.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
Graphics graphics = frame.getGraphics();
graphics.setColor(Color.RED);
graphics.drawRect(e.getX() - 1, e.getY() - 1, 3, 3);
}
@Override
public void mousePressed(MouseEvent e) { }
@Override
public void mouseReleased(MouseEvent e) { }
@Override
public void mouseEntered(MouseEvent e) { }
@Override
public void mouseExited(MouseEvent e) { }
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Provide the cursor image in a size matching Toolkit.getBestCursorSize().
To test this, uncomment the second line setting cursorSize, and comment out the first one.
FREQUENCY : always
- duplicates
-
JDK-8158776 [hidpi] The hotspot of the custom cursor isn't correct
-
- Closed
-
- relates to
-
JDK-8158776 [hidpi] The hotspot of the custom cursor isn't correct
-
- Closed
-