天天看點

java 進度條 不更新_java進度條不動怎麼解決?

在編寫完進度條後,我們有時候會遇到它完全不動的情況,小夥伴們知道是什麼原因嗎?下面聽小編為你們講解講解。

進度條不動可能是因為這個原因,“當應用程式在事件線程中執行長時間的操作時,會阻塞正常的AWT事件處理,是以阻止了重繪操作的發生”,即API本身就是線程不安全的。造成這個錯誤的原因,就是在run方法内直接寫:

progressBar.setValue(jd);

最終修改示例:import java.awt.Color;

import java.awt.Dimension;

import java.awt.GridLayout;

import java.awt.Rectangle;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import javax.swing.JButton;

import javax.swing.JFileChooser;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JProgressBar;

import javax.swing.JTextField;

public class Exp10_3 extends JFrame implements Runnable

{

boolean b = false; // 線程執行的标志

int jd = 0; // 目前進度

long sum = 0; // 目前共複制的長度

JButton button1 = new JButton("被複制");

JTextField beCyFile = new JTextField(30);

JButton button2 = new JButton("複制到");

JTextField CyToDir = new JTextField(30);

JButton Start = new JButton("開始複制");

JLabel label = new JLabel("進度");

JProgressBar progressBar = new JProgressBar();

void initUI()

{

JPanel top1 = new JPanel();

JPanel top2 = new JPanel();

JPanel end = new JPanel();

top1.add(button1);

top1.add(beCyFile);

top2.add(button2);

top2.add(CyToDir);

setLayout(new GridLayout(4, 1));

add(top1);

add(top2);

add(Start);

progressBar.setStringPainted(true); // 設定進度條上字元串可顯示

progressBar.setBackground(Color.GREEN); // 設定進度條顔色

end.add(label);

end.add(progressBar);

add(end);

button1.addActionListener(new ActionListener()

{

// 将選擇檔案的絕對路徑顯示到被複制後的文本框内

@Override

public void actionPerformed(ActionEvent e)

{

JFileChooser fc = new JFileChooser();

fc.setFileHidingEnabled(false); // 顯示隐藏檔案

fc.setMultiSelectionEnabled(false); // 允許多選

fc.setDialogTitle("請選擇要複制的檔案");

if (fc.showOpenDialog(Exp10_3.this) == JFileChooser.APPROVE_OPTION)

{

beCyFile.setText(fc.getSelectedFile()

.getAbsolutePath());

CyToDir.setText(fc.getSelectedFile()

.getParent()); // 擷取file檔案的父目錄(強大的API) 自我設定:預設複制到同一目錄

}

}

});

button2.addActionListener(new ActionListener()

{

@Override

public void actionPerformed(ActionEvent e)

{

JFileChooser fc = new JFileChooser();

fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // 僅僅能選擇目錄

fc.setDialogTitle("請選擇要複制到的路徑");

if (fc.showOpenDialog(Exp10_3.this) == JFileChooser.APPROVE_OPTION)

{

CyToDir.setText(fc.getSelectedFile()

.getAbsolutePath());

}

}

});

Start.addActionListener(new ActionListener()

{

@Override

public void actionPerformed(ActionEvent e)

{

jd = 0;

b = true;

try

{

String file1Path = beCyFile.getText();

File file1 = new File(beCyFile.getText()); // 被複制的檔案

String file2Path = CyToDir.getText() + "\\copy" + file1.getName(); // 複制完後新檔案路徑名

File file2 = new File(file2Path); // 建立複制檔案

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file1Path));

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file2Path));

byte[] be = new byte[1024 * 1024]; // 之前定義為b和boolean重複了 屏蔽了全局标志b

int len = bis.read(be);

long sum = 0;

long file1len = file1.length();

while (-1 != len)

{

bos.write(be, 0, len); // 一次讀一個位元組數組 換行也會讀 不用自動換行了

bos.flush();

sum += len;

jd = (int)(sum * 1.0 / file1len * 100); // 之前沒有乘1.0 且多寫了一個(int) 導緻jd一直是0 最後一次突變100

len = bis.read(be);

}

最後再繪一次

Dimension d = progressBar.getSize();

Rectangle rect = new Rectangle(0, 0, d.width, d.height);

progressBar.setValue(jd);

progressBar.paintImmediately(rect);

b = false;

System.out.println("b=" + b);

}

catch (IOException e1)

{

e1.printStackTrace();

}

}

});

Thread t = new Thread(this);

t.start();

pack();

setLocationRelativeTo(null);

setVisible(true);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[] args)

{

Exp10_3 t = new Exp10_3();

t.initUI();

}

@Override

public void run()

{

while (true)

{

if (b)

{

//progressBar.setValue(jd);//之前run内就這一行,進度條一直不重新整理

Dimension d = progressBar.getSize();

Rectangle rect = new Rectangle(0, 0, d.width, d.height);

progressBar.setValue(jd);

progressBar.paintImmediately(rect);

if (jd == 100)

{

b = false;

//System.out.println("run内b=" + b);// 不能寫return 此程序不能結束 一直開着

}

}

//System.out.println("我沒有結束");//删了此行進度條就又不重新整理了

//第一次改進  上面一行換成下面5行  即輸出操作改成停頓1ms

try

{

Thread.sleep(1);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

}

}

以上就是本篇文章的所有内容,對于一些java常見問題及解決方法還有不懂的話就來我們網站看看吧。

推薦閱讀: