下载Java中的文件/文件。 multithreading,这有效吗?

首先,每个人都需要知道我对Java编码相对较新。 更确切地说,我对面向对象编程完全陌生。


对于这个问题。

我正在尝试创建一个下载类,用于更新它所显示的进度条以显示其进度。 可能还有其他任何我决定将来更新的东西。

目前的问题是,在我看来,这不应该奏效。 我可以在“主”方法上做任何我想做的事情,GUI仍然响应迅速。 根据我过去编程的经验,除非我对GUI进行线程化,否则这是不可能的。 为什么是这样?

既然它有效,这样就可以了吗?


class级主要

package atomicElectronics; import java.io.IOException; import atomicElectronics.physical.AtomFrame; import atomicElectronics.utility.Download; public class Initial { static AtomFrame atomLauncher; public static void main(String[] args) { atomLauncher = new AtomFrame(); atomLauncher.start(); System.out.println(Integer.MAX_VALUE); Download theDownload = new Download(); theDownload.fileProgressBar(atomLauncher.progressBar); try { theDownload.exicute("http://download.videolan.org/pub/videolan/vlc/last/win64/vlc-2.1.3-win64.exe", "C:\\Users\\TrinaryAtom\\AppData\\Roaming"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // TODO Add Download Methods // theDownload.updateBarTotal(JProgressBar); // theDownload.updateLabelSpeed(String); // theDownload.updateLabelTotal(String); // theDownload.addFile(File); // theDownload.addFiles(Files); } } 

类AtomFrame

 package atomicElectronics.physical; import javax.swing.JFrame; import java.awt.FlowLayout; import javax.swing.JProgressBar; public class AtomFrame extends JFrame{ public JProgressBar progressBar; private static final long serialVersionUID = 4010489530693307355L; public static void main(String[] args){ AtomFrame testFrame = new AtomFrame(); testFrame.start(); } public AtomFrame(){ initializeComponents(); } public void initializeComponents(){ this.setSize(400, 400); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("Atom Launcher"); this.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5)); progressBar = new JProgressBar(); this.add(progressBar); //this.pack(); } public void start() { this.setVisible(true); } public void close() { this.dispose(); } } 

课程下载

 package atomicElectronics.utility; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import javax.swing.JProgressBar; public class Download { private static final int BUFFER_SIZE = 4096; private JProgressBar fileProgressBar; public Download() { } public void fileProgressBar(JProgressBar fileBar) { fileProgressBar = fileBar; } public void exicute(String fileURL, String saveDir) throws IOException { URL url = new URL(fileURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); int responseCode = httpConn.getResponseCode(); // always check HTTP response code first if (responseCode == HttpURLConnection.HTTP_OK) { String fileName = ""; String disposition = httpConn.getHeaderField("Content-Disposition"); String contentType = httpConn.getContentType(); double contentLength = httpConn.getContentLength(); if (disposition != null) { // extracts file name from header field int index = disposition.indexOf("filename="); if (index > 0) { fileName = disposition.substring(index + 9, disposition.length()); } } else { // extracts file name from URL fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1, fileURL.length()); } System.out.println("Content-Type = " + contentType); System.out.println("Content-Disposition = " + disposition); System.out.println("Content-Length = " + contentLength); System.out.println("fileName = " + fileName); // opens input stream from the HTTP connection InputStream inputStream = httpConn.getInputStream(); String saveFilePath = saveDir + File.separator + fileName; // opens an output stream to save into file FileOutputStream outputStream = new FileOutputStream(saveFilePath); double totalRead = 0; int bytesRead = -1; byte[] buffer = new byte[BUFFER_SIZE]; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); totalRead += bytesRead; System.out.println((totalRead / contentLength) * 100); fileProgressBar.setValue((int)((totalRead / contentLength) * 100)); } outputStream.close(); inputStream.close(); System.out.println("File downloaded"); } else { System.out.println("No file to download. Server replied HTTP code: " + responseCode); } httpConn.disconnect(); } 

}

建议:

  • 使用SwingWorker完成后台线程工作。
  • 在SwingWorker中,通过setProgress(int progress)设置其进度“bound”属性。 该值应介于1和100之间。
  • 没有你的SwingWorker /文件下载器持有JProgressBar或任何Swing组件。
  • 将PropertyChangeListener添加到SwingWorker并监视progress属性中的更改。
  • 永远不要将您的Swing字段(或大多数和所有字段)公开。 限制访问,而是通过方法更改对象状态。
  • 阅读Swing中的Concurrency教程以获取必要的详细信息。

例如,下面的代码是一个粗略的简化并且不下载任何文件,但是应该给你一个想法:

 import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Random; import javax.swing.*; public class Initial { static AtomFrame atomLauncher; public static void main(String[] args) { atomLauncher = new AtomFrame(); atomLauncher.start(); System.out.println(Integer.MAX_VALUE); final Download theDownload = new Download(); theDownload.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent pcEvt) { if ("progress".equals(pcEvt.getPropertyName())) { int progress = theDownload.getProgress(); atomLauncher.setProgress(progress); } } }); theDownload.execute(); } } class AtomFrame extends JFrame { // ********* should be private! private JProgressBar progressBar; private static final long serialVersionUID = 4010489530693307355L; public static void main(String[] args) { AtomFrame testFrame = new AtomFrame(); testFrame.start(); } public void setProgress(int progress) { progressBar.setValue(progress); } public AtomFrame() { initializeComponents(); } public void initializeComponents() { this.setSize(400, 400); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("Atom Launcher"); this.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5)); progressBar = new JProgressBar(); this.add(progressBar); // this.pack(); } public void start() { this.setVisible(true); } public void close() { this.dispose(); } } class Download extends SwingWorker { private static final long SLEEP_TIME = 300; private Random random = new Random(); @Override protected Void doInBackground() throws Exception { int myProgress = 0; while (myProgress < 100) { myProgress += random.nextInt(10); setProgress(myProgress); try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) {} } return null; } }