7

我有一个 35x40 像素。我想在 Swing 应用程序中用作自定义光标的 png 图像。该图像具有发光,因此包含 Alpha 透明度值。问题是当我尝试使用传统的方法Toolkit来生成自定义光标时,我会得到黑色像素,其中应该是 alpha 透明度值。

这是我用于光标的图像: https ://dl.dropbox.com/u/1186703/cursor.png

这是我的代码:

public static void main(String[] args) throws IOException {

     new Sandbox().gui();

}
private Cursor cursor;

private Toolkit kit;

private Image cursorImage;

public void gui() {

    kit = Toolkit.getDefaultToolkit();
    cursorImage = kit.createImage(getClass().getResource(
            "/aurora/V1/resources/cursor.png"));

    cursor = Toolkit.getDefaultToolkit().createCustomCursor(
            cursorImage, new Point(0, 0), "CustomCursor");

    setSize(800, 800);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setVisible(true);
    setCursor(cursor);
}

这是当前的结果:

结果

编辑似乎这种方法在跨平台上效果不佳,例如 Windows LAF 不支持半透明。因此,我正在寻找任何解决方案来让它在 Windows 上工作,假设这个实现在 Mac OSX 上工作,我可以在代码中指定根据应用程序运行的操作系统使用哪个实现。

4

4 回答 4

7

您的代码和光标图像实际上会在带有半透明蓝色边框的 MacOS X 10.7.5 (jdk 1.6.0_31) 上产生所需的结果。但我确实注意到这个答案中有一条评论说默认的 Windows 外观不支持部分透明度。

于 2012-11-10T22:01:55.317 回答
6

您遇到的问题与Cursor(在 Windows 下)不考虑图像透明度值的类有关

这绝不是一个“真正的”解决方案,而更多的是“捏造”结果......

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();
            }
        }
    }
}

我得到了这里的想法

于 2012-11-13T05:45:54.110 回答
2

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.

于 2012-11-14T14:44:31.573 回答
2

另一种方法是伪造光标。

看看 Alexander Potochkin 的Well Behaved GlassPane

特别是,运行示例代码,选择Options>GlassPane is VisibleOptions>Final GlassPane

从这里开始,加载一个完全透明的光标图像,然后在玻璃板上绘制一个适当的 alpha 混合光标。

于 2012-11-18T00:41:05.070 回答