我需要在图片的边界内创建一个可点击的图像。然后我需要图片在文件夹中的那些之间切换

时间:2016-01-15 04:01:15

标签: java swing jpanel

我一直在努力解决这个问题,我可以通过一般的主动监听器来切换图片,但是无法选择可点击区域的区域以允许切换。我希望创建一个带有边界的矩形,这将允许我有一个可点击区域来更改图片。我试图这样做但不确定如何设置一个动作监听器在jpanel的特定区域工作。任何帮助将不胜感激,谢谢!

public class drawPictures {
Random random = new Random();
int one = random.nextInt(1200)+1;
int two = random.nextInt(600)+1;

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

public drawPictures() {
    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("/Di/rec/tory").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) {

        Rectangle bounds = new Rectangle(one, two, 100, 100);
        if (bounds.contains((e).getPoint())){
          // Image was clicked...
          currentIndex++;
          if (currentIndex >= fileList.length) {
              currentIndex = 0;
          }
          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)+140, image.getHeight(this)+200);
    }
    @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 -500 + one;
            int y = (height - image.getHeight(this)) / 2- 300 + two;
            g.drawImage(image, x, y, this);


        }
    }
}

}

1 个答案:

答案 0 :(得分:2)

让我们从显而易见的事情开始......

你从未真正将ImagePane添加到任何内容中(首先,您尝试在点击后添加它,但如果它没有被添加到任何内容,它会如何被点击?)

//...
public ImageViewPane() {
    //...
    imagePane = new ImagePane();
    imagePane.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            //...
        }
    });

    // And... nothing
}

你的MouseListener中有很多事情真的不需要在那里......

imagePane.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {

        Rectangle bounds = new Rectangle(one, two, 100, 100);
        if (bounds.contains((e).getPoint())) {
            // Image was clicked...
            currentIndex++;
            if (currentIndex >= fileList.length) {
                currentIndex = 0;
            }
            nextImage();
        }

        setLayout(new GridBagLayout());
        add(imagePane);

        nextImage();
    }
});

您的来电nextImage至少一次,如果不是两次。一旦用户在您的可访问框内单击一次,并在方法结束时单击一次。尽管currentIndex无论如何都会这样做,但您也在递增nextImage值。您似乎也尝试将imagePane添加到容器中......再次...

这可以简化为......

imagePane.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        Rectangle bounds = new Rectangle(one, two, 100, 100);
        if (bounds.contains((e).getPoint())) {
            // Image was clicked...
            nextImage();
        }
    }
});

接下来,您的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();
    }
}

好的,这实际上并不坏,通过过滤掉那些你知道不是文件的文件,可以简化阅读图像的“绒毛”

fileList = new File("/a/directory/somewhere").listFiles(new FileFilter() {
    @Override
    public boolean accept(File pathname) {
        return pathname.isFile()
                && (pathname.getName().toLowerCase().endsWith(".jpg")
                || pathname.getName().toLowerCase().endsWith(".bmp")
                || pathname.getName().toLowerCase().endsWith(".png")
                || pathname.getName().toLowerCase().endsWith(".gif"));
    }
});

让我们假装我们生活在一个扩展实际意义上的世界。你可以尝试在这里阅读图像,如果它不是图像,则丢弃它,但这是非常耗费时间......

这样可以让nextImage更像......

public void nextImage() {
    if (fileList != null && fileList.length > 0) {
        currentIndex++;
        if (currentIndex < 0 || currentIndex >= fileList.length) {
            currentIndex = 0;
        }
        try {
            Image image = ImageIO.read(fileList[currentIndex]);
            imagePane.setImage(image);
            invalidate();
            repaint();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

现在,就个人而言,我File中的ListFile每次Image无法生成List,我会将其从@Override public Dimension getPreferredSize() { return new Dimension(1200, 600); } ,但那就是我

最后添加,您还应该添加...

ImageViewPane

到你的int x = (width - image.getWidth(this)) / 2 - 500 + one; int y = (height - image.getHeight(this)) / 2 - 300 + two; 课程,这将允许你打包它周围的框架(我在测试过程中不断丢失我的“魔术”方块,因为窗口很小)

我不完全确定这是做什么......

int x = one + ((100 - image.getWidth(this)) / 2);
int y = two + ((100 - image.getHeight(this)) / 2);

但是,像是......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DrawPictures {

    Random random = new Random();
    int one = random.nextInt(1200) + 1;
    int two = random.nextInt(600) + 1;

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

    public DrawPictures() {
        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("...").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.isFile()
                            && (pathname.getName().toLowerCase().endsWith(".jpg")
                            || pathname.getName().toLowerCase().endsWith(".bmp")
                            || pathname.getName().toLowerCase().endsWith(".png")
                            || pathname.getName().toLowerCase().endsWith(".gif"));
                }
            });

            imagePane = new ImagePane() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(Color.BLACK);
                    g.drawRect(one, two, 100, 100);
                }

            };
            imagePane.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    Rectangle bounds = new Rectangle(one, two, 100, 100);
                    if (bounds.contains((e).getPoint())) {
                        // Image was clicked...
                        nextImage();
                    }
                }
            });
            setLayout(new BorderLayout());
            add(imagePane);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(1200, 600);
        }

        public void nextImage() {
            if (fileList != null && fileList.length > 0) {
                currentIndex++;
                if (currentIndex < 0 || currentIndex >= fileList.length) {
                    currentIndex = 0;
                }
                try {
                    Image image = ImageIO.read(fileList[currentIndex]);
                    imagePane.setImage(image);
                    invalidate();
                    repaint();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    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) + 140, image.getHeight(this) + 200);
        }

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

            }
        }
    }
}

将允许您将图像置于“魔术”方块中心......

最后,因为一堆不符合上下文的代码很难恢复到位......

<!DOCTYPE html>
  <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Audio Tag</title>
    </head>
    <body>
        <!--Before HTML5, Developer can add audio tag by Plug-in like  FLASH. But HTML5 introduces an audio tag for embedded an audio media in a web page**strong text**-->

       <audio controls="controls">
          <source src="Allegro%20from%20Duet%20in%20C%20Major.mp3" type="audio/mp3">

        </audio>
    </body>
  </html>