我使用Java,Swing(窗口生成器)在Windows上開發了一個應用程序。
單擊按鈕,我的應用程序將轉到另一個類(FileManager.java
文件)以統計輸入文件夾中的文件總數(同時progressBar
將處於不確定模式)。一旦文件的數量已知,則設置最大值progressBar
。Java Swing Worker for Progress Bar - 用戶界面長時間保持無響應狀態
然後我打電話convertToXLS(fileMgr)
來讀取每個文件的內容(1 kb),並在讀取每個文件時更新progressBar
。
這裏是它的代碼:
public class xmlToXL {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
xmlToXL window = new xmlToXL();
window.frame.setVisible(true);
}
});
private void initialize() {
...... some UI code ........
btnConvertXmlTo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
preConvertToXLS();
Task task = new Task(folderPath.getText());
task.execute();
} catch (Exception e1) {
e1.printStackTrace();
}
}// end of actionPerformed method
}); // end of action listened
}//end of initialize
public void preConvertToXLS() { //method to set few UI properties
btnConvertXmlTo.setEnabled(false);
progressBar.setVisible(true);
progressBar.setStringPainted(true);
progressBar.setIndeterminate(true);
progressBar.setString("Calculating Total number of files...");
progressBar.setForeground(new Color(0, 102, 0));
}
ParserUtils parUtils = new ParserUtils(); //class to parse XML files (in another .java file)
private void convertToXLS(FileManager fileMgr) {
try {
int i=1;
parUtils.reset();
progressBar.setValue(0);
List<File> files = fileMgr.getFiles();
for(File file : files) {
progressBar.setString("Reading " + i+ " of " + fileMgr.getSize()+ " files");
parUtils.parseFileUsingDOM(file); // This will read content of the input file
progressBar.setValue(i++);
}
btnConvertXmlTo.setEnabled(true);
} catch (Exception e) {
}
}
class Task extends SwingWorker<Void, Void> {
private FileManager fileMgr;
public Task(String srcPath) {
this.fileMgr = new FileManager(new File(srcPath));
}
/*
* Main task. Executed in background thread.
*/
@Override
public Void doInBackground() {
try {
progressBar.setIndeterminate(true);
fileMgr.readFiles();
progressBar.setIndeterminate(false);
progressBar.setMaximum(fileMgr.getSize());
convertToXLS(fileMgr);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/*
* Executed in event dispatching thread
*/
@Override
public void done() {
Toolkit.getDefaultToolkit().beep();
try {
progressBar.setString("FileRead Successful");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}//end of task class
}//end of My class
我的UI變得fileMgr.readFiles();
後反應遲鈍。它需要一兩分鐘,有時需要三分鐘,然後執行convertToXLS(fileMgr)
。
FileManager.java
import XMLParsing.DetermineEncoding;
public class FileManager {
public HashMap<String, ArrayList<String>> dirFiles = null;
public ArrayList<String> dirNames = null;
public int numberOfFiles;
private File src;
private List<File> files;
public FileManager(File src) {
this.src = src;
dirNames = new ArrayList<String>();
dirFiles = new HashMap<String, ArrayList<String>>();
numberOfFiles = 0;
files = new ArrayList<File>();
}
public int getSize() {
return numberOfFiles;
}
public ArrayList<String> getDirectories(){
return dirNames;
}
public List<File> getFiles() {
Iterator it = dirFiles.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
String folderName = (pair.getKey()).toString();
ArrayList<String> FileNames = (ArrayList<String>) pair.getValue();
if (FileNames != null) {
for (String fileName : FileNames) {
if(replaceSelected(fileName)) {
File fXmlFile = new File(fileName);
files.add(fXmlFile);
}
else {
}
}
}
}
return files;
}
public void readFiles() throws IOException {
readFiles(src);
}
private void readFiles(File folder) throws IOException {
if (folder.isDirectory()) {
ArrayList<String> fileNames = new ArrayList<String>();
for (final File file : folder.listFiles()) {
if (file.isDirectory()) {
readFiles(file);
} else {
String fileName = (file.getPath()).toString();
if(fileName.toLowerCase().endsWith(".xml")) {
fileNames.add(file.getPath());
numberOfFiles = numberOfFiles + 1;
System.out.println(".");
if(!dirNames.contains(file.getParentFile().getName()))
dirNames.add(file.getParentFile().getName());
}
}
}
dirFiles.put(folder.getName(), fileNames);
}
}
private boolean replaceSelected(String filePath) {
String line;
String input = "";
try {
DetermineEncoding DE = new DetermineEncoding();
String encoding = DE.getFileEncoding(filePath);
InputStreamReader file = new InputStreamReader(new FileInputStream(
filePath), encoding);
BufferedReader br = new BufferedReader(file);
while ((line = br.readLine()) != null) {
input += line.toString() + " ";
}
file.close();
Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(filePath), "UTF-8"));
out.append(input.trim());
out.flush();
out.close();
} catch (Exception e) {
return false;
}
return true;
}
}
DetermineEncoding.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.mozilla.universalchardet.UniversalDetector;
public class DetermineEncoding {
public DetermineEncoding() {
// TODO Auto-generated constructor stub
}
public String getFileEncoding(String fileName) throws IOException {
byte[] buf = new byte[4096];
java.io.FileInputStream fis = new FileInputStream(fileName);
UniversalDetector detector = new UniversalDetector(null);
int nread;
while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread);
}
detector.dataEnd();
String encoding = detector.getDetectedCharset();
if (encoding != null) {
return encoding;
} else {
return "";
}
}
}
請幫我找出問題。
你不應該被修改從事件派發線程的上下文之外的UI組件的狀態,在'doInBackground'方法內調用'progressBar.setIndeterminate(true);'是一個壞主意 – MadProgrammer
好吧,但那是當我的progressBar要更新時。我該怎麼做 ?感謝您的回覆 –
看看這個[示例](http://stackoverflow.com/questions/23125642/swingworker-in-another-swingworkers-done-method/23126410#23126410) – MadProgrammer