【问题标题】:MouseEvents and Icon / ImageIcon鼠标事件和图标 / ImageIcon
【发布时间】:2013-01-14 19:41:10
【问题描述】:

请可以从Icon / ImageIcon 监听MouseEvents(在 API 中未实现任何通知器),无需从容器监听(JPanelJLabel)或通过使用转换事件SwingUtilities,实现并将XxxListener 添加到普通香草Icon / ImageIcon

编辑

类似于code (@pietblok),但可能不是我的问题的答案,我不确定创建图形对象、BufferedImage 和paintIcon 是否是最后一个属性

(我看到了一些类似的代码,这是SSCCE形式)

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.WeakHashMap;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class TestMouseAwareIcon {

    public static class MouseAwareIcon extends MouseAdapter implements Icon {

        private static final long serialVersionUID = 1L;
        private int size = 80, halfSize = 40;
        private final BufferedImage image;
        private Map components = new WeakHashMap();

        public MouseAwareIcon() {
            super();
            image = createImage();
        }

        @Override
        public int getIconHeight() {
            return image.getHeight();
        }

        @Override
        public int getIconWidth() {
            return image.getWidth();
        }

        @Override
        public void mouseClicked(MouseEvent event) {
            Object source = event.getSource();
            if (source instanceof Component) {
                Component component = (Component) source;
                Point paintPoint = (Point) components.get(component);
                if (paintPoint == null) {
                    System.out.println("unknown component");
                } else {
                    Point mousePoint = event.getPoint();
                    int imageX = mousePoint.x - paintPoint.x;
                    int imageY = mousePoint.y - paintPoint.y;
                    if (imageX >= 0 && imageX < this.getIconWidth() && imageY >= 0
                            && imageY < this.getIconHeight()) {
                        int argb = image.getRGB(imageX, imageY);
                        int alpha = (argb << 0) >>> 24;
                        int red = (argb << 8) >>> 24;
                        int green = (argb << 16) >>> 24;
                        int blue = (argb << 24) >>> 24;
                        System.out.println("Color clicked on "
                                + component.getName() + ": " + alpha + ","
                                + red + "," + green + "," + blue);
                        int fillX = halfSize * (imageX / halfSize);
                        int fillY = halfSize * (imageY / halfSize);
                        Graphics2D g2 = image.createGraphics();
                        g2.setColor(new Color(255 - red, 255 - green,
                                255 - blue, alpha));
                        g2.fill3DRect(fillX, fillY, halfSize, halfSize, true);
                        g2.dispose();
                        component.repaint();
                    } else {
                        System.out.println("Clicked outside image area");
                    }
                }
            }
        }

        @Override
        public void paintIcon(Component component, Graphics g, int x, int y) {
            ((Graphics2D) g).drawImage(image, null, x, y);
            if (!components.containsKey(component)) {
                component.addMouseListener(this);
            }
            components.put(component, new Point(x, y));
        }

        private BufferedImage createImage() {
            BufferedImage image1 = new BufferedImage(size, size,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = image1.createGraphics();
            Color[] colors = new Color[]{Color.BLACK, Color.RED, Color.GREEN,
                Color.BLUE};
            int colorIndex = 0;
            for (int x = 0; x < size; x += halfSize) {
                for (int y = 0; y < size; y += halfSize) {
                    g2.setColor(colors[colorIndex]);
                    g2.fill3DRect(x, y, halfSize, halfSize, true);
                    colorIndex++;
                }
            }
            g2.dispose();
            return image1;
        }
    }

    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);
                JLabel label = new JLabel(new MouseAwareIcon());
                label.setName("label");
                frame.getContentPane().add(label);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });    
    }
}

【问题讨论】:

  • 渲染 Icon/ImageIcon 的唯一两种方法是附加到支持图标渲染的组件(如 JLabel 和/或 JButton)或自己绘制...所以没有。
  • 为什么不使用未装饰的按钮?

标签: java swing imageicon mouse-listeners


【解决方案1】:

不,这是不可能的,您必须使用现有的 JComponent,如 JPanel 或 JLabel,或者实现一个 ad-hoc JComponent 来做您想做的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 2011-05-25
    • 2011-12-30
    • 2019-02-02
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多