JButton中不透明像素的事件检测 [英] Event detection on opaque pixels in JButton

查看:55
本文介绍了JButton中不透明像素的事件检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个扩展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 overriden paintComponent method, but because, especially with buttons, this will redraw the JButton background call setContentAreaFilled(false) on JButton instance to stop this. You may also want setBorderPainted(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中不透明像素的事件检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆