java swing中经常要使用到进度条,比如下载文件和拷贝文件时显示进度,如下图所示:
下载完成之后:
难点在于:在读取输入流的时候,实时更新进度条。
我自己定了一个规则:
(1) 若输入流的大小小于1024,则字节数组的长度就是输入流的大小。
<!--[if !supportLists]-->(1) (2) <!--[endif]-->获取文件的大小,并平分为100等份,得到商1;
<!--[if !supportLists]-->(2) (3)<!--[endif]-->拿每一等份(商1)和1024比较:若小于等于1024,则字节数组大小为商1;
若大于1024,则除以1024,得到商2,则字节数组大小为商1/商2
<!--[if !supportLists]-->(3)
规定:100%时的颜色为蓝色:copyProgressBar.setForeground(Color.blue);
核心代码:
/*** * 在实际使用过程中,应该放在线程中 * @param in * @param sourceSize * : 输入流的长度,即要读取的字节个数 * @param targfile */ public static void progress(JProgressBar copyProgressBar, InputStream in, long sourceSize, File targfile) { FileOutputStream target = null; try { int bytesArrLeng = 0; if (sourceSize < SystemHWUtil.BUFF_SIZE_1024) {// bytesArrLeng = (int) sourceSize; } else { long shangOne = sourceSize / SystemHWUtil.NUMBER_100; if (shangOne == 0) {// sourceSize<100 shangOne = shangOne + 1; } if (shangOne <= SystemHWUtil.BUFF_SIZE_1024) { bytesArrLeng = (int) shangOne; } else { long shangTwo = shangOne / SystemHWUtil.BUFF_SIZE_1024; if (shangOne % SystemHWUtil.BUFF_SIZE_1024 != 0) { shangTwo = shangTwo + 1L; } bytesArrLeng = (int) (shangOne / shangTwo); } } System.out.println("字节数组的长度是:" + bytesArrLeng); target = new FileOutputStream(targfile); byte[] buffer = new byte[bytesArrLeng]; int byteNum; long hasReadByte = 0L;// 已经读取的字节个数 float result; int progressSize = 0; while ((byteNum = in.read(buffer)) != SystemHWUtil.NEGATIVE_ONE) { target.write(buffer, 0, byteNum); hasReadByte = hasReadByte + byteNum; result = (float) ((double) hasReadByte / sourceSize); progressSize = Math.round(result * SystemHWUtil.NUMBER_100); // copyProgressBar.setString(progressSize + "%"); // copyProgressBar.setValue(progressSize); updateProgress(copyProgressBar, progressSize); } if (progressSize < SystemHWUtil.NUMBER_100) { progressSize = SystemHWUtil.NUMBER_100; updateProgress(copyProgressBar, progressSize); } copyProgressBar.setForeground(Color.blue); // System.out // .println("[SystemUtil:copyFile]:file copy successfully!"); // resultTextArea.setText(); } catch (Exception e) { e.printStackTrace(); // copyFileBtn.setEnabled(true); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } in = null; } if (target != null) { try { target.close(); } catch (IOException e) { e.printStackTrace(); } target = null; } } } /*** * 更新进度条上得进度数字 * @param copyProgressBar * @param progressSize */ private static void updateProgress(JProgressBar copyProgressBar, int progressSize) { copyProgressBar.setString(progressSize + "%"); copyProgressBar.setValue(progressSize); }
使用进度条的代码:
new Thread(new Runnable() { @Override public void run() { try { HttpSocketUtil.setDetail(true); // HttpSocketUtil.httpRequest(urlTF.getText(), null, // null, true, selectedFile, -1, -1); HttpURLConnection huc = HttpSocketUtil .beforeConnect(httpSenderApp.getUrlTF() .getText(), null, null, null, null, SystemHWUtil.NEGATIVE_ONE, SystemHWUtil.NEGATIVE_ONE); InputStream in = huc.getInputStream(); int contentLength; String sizeHeadKey = null; if (ValueWidget.isNullOrEmpty(sizeHeadKey)) {// 若header中没有size contentLength = huc.getContentLength(); } else { contentLength = Integer.parseInt(huc .getHeaderField(sizeHeadKey)); } ComponentUtil.progress( httpSenderApp.getCopyProgressBar(), in, contentLength, selectedFile); GUIUtil23.infoDialog("下载成功!size:" + FileUtils.formatFileSize2(selectedFile .length())); } catch (Exception e) { GUIUtil23.errorDialog(e.getMessage()); e.printStackTrace(); } } }).start();
依赖的jar:io0007-find_progess-0.0.7.2-SNAPSHOT.jar
demo:http-sender
注意:项目使用maven 构建