使用一些透明度在Java中实现Cursor

我有35×40像素。 png图像我想在Swing应用程序中用作自定义光标。 图像具有发光,因此包含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上工作,我可以在代码中指定基于运行应用程序的操作系统使用哪个实现。

您遇到的问题与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(); } } } } 

我在这里得到了主意

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

如果你绝望并且绝对必须有透明光标,无论结果如何,你都可以使用JNI并使用Win32 API手动设置光标。 Windows自XP以来支持alpha游标,所以你应该没问题。

但是你失去了平台独立性。 并且基于Windows设置,可能会为该特定用户关闭Alpha混合。

另一种方法是伪造光标。

看看Alexander Potochkin的Well Behaved GlassPane 。

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

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