这篇文章主要知识点是关于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毫秒。大家可以找一个图片很多的文件夹,尝试加载大量图片的情况。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。
以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。
完美图解物联网IoT实操:ESP8266 Arduino,Cordova物联网移动App,JavaScript微控制器编程 PDF 影印完整版电子书
分类:物联网 作者:赵英杰大小:60.8 MB
Copyright 2018-2020 www.xz577.com 码农之家
版权投诉 / 书籍推广 / 赞助:520161757@qq.com
Java Swing组件复选框JCheckBox用法示例
本文实例讲述了Java Swing组件复选框JCheckBox用法。分享给大家供大家参考,具体如下: JCheckBox是Swing中的复选框。所谓复选框就是指,可以同时存在多个这样的控件,它们可以有多个处于被选中状态。对于每一个复选框而言,它只有选中和未选中两种状态。 JCheckBox的常用方法 如下图所示: 可以为它添加ActionListener对象来响应事件。 使用demo如下: JCheckBoxDemo.java package awtDemo;import java.awt.BorderLayout;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JCheckBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;/* * source code from 《java核心技术 卷1 基础知识》 P326 */@SuppressWarnings("serial")public class JCheckBoxDemo extends JFrame{ int DEFAULT_WIDTH = 600; int DEFAULT_HEIGHT = 400; private JLabel label; private JCheckBox boldCheckbox; private JCheckBox italicCheckbox;……
Java Swing组件单选框JRadioButton用法示例
本文实例讲述了Java Swing组件单选框JRadioButton用法。分享给大家供大家参考,具体如下: JRadioButton是Swing中的单选框。所谓单选框是指,在同一个组内虽然有多个单选框存在,然而同一时刻只能有一个单选框处于选中状态。它就像收音机的按钮,按下一个时此前被按下的会自动弹起,故因此得名。因此,在添加JRadioButton控件时,要记得将它们添加到同一个ButtonGroup中。 JRadioButton的常用方法如下图所示: 可以为它添加ActionListener对象来响应事件。这里有一个问题,当多个JRadioButton共用一个事件监听器时,如何获取产生事件的按钮? 有4种方法: 1.遍历这些按钮并检查是否选中,这种方法比较笨重。 2.使用事件的 getActionCommand() 方法,这需要事先为每个控件设置 ActionCommand 。 3.使用事件的 getSource ,并转化为控件对象。 4.使用 ButtonGroup 的 getSelection 方法,它……
Java-JFrame-swing嵌套浏览器的具体步骤
一、使用swing嵌套浏览器要实现的功能: 通过java的swing实现在一个窗体中嵌套一个浏览器,可以在这个浏览器中将另一个项目的内容显示出来,只需要回去另一个项目首页的url即可,这样另一个项目就可以在swing嵌套的浏览器中进行正常的显示了; 二、下面的浏览器工具类中的方法在使用的时候,只需要从另一个项目的服务端获取另一个项目的首页stirng类型的url地址和浏览器左上角要显示的string类型的标题两个参数即可,参数只有url和title两个; (1)主要步骤: 1、通过以下java代码实现创建浏览器; 2、创建JFrame窗体,对窗体进行基本的设置; 3、设置浏览器显示的定位尺寸,并将浏览器添加到JFrame窗体中去: 非常注意:将浏览器添加到窗体的java代码一定在将浏览器顶部工具栏背景图片添加到窗体的java代码之后,否则浏览器内容显示不出来; 4、设……
Java Swing仿QQ登录界面效果
本文实例为大家分享了Java Swing仿QQ登录界面展示的具体代码,供大家参考,具体内容如下 闲来无事将早些时候已实现的QQ登录界面再实现了一遍,纯手工打造(意思是没有用NetBeans、MyEclipse的拖动功能)。 源代码如下: package ibees.qq; import java.awt.BorderLayout; import java.net.URL; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; /** * 仿QQ登录界面,仅供学习参考,涉及到的有窗口居中、JPanel、LayoutManager的使用 * @author hhzxj2008 * */ public class QQLoginView extends JFrame { /** * */ private static final long serialVersionUID = -5665975170821790753L; public QQLoginView() { initComponent(); } private void initComponent() { setTitle("用户登录"); //设置LOGO URL image = ……