Java ImageIcons and actioin listeners

前端 未结 1 1712
暗喜
暗喜 2020-12-22 02:20

I am creating a simple game where a person clicks on an image the score increases by one. It seems simple enough, right? Here\'s the catch-- the images will be hidden partia

相关标签:
1条回答
  • 2020-12-22 02:53

    Example 1

    This basically uses a series of JLabels on a JLayeredPane. Each label has it's own mouse listener and when you mouse over it, will turn red. But, if there is a label above it, it won't respond to mouse events...

    enter image description here

    import java.awt.AlphaComposite;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    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.io.File;
    import javax.imageio.ImageIO;
    import javax.swing.Icon;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JLayeredPane;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class ClickMyImages {
    
        public static void main(String[] args) {
            new ClickMyImages();
        }
    
        public ClickMyImages() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JLayeredPane {
    
            public TestPane() {
                try {
                    BufferedImage img1 = ImageIO.read("/Image1");
                    BufferedImage img2 = ImageIO.read("/Image2");
                    BufferedImage img3 = ImageIO.read("/Image3");
                    BufferedImage img4 = ImageIO.read("/Image4");
                    BufferedImage img5 = ImageIO.read("/Image5");
    
                    JLabel label1 = new ClickableLabel(new ImageIcon(img1));
                    JLabel label2 = new ClickableLabel(new ImageIcon(img2));
                    JLabel label3 = new ClickableLabel(new ImageIcon(img3));
                    JLabel label4 = new ClickableLabel(new ImageIcon(img4));
                    JLabel label5 = new ClickableLabel(new ImageIcon(img5));
    
                    Dimension masterSize = getPreferredSize();
    
                    Dimension size = label1.getPreferredSize();
                    label1.setBounds((masterSize.width - size.width) / 2, (masterSize.height - size.height) / 2, size.width, size.height);
                    Point masterPoint = label1.getLocation();
                    size = label2.getPreferredSize();
                    label2.setBounds(
                            masterPoint.x - (size.width / 2), 
                            masterPoint.y - (size.height  / 2), 
                            size.width, size.height);
                    size = label3.getPreferredSize();
                    label3.setBounds(
                            masterPoint.x + (size.width / 2), 
                            masterPoint.y - (size.height  / 2), 
                            size.width, size.height);
                    size = label4.getPreferredSize();
                    label4.setBounds(
                            masterPoint.x - (size.width / 2), 
                            masterPoint.y + (size.height  / 2), 
                            size.width, size.height);
                    size = label5.getPreferredSize();
                    label5.setBounds(
                            masterPoint.x + (size.width / 2), 
                            masterPoint.y + (size.height  / 2), 
                            size.width, size.height);
    
                    add(label1);
                    add(label2);
                    add(label3);
                    add(label4);
                    add(label5);
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(800, 800);
            }
        }
    
        // This is for demonstration purposes only!
        public class ClickableLabel extends JLabel {
    
            private boolean isIn = false;
    
            public ClickableLabel(Icon image) {
                super(image);
                addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseEntered(MouseEvent e) {
                        isIn = true;
                        repaint();
                    }
    
                    @Override
                    public void mouseExited(MouseEvent e) {
                        isIn = false;
                        repaint();
                    }
                });
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (isIn) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                    g2d.setColor(Color.RED);
                    g2d.fillRect(0, 0, getWidth(), getHeight());
                    g2d.dispose();
                }
            }
        }
    }
    

    Example 2

    This examples uses the paintComponent method to renderer the images. It checks the pixel alpha of the image at the mouse point to determine if the mouse event should fall through or not.

    I've been a little strict using an alpha value of 255, but you could soften it a little based on your needs (something like 225 instead for example)...

    I've hard coded the layers so that the tree is always above the squirrel, but it wouldn't be hard to add all the images to List in the order you want them to appear and simple run down the list till you get a hit.

    enter image description here

    import java.awt.AlphaComposite;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Composite;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class ClickMyDrawnImages {
    
        public static void main(String[] args) {
            new ClickMyDrawnImages();
        }
    
        public ClickMyDrawnImages() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private BufferedImage tree;
            private BufferedImage squirrel;
            private BufferedImage mouseOver;
    
            public TestPane() {
                try {
                    tree = ImageIO.read(new File("Tree.png"));
                    squirrel = ImageIO.read(new File("Squirrel.png"));
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
                addMouseMotionListener(new MouseAdapter() {
                    @Override
                    public void mouseMoved(MouseEvent e) {
                        if (withinTree(e.getPoint())) {
                            mouseOver = tree;
                        } else if (withinSquirrel(e.getPoint())) {
                            mouseOver = squirrel;
                        } else {
                            mouseOver = null;
                        }
                        repaint();
                    }
                });
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            protected boolean withinTree(Point p) {
                return withinBounds(p, getTreeBounds(), tree);
            }
    
            protected boolean withinSquirrel(Point p) {
                return !withinBounds(p, getTreeBounds(), tree) && withinBounds(p, getSquirrelBounds(), squirrel);
            }
    
            protected Rectangle getTreeBounds() {
                int width = getWidth();
                int height = getHeight();
    
                int x = (width - tree.getWidth()) / 2;
                int y = (height - tree.getHeight()) / 2;
    
                return new Rectangle(x, y, tree.getWidth(), tree.getHeight());
            }
    
            protected Rectangle getSquirrelBounds() {
                Rectangle bounds = getTreeBounds();
    
                return new Rectangle(
                        bounds.x - (squirrel.getWidth() / 4),
                        (getHeight() - squirrel.getHeight()) / 2,
                        squirrel.getWidth(), squirrel.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                int width = getWidth();
                int height = getHeight();
    
                int x = (width - tree.getWidth()) / 2;
                int y = (height - tree.getHeight()) / 2;
    
                g.drawImage(highlight(squirrel), x - (squirrel.getWidth() / 4), (height - squirrel.getHeight()) / 2, this);
                g2d.drawImage(highlight(tree), x, y, this);
    
                g2d.dispose();
            }
    
            protected BufferedImage highlight(BufferedImage img) {
                BufferedImage highlight = img;
                if (img.equals(mouseOver)) {
                    highlight = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
                    Graphics2D g2d = highlight.createGraphics();
                    g2d.setColor(Color.RED);
                    g2d.drawImage(img, 0, 0, this);
    
                    g2d.setComposite(AlphaComposite.SrcAtop.derive(0.5f));
                    g2d.fillRect(0, 0, highlight.getWidth(), highlight.getHeight());
                    g2d.dispose();
                }
                return highlight;
            }
    
            protected boolean withinBounds(Point p, Rectangle bounds, BufferedImage image) {
                boolean withinBounds = false;
                if (bounds.contains(p)) {
                    int x = p.x - bounds.x;
                    int y = p.y - bounds.y;
                    int pixel = image.getRGB(x, y);
                    int a = (pixel >> 24) & 0xFF;
                    // could use a little weighting, so translucent pixels can be effected
                    if (a == 255) {
                        withinBounds = true;
                    }
                }
                return withinBounds;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题