大二的时候做的课程设计,图片管理器,当时遇到图片很多的文件夹,加载顺序非常慢。虽然尝试用多个thread加载图片,却无法保证图片按顺序加载。直到今天学会了使用callable接口和future接口,于是心血来潮实现了这个功能。
废话不多说,看代码。
多线程加载图片(核心):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
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界面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
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毫秒。大家可以找一个图片很多的文件夹,尝试加载大量图片的情况。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/qq_21508059/article/details/78743696