前言
因为大作业要做浏览器,浏览器要带下载器,所以现在先实现一个带界面的多线程下载器类。
多线程下载器原理
之前写过一个的【Java URLConnection类 实现多线程下载文件】,只是那个demo比较简陋。。。
今天我们来加上图形界面,其实下载部分的代码都是复用过来的。。。。
JFrame
主窗体,windows窗口,可缩放等等
JTextField
文字框输入,我们需要用户输入或者改变
- 下载的url
- 保存地址
- 文件名
可以通过.set / get Text
方法设置或者取得里面的文字
JButton
按钮组件,我们点击后,开始创建下载线程并且开始下载。
可以简单的为一个JButton对象绑定被点击时候的事件
// 开始下载按钮 注册事件 点击的时候创建新下载线程JButton startBtn = new JButton("开始下载");startBtn.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 按钮按下的时候执行此处代码}});
JLabel
一个文字显示的组件,可以支持显示html格式,我们用于显示一些提示信息
JProgressBar
这次的重点,进度条组件,使用方便,在构造函数的时候,指定最小值,最大值
JProgressBar bar = new JProgressBar(0, 100);
然后可以通过.setValue来改变当前进度条的值
布局
JFrame使用【网格布局】,通过以下代码就可以实现一个9行1列
的网格
// 主窗体JFrame jf = new JFrame("下载器");jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);jf.setSize(512, 321);jf.setLayout(new GridLayout(9, 1));
实现
因为进度条需要调用组件,所以我们创建一个类叫MultiThreadDownloader
,将所有组件都设置为成员变量
此外我们还要存一个下载进程,方便我们查看下载进度并且更新进度条,因为所有下载进程共享一个进度,我们保留其中一个下载进程,就可以轻松获取了。
public class MultiThreadDownloader {String url; // 目标urlString savePath;// 本地保存路径String fileName;// 文件名int tnum = 5; // 默认线程数目long totalLength; // 总大小DownloadThread dth; // 一个下载线程,用于查看下载进度JLabelurlInputText; // 文字:目标对象urlJTextField urlInput;// url输入框JLabelpathInputText;// 文字:本地保存路径JTextField pathInput; // 保存路径输入框JLabelnameInputText;// 文字:文件名JTextField nameInput; // 文件名输入框JLabelbarTex; // 文字:进度条JProgressBar bar; // 进度条JButton startBtn; // 开始下载按钮ExecutorService pool = Executors.newCachedThreadPool(); // 线程池MultiThreadDownloader() {}MultiThreadDownloader(String url, String savePath, String fileName, int tnum) {this.url = url;this.tnum = tnum;this.savePath = savePath;this.fileName = fileName;}...下面是类的其他方法实现}
我们编写一个download方法,该方法初始化我们的界面并且显示,除此之外,还为按钮注册按下事件, 事件内容里面执行的代码就是创建下载线程并且开始下载。
public void download() throws Exception {// 初始化组件,利用默认内容// url输入urlInputText = new JLabel ("目标对象URL");urlInput = new JTextField(url);// 路径输入pathInputText = new JLabel ("本地保存路径");pathInput = new JTextField(savePath);// 文件名输入nameInputText = new JLabel ("文件名");nameInput = new JTextField(fileName);// 进度条JLabelbarText = new JLabel ("进度条");bar = new JProgressBar(0, 100);// 开始下载按钮 注册事件 点击的时候创建新下载线程startBtn = new JButton("开始下载");startBtn.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {startBtn.setEnabled(false); // 按钮禁用// 获得用户实际输入的内容savePath = pathInput.getText();fileName = nameInput.getText();url = urlInput.getText();try {totalLength = new URL(url).openConnection().getContentLength();bar.setMaximum((int)totalLength);long eachLength = totalLength / tnum;// 拓展名String ext = url.substring(url.lastIndexOf("."));// 创建下载线程for(int i=0; i= totalLength) {startBtn.setText("下载完成");break;}try {this.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}});// 关闭线程池pool.shutdown();} catch(Exception e1) {e1.printStackTrace();}}});// 开始下载按钮 注册事件 -- 结束// 主窗体JFrame jf = new JFrame("下载器");jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);jf.setSize(512, 321);jf.setLayout(new GridLayout(9, 1));jf.add(urlInputText);jf.add(urlInput);jf.add(pathInputText);jf.add(pathInput);jf.add(nameInputText);jf.add(nameInput);jf.add(barText);jf.add(bar);jf.add(startBtn);jf.show();}
main函数只需创建相应的下载器,调用download方法即可。
这里我在我的个人网址上提供了两个链接用于测试下载,分别是稍大的pdf文件和小型txt文件。
温馨提示
温馨提示
public static void main(String[] args) throws Exception {MultiThreadDownloader dl = new MultiThreadDownloader("http://www.szulrl.cn/browserTest/PDFFILE.zip", "E:/MyEclipse/WorkSpace/Hello/src/homework/", "下载",3);dl.download();}
完整代码
/* * @Author : @李若龙 2018171028 @SZU @CSSE */import java.net.*;import java.util.*;import java.util.concurrent.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.*;import javax.swing.*;import javax.swing.event.*;import javax.swing.text.html.*;class DownloadThread extends Thread {URLConnection con;RandomAccessFile rf;public static volatile long allcur = 0;public static boolean isReady = false;public DownloadThread() {}public DownloadThread(URLConnection con, RandomAccessFile rf) {this.con = con;this.rf = rf;}public void run() {try {// 获取输入输出流InputStream is = con.getInputStream();//System.out.printf("线程 获取文件成功\n");// 输入流内容写入输出流byte[] buf = new byte[1024];int len = -1;while((len=is.read(buf)) != -1) {rf.write(buf, 0, len);synchronized(new Object()) {allcur += (long)len;}// System.out.printf("%d / %d \n", allcur, 29210163);}rf.close();} catch(Exception e) {e.printStackTrace();}}}public class MultiThreadDownloader {String url; // 目标urlString savePath;// 本地保存路径String fileName;// 文件名int tnum = 5; // 默认线程数目long totalLength; // 总大小DownloadThread dth; // 一个下载线程,用于查看下载进度JLabelurlInputText; // 文字:目标对象urlJTextField urlInput;// url输入框JLabelpathInputText;// 文字:本地保存路径JTextField pathInput; // 保存路径输入框JLabelnameInputText;// 文字:文件名JTextField nameInput; // 文件名输入框JLabelbarTex; // 文字:进度条JProgressBar bar; // 进度条JButton startBtn; // 开始下载按钮ExecutorService pool = Executors.newCachedThreadPool(); // 线程池MultiThreadDownloader() {}MultiThreadDownloader(String url, String savePath, String fileName, int tnum) {this.url = url;this.tnum = tnum;this.savePath = savePath;this.fileName = fileName;}public void download() throws Exception {// 初始化组件,利用默认内容// url输入urlInputText = new JLabel ("目标对象URL");urlInput = new JTextField(url);// 路径输入pathInputText = new JLabel ("本地保存路径");pathInput = new JTextField(savePath);// 文件名输入nameInputText = new JLabel ("文件名");nameInput = new JTextField(fileName);// 进度条JLabelbarText = new JLabel ("进度条");bar = new JProgressBar(0, 100);// 开始下载按钮 注册事件 点击的时候创建新下载线程startBtn = new JButton("开始下载");startBtn.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {startBtn.setEnabled(false); // 按钮禁用// 获得用户实际输入的内容savePath = pathInput.getText();fileName = nameInput.getText();url = urlInput.getText();try {totalLength = new URL(url).openConnection().getContentLength();bar.setMaximum((int)totalLength);long eachLength = totalLength / tnum;// 拓展名String ext = url.substring(url.lastIndexOf("."));// 创建下载线程for(int i=0; i= totalLength) {startBtn.setText("下载完成");break;}try {this.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}});// 关闭线程池pool.shutdown();} catch(Exception e1) {e1.printStackTrace();}}});// 开始下载按钮 注册事件 点击的时候创建新下载线程 -- 结束// 主窗体JFrame jf = new JFrame("下载器");jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);jf.setSize(512, 321);jf.setLayout(new GridLayout(9, 1));jf.add(urlInputText);jf.add(urlInput);jf.add(pathInputText);jf.add(pathInput);jf.add(nameInputText);jf.add(nameInput);jf.add(barText);jf.add(bar);jf.add(startBtn);jf.show();}public static void main(String[] args) throws Exception {MultiThreadDownloader dl = new MultiThreadDownloader("http://www.szulrl.cn/browserTest/PDFFILE.zip", "E:/MyEclipse/WorkSpace/Hello/src/homework/", "下载",3);dl.download();}}