Java JButton中不透明像素的事件检测
我有一个扩展了Java JButton中不透明像素的事件检测,java,swing,jbutton,paintcomponent,Java,Swing,Jbutton,Paintcomponent,我有一个扩展了JButton的类,我正试图将.png图像应用于该类。 图像形状不规则,周围有透明像素。我已经覆盖了JButton中的paintComponent()方法,将缓冲图像应用于按钮。现在,图像是唯一正在绘制的东西,这就是我想要的 但是,按钮仍在其周围的矩形中检测事件。是否有办法将检测限制在仅包含不透明像素的区域(或者不检测透明像素上的事件) 按钮类的代码如下 public class DrawButton extends JButton{ private BufferedIm
JButton
的类,我正试图将.png图像应用于该类。
图像形状不规则,周围有透明像素。我已经覆盖了JButton
中的paintComponent()
方法,将缓冲图像应用于按钮。现在,图像是唯一正在绘制的东西,这就是我想要的
但是,按钮仍在其周围的矩形中检测事件。是否有办法将检测限制在仅包含不透明像素的区域(或者不检测透明像素上的事件)
按钮类的代码如下
public class DrawButton extends JButton{
private BufferedImage bi;
public DrawButton(BufferedImage bi){
setPreferredSize(new Dimension(bi.getWidth(), bi.getHeight()));
this.bi = bi;
}
@Override
protected void paintComponent(Graphics g){
g.drawImage(bi, 0, 0, null);
g.dispose();
}
}
我建议使用
MouseAdapter
,并覆盖mouseClicked(…)
。在mouseClicked
中,检查单击点的像素是否为alpha,如果为“不做任何事情”,如果为“不做任何事情”
- 始终将调用
作为重写的super.paintComponent(..)
方法中的第一个调用,但因为,特别是使用按钮,这将在paintComponent
实例上重新绘制JButton
后台调用JButton
。您可能还需要setContentAreaFilled(false)
设置(false)
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class TransparentButton {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyButton button = null;
try {
button = new MyButton(scaleImage(100, 100, ImageIO.read(new URL("http://2.bp.blogspot.com/-eRryNji1gQU/UCIPw0tY5bI/AAAAAAAASt0/qAvERbom5N4/s1600/original_smiley_face.png"))));
} catch (Exception ex) {
ex.printStackTrace();
}
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
MyButton mb = ((MyButton) me.getSource());
if (!isAlpha(mb.getIconImage(), me.getX(), me.getY())) {
JOptionPane.showMessageDialog(frame, "You clicked the smiley");
}
}
private boolean isAlpha(BufferedImage bufImg, int posX, int posY) {
int alpha = (bufImg.getRGB(posX, posY) >> 24) & 0xFF;
return alpha == 0;
}
});
frame.add(button);
frame.pack();
frame.setVisible(true);
}
});
}
public static BufferedImage scaleImage(int w, int h, Image img) throws Exception {
BufferedImage bi;
bi = new BufferedImage(w, h, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(img, 0, 0, w, h, null);
return bi;
}
}
class MyButton extends JButton {
BufferedImage icon;
MyButton(BufferedImage bi) {
this.icon = ((BufferedImage) bi);
setContentAreaFilled(false);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(icon.getWidth(), icon.getHeight());
}
public BufferedImage getIconImage() {
return icon;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(icon, 0, 0, this);
}
}
@david看了你的答案——我需要先调用
super.paintComponent()
吗?如果我这样做了,它会保留原来的按钮背景,这是我不想要的。非常感谢!这是完美的(至少目前看来是如此)!看起来您使用的代码与我看的另一个问题()相同,但我无法理解。这个更完整的例子很有意义。@user18是的,只是根据最佳实践修改了这个例子,并将其应用到针对您的具体问题的SSCE中。而不是使用return alpha==0?真:假代码>简单写入返回alpha==0
;-)@GuillaumePolet+1 lol非常真实地谈论过复杂化一句简单的话:)谢谢