我想在Java中的图像上创建一个不可见的可点击对象

所以我用Java创建了一个游戏,用户点击的图像与其他图像不同。 我已经获得了创建关卡的图像,但我只是想让它如果用户点击图像上的特定位置,游戏将会继续进行下一个图像。 (所有图像都已放置在一个数组中。)设置游戏,使其打开第一张图像。 这是我的代码:

package Final; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.*; import javax.swing.JFrame; public class drawPictures extends JFrame implements MouseListener { //it implements this because I want the user to click stuff //Now I need to declare the images that serve as my levels variables ahead of time. protected static Image levelOne; protected static Image levelTwo; protected static Image levelThree; protected static Image levelFour; protected static Image levelFive; protected Graphics g = this.getGraphics(); //Done declaring. //Now to load the images private static Image loadImage(String imgFileName) { Image img = null; try { Toolkit tk = Toolkit.getDefaultToolkit(); img = tk.getImage(imgFileName); } catch (Exception e) { System.err.println("Image not found: "+ imgFileName); } return img; } //done loading the images static Image [] pictureArray = new Image[5]; { //This is the array that will store all of the images //otherwise known as the "levels" pictureArray[0] = levelOne; //each "slot" in the array is taken up by one //of the images that serves as the level pictureArray[1] = levelTwo; pictureArray[2] = levelThree; pictureArray[3] = levelFour; pictureArray[4] = levelFive; } /* * Now that the actual array that stores the levels has been created * I need to create a method that "paints" the level, * and moves on to the next one when the user clicks on something. * * I also need to create a box with dimensions 151x159 * overtop of the happy tomato in the first level. * That will be the */ public drawPictures() { super("One of These Things Doesn't Belong..."); setSize(1500, 750); setDefaultCloseOperation(EXIT_ON_CLOSE); // Creates the "x" box. setVisible(true); // Makes the window visible. start(); } public void paint(Graphics g) { g.drawImage(pictureArray[0], 100, 100, this); } public static void start() /* * this entire method exists for the sole purpose of loading the images * that I placed in the variables that I declared above. * WHY IS PROGRAMMING SO DARN TEDIOUS??? */ { levelOne = loadImage("Level 1.jpg"); levelTwo = loadImage("Level 2.jpg"); levelThree = loadImage("Level 3.jpg"); levelFour = loadImage("Level 4.jpg"); levelFive = loadImage("Level 5.jpg"); } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub start(); new drawPictures(); } } 

您永远不会向框架添加鼠标侦听器。

话说回来…

  • 您应该避免从顶级容器扩展,例如JFrame
  • 你应该避免在顶层容器上涂漆(通过覆盖任何paint方法)
  • 你应该总是调用super.paintXxx (除非你有一个非常好的理由去做),因为绘画方法相当复杂并且执行了很多非常重要的工作
  • 除非您正在加载大型图像或从Internet下载图像(即使这样),否则您应该使用ImageIO 。 它支持更多的图像。

在鼠标单击事件中,您需要确定开始显示的当前图像。 您需要确定边界并确定是否单击了鼠标。

 // 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(); } 

用例子更新

这是一个粗略的例子。 基本上它使用绘制图像的自定义JPanel 。 为此,我添加了一个MouseListener

主程序使用文件夹并滚动浏览,在单击时在图像面板上显示每个(有效)图像。

鼠标单击只会出现在图像面板本身的上下文中。

 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 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); } } } } 

为什么要在图像上方放置一个不可见的物体?

无论如何,要回答您的问题,请创建一个与您的图像一样的JPanel。

JPanel yourPanel = new JPanel()设置它的位置与图像相同。
在JPanel上创建一个MouseListener。

  yourpPanel.addMouseListener(new MouseAdapter(){
    @覆盖
    public void mousePressed(MouseEvent evnt){
       //点击此处时的代码
    }
 });