java swing加载照片_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 loadImages(String path) {

List 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> futures = new ArrayList<>();

for (final File f : files) {

Future future = executor.submit(() -> {

return new MyLabel(f.getName(), f.getAbsolutePath());

});

futures.add(future);

}

//等待所有并发加载返回结果

try {

for (Future future : futures) {

MyLabel icon = future.get();

images.add(icon);

}

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

//Java8使用stream API 进行排序

List sortedList = images.stream().sorted().collect(Collectors.toList());

return sortedList;

}

//继承JLabel并实现Comparable接口,从而对JLabel进行排序

private static class MyLabel extends JLabel implements Comparable{

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 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();

}

}

运行结果

f6af404f5bbc72be338f37d3430fef3b.png

82af289b4e585c3b5f4260d78a1b2094.png

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值