我想在Java中的图像上创建一个不可见的可点击对象 [英] I want to create an invisible clickable object over an image in Java

查看:123
本文介绍了我想在Java中的图像上创建一个不可见的可点击对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在Java中创建一个游戏,用户点击一个不同于其他图片的游戏。我已经得到了创建的级别的图像,但我只是想使它,如果用户点击图像上的特定点,游戏会反应,移动到下一个图像。 (所有的图像都已经放置在一个数组中了。)游戏已经设置好,以便第一个图像已经打开。这是我的代码:

So I'm creating a game in Java in which the user clicks on an image that's different from the rest. I've already got the images for the level created, but I just want to make it so that if the user clicks on a specific spot on the image, the game will react in moving on to the next image. (All of the images are placed in an array already.) The game is set up so that it opens with the first image already. Here's my code:

    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

  • 除非你要加载大图片或从互联网上下载图片,否则不会出现这种情况。 (即使是),您应该使用 ImageIO 。它支持更多的图片。

  • 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

这是一个粗略的例子,基本上使用自定义 JPanel 。这个我添加一个 MouseListener

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

主程序使用

鼠标点击只会在图像面板本身的上下文中进行。

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

这篇关于我想在Java中的图像上创建一个不可见的可点击对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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