Java Swing 多线程加载图片实例详解
- 更新时间:2020-03-08 21:00:00
- 编辑:侯勇捷
大二的时候做的课程设计,图片管理器,当时遇到图片很多的文件夹,加载顺序非常慢。虽然尝试用多个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毫秒。大家可以找一个图片很多的文件夹,尝试加载大量图片的情况。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。
相关教程
-
js经验分享 JavaScript反调试技巧
在这篇文章中,我打算跟大家总结一下关于JavaScript反调试技巧方面的内容。值得一提的是,其中有些方法已经被网络犯罪分子广泛应用到恶意软件之中了,需要的朋友可以参考下
发布时间:2019-06-21
-
看Java技术视频入门快吗
java技术已经开始逐渐普及,有些小伙伴在自学java,大部分自学的朋友会选择看视频教程来学习,那么,看Java技术视频入门快吗?这个问题就由码农之家java培训机构的小编来为大家解答。
发布时间:2021-06-06
-
Java攻略 Java常见问题的简单解法
这书以案例方式撰写,包含Java8和Java9的新特点,并得出了70多个能够 用以具体开发设计的实例,致力于让用户把握怎样运用这种新特点来处理开发设计中碰到的各种各样难题。这书致力于让用
大小:7 MBJava电子书
-
Java开发实例大全(提高卷)
汇集了Java开发从基础知识到高级应用各个层面的大量实例及源代码,45个方向,1201个实例案例,java编程类四库全书,供学习、速查、实践练习的超全参考手册,是《java开发实战1200例》之全新升级
大小:162.8 MBJava编程电子书
-
精通JavaScript
精通JavaScript(第2版) 是iQuery之父的经典之作,是深入学习JavaScript技术的绝佳教材,涵盖了可重用代码、文档对象模型、Ajax、Web生产工具、AngularJS等内容。作者讲解了JavaScript的发展现状、实用技
大小:33.5 MBJavaScript电子书
-
大型JavaScript应用最佳实践指南
大小:35 MBJavaScript电子书
-
Java常用算法手册(第3版)
Java常用算法手册是程序设计的基础和灵魂,编程水平高低的集中体现。历经三次改版,销量达万册;完整源代码和配套视频与图书内容相辅相成。
大小:171.5 MBJava算法手册电子书
-
JavaScript启示录
《JavaScript启示录》无关于JavaScript设计模式,也无关于JavaScript面向对象代码实现。《JavaScript启示录》意图通过考察原生JavaScript对象和不同环境对原生对象的支持和细微差别。
大小:24.4 MBJS电子书
-
完美图解物联网IoT实操:ESP8266 Arduino,Cordova物联网移动App,JavaScript微控制器编程
完美图解物联网技术系列》图书是当前物联网开发技术应用的集大成者。本书内容以Arduino和JavaScript为主线,开发物联网应用、手机App和操控微电脑
大小:60.8 MB物联网电子书