Java图片显示与浏览文件夹中图片

0.前言

Java那本书基础篇看完了,写一个小东西作为结书练习。在这个案例中,会展示选择文件夹,递归地获得文件夹中图片,使用监听器响应键盘事件,改变图片大小并重新绘制画布。同时会把接口和类设计的一些知识点也涉及。

如果有空的话会把读入文件从而减少加载时间的那部分也写上(就和之前python的一样)。不过博主我啊是真的要阳了,所以估计不行啦。

图片浏览器键盘左键上一张,右键下一张,上键随机一张。

1.获取文件夹和文件夹中图片

Java提供了便利的文件读取类JFileChooser,我们设置它的获取模式为文件夹,再递归地获得文件夹中图片——事实上似乎有这么一个函数已经提供给我们了,但是我的java版本似乎不支持。

import javax.swing.*;
import java.io.File;
import java.util.Vector;

public class MyFileGetter {
    public static void getAllFileNames(File file, Vector<String> fileNames) {
        //获得所有文件名,是不是和listdir一模一样
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                getAllFileNames(f, fileNames);
            }
            else {
                String path = f.getAbsolutePath();
                //是图片的话
                if(path.contains("jpg")||path.contains("png"))
                    fileNames.add(f.getAbsolutePath());
            }
        }
    }
    public static File getDirectory(){
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        //设置好打开所在文件夹
        fileChooser.setCurrentDirectory(new File("D:/素材/P站图片"));
        if(fileChooser.showOpenDialog(null)==JFileChooser.APPROVE_OPTION)
        {
            File file = fileChooser.getSelectedFile();
            return file;
        }
        else{
            System.out.println("No return");
            return new File("D:/素材/P站图片/P站图片2021年/P站图片2021九月/P站图片20210906");
            //为方便起见不抛出错误,返回一个默认的文件夹
        }

    }
}

2.显示图片:ImageShower类

我们继承Jpannel类来显示一张图片,核心函数是drawImage。

这里我们思考一下为什么要把被拉伸初始化设置为true,并且之后我们是怎么绕过这一点让图片保持原来的长宽比的:因为我们无法保证用户之后不对边框拉伸,如果不默认为true,就需要处理敞口拉伸的事件,这不是那么容易做到的。

至于之后我们更改图片以后,只需要简单的frame.setSize即可。

import javax.swing.*;
import java.awt.*;

public class ImageShower extends JPanel {
    private Image image;
    private boolean streched = true;
    private int xCoordinate;
    private int yCoordinate;

    public ImageShower(){};

    public ImageShower(Image image)
    {
        this.image=image;
    }

    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        if(image!=null){
            if(streched)
                g.drawImage(image,xCoordinate,yCoordinate,getWidth(),getHeight(),this);
        }
        else
            g.drawImage(image,xCoordinate,yCoordinate,this);
    }

    public Image getImage()
    {
        return image;
    }

    public void setImage(Image image) {
        this.image = image;
        repaint();
    }

    public boolean isStreched() {
        return streched;
    }

    public void setStreched(boolean streched) {
        this.streched = streched;
        repaint();
    }

    public int getxCoordinate() {
        return xCoordinate;
    }

    public void setxCoordinate(int x)
    {
        xCoordinate=x;
        repaint();
    }
    public int getyCoordinate() {
        return yCoordinate;
    }

    public void setyCoordinate(int y)
    {
        yCoordinate=y;
        repaint();
    }
}

3.TestImageDemo类:主函数入口

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.Random;
import java.util.Vector;

public class TestImageViwer extends JFrame{
    private Image image1;//image对象
    private ImageIcon imageicon1;
    private ImageShower imgShower;//用于显示图片
    public int imgWidth;
    public int imgHeight;
    private double muliple;
    private int currentPos = 0;
    private Random r = new Random();
    private Vector<String> filenames = new Vector<String>(30);
    public TestImageViwer(Vector<String> filenames){
        this.filenames = filenames;
        currentPos = -1;
        setNewImage(1);

        setLayout(new GridLayout(1,2,5,5));
        imgShower = new ImageShower(image1);
        add(imgShower);

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                switch (e.getKeyCode()){
                    //下一张
                    case KeyEvent.VK_RIGHT:
                        setNewImage(1);
                        changeImage();
                        break;
                    //上一张
                    case KeyEvent.VK_LEFT:
                        setNewImage(-1);
                        changeImage();
                        break;
                    //随机一张
                    case KeyEvent.VK_UP:
                        setNewImage(0);
                        changeImage();
                        break;
                }
            }
        });
    }
    private void changeImage(){
        //设置新的图片
        imgShower.setImage(image1);
        //窗口改变大小
        setSize(imgWidth,imgHeight);
    }
    private void setNewImage(int mode)
    {
        if(mode==1)//下一张
            currentPos = (currentPos+1)%filenames.size();
        else if(mode==-1)//上一张
            currentPos = currentPos-1>=0?currentPos-1:filenames.size()-1;
        else if(mode==0)//随机一张
            currentPos = r.nextInt(0,filenames.size());
        String path = filenames.get(currentPos);
        imageicon1 = new ImageIcon(path);
        image1 =  imageicon1.getImage();
        imgWidth = imageicon1.getIconWidth();
        imgHeight = imageicon1.getIconHeight();

        //为了保证长宽不超过屏幕我们提前设置一个合适的尺寸,使图片只能在此大小
        muliple = (double)Math.min(1000.0/imgWidth,800.0/imgHeight);
        imgWidth *= muliple;
        imgHeight *= muliple;

        //设置标题
        int tmp = path.lastIndexOf('\\');
        setTitle(path.substring(tmp+1));
    }

    public static void main(String[] args) throws Exception {
        File director = MyFileGetter.getDirectory();
        Vector<String> filenames = new Vector<String>();
        MyFileGetter.getAllFileNames(director,filenames);

        TestImageViwer frame = new TestImageViwer(filenames);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(frame.imgWidth, frame.imgHeight);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

4.结语

博主家里人已经阳了,现在博主还在苟延残喘,不知道能撑到什么时候,现在博主每天得负责烧饭,打扫消毒,遛狗等家务事,没多少时间学习,等我熬过这波疫情才能愉快地继续学习。大家一定要保重好身体,做好防护。

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值