Java Swing 多线程加载图片(保证顺序一致)
2017-12-15 10:26
801 查看
大二的时候做的课程设计,图片管理器,当时遇到图片很多的文件夹,加载顺序非常慢。虽然尝试用多个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(); } }
运行结果
在我的电脑上,加载92张图片并渲染到界面上,总共花了1568毫秒。大家可以找一个图片很多的文件夹,尝试加载大量图片的情况。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- 情人节写给女朋友Java Swing代码程序
- Java Swing组件实现进度监视功能示例
- Java编程使用卡片布局管理器示例【基于swing组件】
- Java编程使用箱式布局管理器示例【基于swing组件】
- 基于java swing实现答题系统
- Java实现的可选择及拖拽图片的面板功能【基于swing组件】
- Java编程swing组件JLabel详解以及使用示例
- java实现的计算器功能示例【基于swing组件】
- Java Swing实现简单的体重指数(BMI)计算器功能示例
- Java swing实现的计算器功能完整实例
- java swing实现的扫雷游戏及改进版完整示例
- Java swing框架实现的贪吃蛇游戏完整示例
- Java编程实现swing圆形按钮实例代码
- java中Swing会奔跑的线程侠
相关文章推荐
- Java Swing 多线程加载图片(保证顺序一致)
- 利用图片onload、onerror实现ie fox 的多线程,并保证顺序
- 网络图片异步加载(用到多线程(线程池),java回调机制,图片缓存,图片的动画)
- Java swing 加载和显示图片 利用Image与BufferedImage
- Java HasSet 不保证数据放入后再取出时顺序是一致的
- Java 多线程 (PART VII) 使用join()方法保证线程的执行顺序
- JAVA Swing复习(4)案例:自制一个验证码并把图片加载到窗口中
- java项目中依赖的jar包中含有相同类时的加载顺序(按照)
- selenim java判断图片有没有加载完成
- 【玩转cocos2d-x之二十三】多线程和同步03-图片异步加载
- 数组去重复元素-(不保证与原有数据顺序一致)
- ViewPager + Volley 异步多线程图片加载实现Banner效果
- Java与Flex学习笔记(10)----Flex中加载gif图片
- 正在加载中 图片大全,【绝对是你做软件急需的,多线程,文件处理,下载】
- 使用GCD处理非UI相关的异步任务 Object-C异步多线程加载网络图片
- 网络图片的异步加载器,多线程队列,带文件和内存缓存
- JAVA GUI 开发---界面加载背景图片
- Android图片加载神器之Fresco-更灵活的设置加载特效[Java代码实现XML效果]
- Java中类的加载顺序剖析(常用于面试题)
- 转----java复习一 ——java web项目启动加载顺序