Java Swing 多线程加载图片(保证顺序一致)
来源:互联网 发布:周振兴 mysql 编辑:程序博客网 时间:2024/05/18 00:39
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(); }}
运行结果
在我的电脑上,加载92张图片并渲染到界面上,总共花了1568毫秒。大家可以找一个图片很多的文件夹,尝试加载大量图片的情况。
阅读全文
0 0
- Java Swing 多线程加载图片(保证顺序一致)
- Java HasSet 不保证数据放入后再取出时顺序是一致的
- swing的加载顺序
- 数组去重复元素-(不保证与原有数据顺序一致)
- Java 多线程 (PART VII) 使用join()方法保证线程的执行顺序
- 利用图片onload、onerror实现ie fox 的多线程,并保证顺序
- Java swing 加载和显示图片 利用Image与BufferedImage
- SWING 组件加载图片方法
- JAVA多线程超时加载当网页图片
- java swing 图片处理
- Swing代码分析(实践场景-加载图片)
- java Swing保持与操作系统原生UI一致的感官
- 多线程-图片顺序出现
- android 图片加载顺序
- 加载图片以及多线程
- 加载图片以及多线程
- 加载图片以及多线程
- MBProgressHUD多线程加载图片
- 项目启动连接不上MySql
- 号码提取
- IE下getTime()返回NaN
- 利用sourceTree管理gitlab[纯操作]
- ELDD读书笔记:第五章 字符设备驱动程序
- Java Swing 多线程加载图片(保证顺序一致)
- centos7安装oracle12c 三
- Android ANR产生的原因和分析
- git update-index —assume-unchange path
- 正则表达式
- ABAP计算间隔月份
- win7(iis7)无法加载运行CSS和图片的解决方法
- 第十八讲 二叉树、JDK8函数式接口、File类、输入流与输出流、字节流与字符流、文件复制的实现
- jq与js中的事件机制与阻止