【发布时间】:2011-10-07 19:57:32
【问题描述】:
阅读编辑 2,了解我实际上缺少什么以使其正常工作
我目前正在尝试使用在 Photoshop 中创建的具有 alpha 参数的图像创建一些自定义 JButton。
到目前为止,重写paint() 方法来绘制图像在按钮被绘制以显示正确图像的意义上是有效的。不过,我想改进它,使其形状(可点击区域)与图像上的可见像素相同(现在如果我绘制按钮的边框,它是一个正方形)。
有没有一种简单的方法可以做到这一点,还是我必须解析图像并找到 alpha 像素来制作自定义边框?
我必须重写哪些方法才能使其按我想要的方式工作?
另外,我稍后会提出另一个问题:使用某种算法来更改图像的颜色以使其看起来像是被点击时会更好,还是我会更好创建第二张图像并在按钮处于活动状态时绘制该图像?
编辑:我刚刚读到其他一些问题,我应该重新定义paintComponent()而不是paint(),我想知道为什么重新定义paint()可以正常工作?
编辑 2: 我更改了所有内容以确保我的 JButton 是使用带有图标的默认构造函数创建的。我想要做的是获取单击注册位置的 X 和 Y 位置,并在该位置抓取图标的像素并检查其 alpha 通道以查看它是否为 0(如果是,则什么也不做,否则执行它应该做的动作)。
问题是,Alpha 通道总是返回 255(蓝色、红色和绿色在透明像素上的值为 238)。在其他像素上,一切都返回它应该返回的值。
这是一个重现我的问题的示例(如果需要,可以尝试使用另一张图片):
public class TestAlphaPixels extends JFrame
{
private final File FILECLOSEBUTTON = new File("img\\boutonrondX.png"); //My round button with transparent corners
private JButton closeButton = new JButton(); //Creating it empty to be able to place it and resize the image after the button size is known
public TestAlphaPixels() throws IOException
{
setLayout(null);
setSize(150, 150);
closeButton.setSize(100, 100);
closeButton.setContentAreaFilled(false);
closeButton.setBorderPainted(false);
add(closeButton);
closeButton.addMouseListener(new MouseListener()
{
public void mouseClicked(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
System.out.println("Alpha value of pixel (" + e.getX() + ", " + e.getY() + ") is: " + clickAlphaValue(closeButton.getIcon(), e.getX(), e.getY()));
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
});
Image imgCloseButton = ImageIO.read(FILECLOSEBUTTON);
//Resize the image to fit the button
Image newImg = imgCloseButton.getScaledInstance((int)closeButton.getSize().getWidth(), (int)closeButton.getSize().getHeight(), java.awt.Image.SCALE_SMOOTH);
closeButton.setIcon(new ImageIcon(newImg));
}
private int clickAlphaValue(Icon icon, int posX, int posY)
{
int width = icon.getIconWidth();
int height = icon.getIconHeight();
BufferedImage tempImage = (BufferedImage)createImage(width, height);
Graphics2D g = tempImage.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
int alpha = (tempImage.getRGB(posX, posY) >> 24) & 0x000000FF;
return alpha;
}
public static void main(String[] args)
{
try
{
TestAlphaPixels testAlphaPixels = new TestAlphaPixels();
testAlphaPixels.setVisible(true);
testAlphaPixels.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
这只是一个疯狂的猜测,但是当我的图像被投射到一个图标时,它是否有可能失去它的 Alpha 属性,因此不会返回正确的值?无论如何,如果有人能真正帮助我并告诉我应该改变什么以获得正确的值,我将不胜感激。
我猜是因为当我尝试使用原始图像时,alpha 通道的值很好,但我实际上不能使用 BufferedImage,因为我调整了它的大小,所以我实际上得到了图像的通道值原来的大小...
【问题讨论】:
-
如果您希望按钮只是图像,为什么不使用
JLabel并将图像设置为其图标? -
第一个原因是我将有一些按钮在从数组生成的图像上显示文本。第二个是我不知道将其设为 JLabel 只会绘制非透明像素(因此不会将 alpha 像素视为点击)。我可能会尝试这样做,但我仍然需要编写方法来绘制它,让它看起来像是被点击了。
-
关于您的第二次编辑,您为什么要准确地测试 alpha?如果这是为了查看您是否单击了圆形按钮,则有更好的方法可以做到这一点,如果是这种情况,我会将其发布为答案。仅当形状不典型时,测试 alpha 才可能派上用场。 (我看到你的是圆的?)
-
@paranoid-android 您的解决方案运行良好,肯定会派上用场。问题是我稍后将在这个程序中使用其他形状奇特的按钮,我只是不能将它们用作示例,因为我还没有创建它们,所以圆形按钮不适用于这些按钮。我可能会使用你的方法来制作圆形按钮,因为它更简单,不过谢谢!
-
@Adam Smith:很高兴听到这个消息。 :) 如果您采用 JButton 的扩展并开始集成
Shapes,那么您就走在了正确的轨道上。希望您的应用适合您。
标签: java swing icons jbutton imageicon