I want to create an invisible clickable object over an image in Java

你离开我真会死。 提交于 2019-12-02 10:27:14

You never add a mouse listener to the frame.

Having said that...

  • You should avoid extending from top level containers, such as JFrame
  • You should avoid painting onto top level containers (by overriding any of the paint methods)
  • You should ALWAYS call super.paintXxx (unless you have an incredibly good reason to do otherwise) as the paint methods a rather complex and perform a lot of very import work
  • Unless you're loading large images or downloading images from the Internet (even then), you should use the ImageIO. It has support for a larger number of images.

In your mouse clicked event, you need to determine the current image that is begin displayed. You need to determine is boundaries and determine if the mouse was clicked in it.

// Current index maintains the index of the current image...
// You should replace g.drawImage(pictureArray[0], 100, 100, this) with
// g.drawImage(pictureArray[currentIndex], 100, 100, this)
Image currentImage = pictureArray[currentIndex];
Rectangle bounds = new Rectangle(100, 100, currentImage.getWidth(this), currentImage.getHeight(this));
if (bounds.contains(arg0.getPoint()) {
  // Image was clicked...
  currentIndex++;
  if (currentIndex >= pictureArray.length) {
      currentIndex = 0;
  }
  repaint();
}

UPDATED with example

This is a crude example. Basically it uses a custom JPanel that paints the image. To this I add a MouseListener.

The main program uses a folder and scrolls through, displaying each (valid) image on the image panel as you click.

Mouse clicks will only occur within the context of the image panel itself.

public class ImageScoller {

    public static void main(String[] args) {
        new ImageScoller();
    }

    public ImageScoller() {
        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 ImageViewPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ImageViewPane extends JPanel {

        private ImagePane imagePane;
        private File[] fileList;
        private int currentIndex = -1;

        public ImageViewPane() {

            fileList = new File("/path/to/some/folder/with/images").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.isFile();
                }
            });

            imagePane = new ImagePane();
            imagePane.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    nextImage();
                }
            });
            setLayout(new GridBagLayout());
            add(imagePane);

            nextImage();
        }

        public void nextImage() {
            if (fileList != null && fileList.length > 0) {
                currentIndex++;
                if (currentIndex < 0 || currentIndex >= fileList.length) {
                    currentIndex = 0;
                }
                Image image = null;
                /*
                    Because I don't know the contents of the folder, this is a little
                    more complicated then it really needs to be.

                    If you know the file is an image, you can simply use ImageIO.read(file)
                */
                while (image == null && currentIndex < fileList.length) {
                    System.out.println("Loading next image: " + currentIndex);
                    try {
                        ImageInputStream iis = ImageIO.createImageInputStream(fileList[currentIndex]);
                        if (iis != null) {
                            Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(iis);
                            if (imageReaders != null && imageReaders.hasNext()) {
                                ImageReader imageReader = imageReaders.next();
                                imageReader.setInput(iis);
                                image = imageReader.read(0);
                            } else {
                                currentIndex++;
                            }
                        } else {
                            currentIndex++;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        currentIndex++;
                    }
                }
                imagePane.setImage(image);
                invalidate();
                repaint();
            }
        }
    }

    public class ImagePane extends JPanel {

        private Image image;
        private JLabel label;

        public ImagePane() {
            setLayout(new GridBagLayout());
            label = new JLabel("No image available");
            add(label);
        }

        public void setImage(Image value) {
            if (image != value) {
                image = value;
                label.setVisible(image == null);
                repaint();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (image != null) {
                int width = getWidth();
                int height = getHeight();
                int x = (width - image.getWidth(this)) / 2;
                int y = (height - image.getHeight(this)) / 2;
                g.drawImage(image, x, y, this);
            }
        }
    }
}

Why do you want an invisible object above your image?

Anyway, to answer your question, create a JPanel located just as your image.

JPanel yourPanel = new JPanel() Set it's location same as your image.
Create a MouseListener on your JPanel.

yourpPanel.addMouseListener( new MouseAdapter() {
   @Override
   public void mousePressed( MouseEvent evnt ){
      // Your code when clicked here
   }
});</code>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!