当前位置:主页 > java教程 > Java Swing 多线程加载图片(保证顺序一致)

Java Swing 多线程加载图片实例详解

发布:2020-03-08 21:00:00 50


本站收集了一篇Java相关的编程文章,网友敖茂才根据主题投稿了本篇教程内容,涉及到Java、Swing、多线程加载图片、Java Swing 多线程加载图片(保证顺序一致)相关内容,已被409网友关注,相关难点技巧可以阅读下方的电子资料。

Java Swing 多线程加载图片(保证顺序一致)

大二的时候做的课程设计,图片管理器,当时遇到图片很多的文件夹,加载顺序非常慢。虽然尝试用多个Thread加载图片,却无法保证图片按顺序加载。直到今天学会了使用Callable接口和Future接口,于是心血来潮实现了这个功能。

废话不多说,看代码。

多线程加载图片(核心):

package com.lin.imagemgr;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import net.coobird.thumbnailator.Thumbnails;

public class ImageMgr {
 private static ImageMgr instance = new ImageMgr();
 private ImageMgr() {}
 public static ImageMgr getInstance() {
  return instance;
 }

 //线程池
 private ExecutorService executor = Executors.newFixedThreadPool(8);

 public List<JLabel> loadImages(String path) {
  List<JLabel> images = new ArrayList<>();
  File file = new File(path);
  if (!file.isDirectory()) {
   throw new RuntimeException("need directory!");
  }
  File[] files = file.listFiles(new FilenameFilter() {

   @Override
   public boolean accept(File dir, String name) {
    //thumbnail只支持jpg??
    if (name.endsWith(".jpg")) {
     return true;
    }
    return false;
   }
  });

  //并发加载图片,并使用Future保存加载结果
  List<Future<MyLabel>> futures = new ArrayList<>();
  for (final File f : files) {
   Future<MyLabel> future = executor.submit(() -> {
    return new MyLabel(f.getName(), f.getAbsolutePath());
   });
   futures.add(future);
  }

  //等待所有并发加载返回结果
  try {
   for (Future<MyLabel> future : futures) {
    MyLabel icon = future.get();
    images.add(icon);
   }
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (ExecutionException e) {
   e.printStackTrace();
  }

  //Java8使用stream API 进行排序
  List<JLabel> sortedList = images.stream().sorted().collect(Collectors.toList());

  return sortedList;
 }

 //继承JLabel并实现Comparable接口,从而对JLabel进行排序
 private static class MyLabel extends JLabel implements Comparable<MyLabel>{
  private static final long serialVersionUID = 1L;
  private String fileName;

  public MyLabel(String fileName, String fullPath) {
   this.fileName = fileName;
   //使用thumbnailator生成缩略图
   try {
    BufferedImage bufferedImage = Thumbnails.of(fullPath) 
    .size(100, 120)
    .asBufferedImage();
    setIcon(new ImageIcon(bufferedImage));
    setPreferredSize(new Dimension(100, 120));
   } catch (IOException e) {
    e.printStackTrace();
   }
  }

  @Override
  public int compareTo(MyLabel o) {
   int result = this.fileName.compareTo(o.fileName);
   return result;
  }


 }

}

Swing界面:

 

package com.lin.imagemgr;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class MainFrame extends JFrame{
 private static final long serialVersionUID = 1L;
 private JTextField pathField;
 private JButton showBtn;
 private JPanel contentPanel;

 public void init() {
  JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
  topPanel.setPreferredSize(new Dimension(800, 40));
  pathField = new JTextField(50);
  showBtn = new JButton("显示图片");
  topPanel.add(pathField);
  topPanel.add(showBtn);
  getContentPane().add(BorderLayout.NORTH, topPanel);
  contentPanel = new JPanel();
  contentPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
  contentPanel.setPreferredSize(new Dimension(750, 1800));
  JScrollPane jsp = new JScrollPane(contentPanel);
  getContentPane().add(BorderLayout.CENTER, jsp);

  showBtn.addActionListener((e) -> {
   try {
    loadImages();
   } catch (Exception ex) {
    ex.printStackTrace();
   }
  });

  setSize(800, 650);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setLocationRelativeTo(null);
  setVisible(true);
 }

 public void loadImages() {
  contentPanel.removeAll();
  String path = pathField.getText();
  long start = System.currentTimeMillis();
  List<JLabel> images = ImageMgr.getInstance().loadImages(path);
  for (JLabel label :images) {
   contentPanel.add(label);
  }
  contentPanel.updateUI();
  long end = System.currentTimeMillis();
  System.out.println("加载需要" + (end - start) + "毫秒!");

 }

 public static void main(String[] args) {
  new MainFrame().init();
 }

}

运行结果

Java Swing 多线程加载图片(保证顺序一致)

Java Swing 多线程加载图片(保证顺序一致)

在我的电脑上,加载92张图片并渲染到界面上,总共花了1568毫秒。大家可以找一个图片很多的文件夹,尝试加载大量图片的情况。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。


参考资料

相关文章

  • Java应用层协议WebSocket实现消息推送

    发布:2023-03-28

    后端向前端推送消息就需要长连接,首先想到的就是websocket,下面这篇文章主要给大家介绍了关于java后端+前端使用WebSocket实现消息推送的详细流程,需要的朋友可以参考下


  • 如何由java转学python

    发布:2019-09-17

    相对来讲,学习过Java的同学,想转到python,还是比较容易的。转其他语言的时候,要明确自己的目标,并且朝这个方向去学习专业的开发技能,同时结合合理的学习方法,很快就会转过去的。


  • Java Set接口及常用实现类总结

    发布:2023-03-02

    Collection的另一个子接口就是Set,他并没有我们List常用,并且自身也没有一些额外的方法,全是继承自Collection中的,因此我们还是简单总结一下,包括他的常用实现类HashSet、LinkedHashSet、TreeSet的总结


  • java实现后台图片跨域上传功能的实例讲解

    发布:2020-04-17

    这篇文章主要给大家介绍了关于java实现后台图片跨域上传功能的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习


  • java异常与处理机制分析

    发布:2019-08-11

    这篇文章主要介绍了java的异常与处理机制,结合实例形式分析了Java异常与处理机制的概念、原理、相关操作技巧与注意事项,并附带面试题分析供大家参考,需要的朋友可以参考下


  • JAVA中通过自定义注解进行数据验证的方法

    发布:2022-09-23

    给大家整理一篇关于JAVA的教程,java 自定义注解验证可自己添加所需要的注解,下面这篇文章主要给大家介绍了关于JAVA中通过自定义注解进行数据验证的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴


  • Java关于参数传递问题

    发布:2020-03-27

    这篇文章主要介绍了Java中的参数传递问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧


  • java垃圾回收机制原理知识点详解

    发布:2019-06-06

    这篇文章主要为大家详细介绍了Java垃圾回收机制的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下


网友讨论