Implementing Cursor in Java with some Transparency

假装没事ソ 提交于 2019-12-01 17:50:49

The problem your having is to do with the Cursor class which (under Windows) doesn't take into account the transparency values of the image

This is, by no means, a "real" solution, but is more about "fudging" the result...

public class TestMouseCursor {

    public static void main(String[] args) {
        new TestMouseCursor();
    }

    public TestMouseCursor() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new MouseCursorPane());
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MouseCursorPane extends JPanel {

        private BufferedImage cursorImage;
        private Toolkit kit;

        public MouseCursorPane() {
            try {
                kit = Toolkit.getDefaultToolkit();
                cursorImage = ImageIO.read(getClass().getResource("/cursor02.png"));
                for (int i = 0; i < cursorImage.getHeight(); i++) {
                    int[] rgb = cursorImage.getRGB(0, i, cursorImage.getWidth(), 1, null, 0, cursorImage.getWidth() * 4);
                    for (int j = 0; j < rgb.length; j++) {
                        int alpha = (rgb[j] >> 24) & 255;
                        if (alpha < 128) {
                            alpha = 0;
                        } else {
                            alpha = 255;
                        }
                        rgb[j] &= 0x00ffffff;
                        rgb[j] = (alpha << 24) | rgb[j];
                    }
                    cursorImage.setRGB(0, i, cursorImage.getWidth(), 1, rgb, 0,
                            cursorImage.getWidth() * 4);
                }
                Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(
                        cursorImage, new Point(0, 0), "CustomCursor");

                setCursor(cursor);

            } catch (Exception exp) {
                exp.printStackTrace();
            }
        }
    }
}

I got the idea for here

Charlie

Your code and cursor image actually produces the desired result on MacOS X 10.7.5 (jdk 1.6.0_31) with semi-transparent blue border. But I did notice an off comment in this answer saying that partial transparency is not supported in the default Windows look and feel.

If you are desperate and absolutely must have transparent cursor, no matter the consequences, you can use JNI and set the cursor manually using Win32 API. Windows since XP support alpha cursors, so you should be ok with that.

But you lose platform independence. And based on Windows settings, the alpha blending might be turned off for that particular user.

An alternative is to fake a cursor.

Take a look at Alexander Potochkin's Well Behaved GlassPane.

In particular, run the sample code, choose Options>GlassPane is Visible and Options>Final GlassPane.

Starting from this, load up a cursor image that is completely transparent, then paint a proper, alpha-blended cursor on the glasspane.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!