问题描述
我有一个扩展JButton
的类,正在尝试将 .png 图像应用到该类.图像形状不规则,并被透明像素包围.我已经覆盖了JButton
中的paintComponent()
方法,以将缓冲的图像应用于按钮.现在,图像是唯一要绘制的东西,这就是我想要的.
I have a class extending JButton
that I am trying to apply a .png image to.The image is irregular in shape, and is surrounded by transparent pixels. I have overridden the paintComponent()
method in the JButton
to apply my buffered image to the button. Right now, the image is the only thing being drawn, which is what I want.
但是,该按钮仍在检测矩形周围的事件.有没有一种方法可以将检测限制为仅包含不透明像素的区域(或者不检测透明像素上的事件)?
However, the button is still detecting events in the rectangle around it. Is there a way to limit detection to only the area containing opaque pixels (or rather to not detect events on the transparent pixels)?
下面是按钮类的代码.
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 ,否则不执行任何操作.
Well I would suggest using a MouseAdapter
, and override mouseClicked(..)
. In mouseClicked
check if pixel is alpha at point of click if it is do nothing, if not do something.
- 始终在覆盖的
paintComponent
方法中作为第一个调用调用super.paintComponent(..)
,但是因为尤其是使用按钮,这将在JButton
实例上重绘JButton
后台调用setContentAreaFilled(false)
来停止此操作.您可能还需要setBorderPainted(false)
.
- Always call
super.paintComponent(..)
as first call in overridenpaintComponent
method, but because, especially with buttons, this will redraw theJButton
background callsetContentAreaFilled(false)
onJButton
instance to stop this. You may also wantsetBorderPainted(false)
too.
这是我制作的一个小示例(改编自此处):
Here is a small example I made (adapted from here):
如果点击笑脸:
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);
}
}
这篇关于JButton中不透明像素的事件检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!