Java 如何使用Swingworker显示进度条?
这是我的代码片段。点击按钮,它在后台执行加载程序,但我无法在进度条中获取任务的详细信息。谁能告诉我我在这里错过了什么 关键是我不想在doInBackground方法中包含所有插入代码Java 如何使用Swingworker显示进度条?,java,multithreading,swing,desktop-application,swingworker,Java,Multithreading,Swing,Desktop Application,Swingworker,这是我的代码片段。点击按钮,它在后台执行加载程序,但我无法在进度条中获取任务的详细信息。谁能告诉我我在这里错过了什么 关键是我不想在doInBackground方法中包含所有插入代码 public class ProgressBarDemo extends JPanel implements ActionListener, PropertyChangeLis
public class ProgressBarDemo extends JPanel
implements ActionListener,
PropertyChangeListener {
private JProgressBar progressBar;
private JButton startButton;
private JTextArea taskOutput;
private Task task;
class Task extends SwingWorker<Void, Integer> {
@Override
protected void process(List<Integer> arg0) {
// TODO Auto-generated method stub
super.process(arg0);
for(int k:arg0)
System.out.println("arg is "+k);
setProgress(arg0.size()-1);
}
/*
* Main task. Executed in background thread.
*/
@Override
public Void doInBackground() throws Exception {
Random random = new Random();
int progress = 0;
//Initialize progress property.
setProgress(0);
Thread.sleep(100);
new LoadUnderwritingData().filesinfolder("D:\\files to upload\\");
System.out.println("records inserted are "+LoadData.records_count_inserted);
publish(LoadData.records_count_inserted);
/*
* while (progress < 100) { //Sleep for up to one second. try {
* Thread.sleep(random.nextInt(1000)); } catch (InterruptedException ignore) {}
* //Make random progress. progress += random.nextInt(10);
* setProgress(Math.min(progress, 100)); }
*/
return null;
}
/*
* Executed in event dispatching thread
*/
@Override
public void done() {
Toolkit.getDefaultToolkit().beep();
startButton.setEnabled(true);
setCursor(null); //turn off the wait cursor
taskOutput.append("Done!\n");
}
}
公共类ProgressBarDemo扩展了JPanel
实现ActionListener,
PropertyChangeListener{
私人JProgressBar progressBar;
私有JButton开始按钮;
专用JTextArea任务输出;
私人任务;
类任务扩展SwingWorker{
@凌驾
受保护的无效进程(列表arg0){
//TODO自动生成的方法存根
超级进程(arg0);
用于(int k:arg0)
System.out.println(“arg是”+k);
setProgress(arg0.size()-1);
}
/*
*主任务。在后台线程中执行。
*/
@凌驾
public Void doInBackground()引发异常{
随机=新随机();
int progress=0;
//初始化进度属性。
setProgress(0);
睡眠(100);
新建LoadUnderwritingData().FileInfolder(“D:\\files to upload\\”;
System.out.println(“插入的记录是”+加载数据。记录\u计数\u插入);
发布(加载数据、记录、计数、插入);
/*
*而(进度<100){//最多睡一秒钟。试试看{
*Thread.sleep(random.nextInt(1000));}catch(InterruptedException ignore){}
*//进行随机进程。进程+=random.nextInt(10);
*setProgress(Math.min(progress,100));}
*/
返回null;
}
/*
*在事件调度线程中执行
*/
@凌驾
公众假期结束(){
getDefaultToolkit().beep();
startButton.setEnabled(真);
setCursor(null);//关闭等待光标
taskOutput.append(“完成!\n”);
}
}
我看到您没有调用progressBar.setValue(progress);
您还需要在每个插入的元素之后调用
publish(currentInsertCount);
。
在流程方法中,您将执行以下操作:
// assuming you are passing the current insert count to publish()
for (int k : arg0){
System.out.println("arg is " + k);
progressBar.setValue(k);
}
然而,从您现在发布的内容来看,还不清楚在哪里进行处理。
是这行吗:new LoadUnderwritingData().filesinfolder("D:\\files to upload\\");
如果是,那么您必须将一些回调传递给文件信息文件夹(“…”)
,以便它可以更新进度
注意:只在一个普通的新线程中执行,而不是使用SwingWorker
,可能会更容易
我将如何用一根普通的线来做:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class ProgressBarDemo extends JPanel implements ActionListener {
private JProgressBar progressBar;
private JButton startButton;
private JTextArea taskOutput;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("ProgressBarDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setPreferredSize(new Dimension(500, 500));
frame.add(new ProgressBarDemo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
public ProgressBarDemo() {
progressBar = new JProgressBar(0, 100);
startButton = new JButton(">");
taskOutput = new JTextArea();
startButton.addActionListener(this);
setLayout(new BorderLayout());
add(startButton, BorderLayout.NORTH);
add(taskOutput, BorderLayout.CENTER);
add(progressBar, BorderLayout.SOUTH);
progressBar.setVisible(false);
}
// If you don't care about a small chance of the UI not updating properly then you can perform the updates directly instead of calling invokeLater.
// If you are compiling below Java 1.8, you need to convert Lambda expression to a Runnable and make the directory parameter final.
public void upload(File directory) {
// No need for invokeLater here because this is called within the AWT Event Handling
startButton.setEnabled(false);
progressBar.setVisible(true);
new Thread() {
@Override
public void run() {
taskOutput.append("Discovering files...\n");
// List<File> files = Arrays.asList(directory.listFiles()); //
// if you want to process both files and directories, but only
// in the given folder, not in any sub folders
// List<File> files = Arrays.asList(getAllFiles(directory)); //
// if you only want the files in that directory, but not in sub
// directories
List<File> files = getAllFilesRecursive(directory); // if you
// want all
// files
SwingUtilities.invokeLater(() -> {
taskOutput.append(" -> discovered " + files.size() + " files.\n");
progressBar.setMaximum(files.size());
taskOutput.append("Processing files...\n");
});
int processedCount = 0;
for (File file : files) {
try {
byte[] bytes = Files.readAllBytes(file.toPath());
// TODO: process / upload or whatever you want to do with it
} catch (Throwable e) {
// Same here, you may skip the invokeLater
SwingUtilities.invokeLater(() -> taskOutput.append("Failed to process " + file.getName() + ": " + e.getMessage() + "\n"));
e.printStackTrace();
} finally {
processedCount++;
final int prcCont = processedCount; // not necessary if invoking directly
SwingUtilities.invokeLater(() -> progressBar.setValue(prcCont));
}
}
SwingUtilities.invokeLater(() -> {
taskOutput.append(" -> done.\n");
startButton.setEnabled(true);
progressBar.setVisible(false);
});
}
}.start();
}
@Override
public void actionPerformed(ActionEvent e) {
upload(new File("C:\\directoryToUpload"));
}
/**
* Gets all normal files in the directory.
*/
public static File[] getAllFiles(File directory) {
return directory.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile();
}
});
}
/**
* Gets all normal files in the given directory and its sub directories.
*/
public static List<File> getAllFilesRecursive(File directory) {
List<File> result = new ArrayList<File>();
getAllFilesRecursive(directory, result);
return result;
}
private static void getAllFilesRecursive(File directory, List<File> addTo) {
if (directory.isFile()) {
addTo.add(directory);
} else if (directory.isDirectory()) {
File[] subFiles = directory.listFiles();
if (subFiles == null)
return;
for (File subFile : subFiles) {
getAllFilesRecursive(subFile, addTo);
}
}
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.io.File;
导入java.io.FileFilter;
导入java.nio.file.Files;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JProgressBar;
导入javax.swing.JTextArea;
导入javax.swing.SwingUtilities;
公共类ProgressBarDemo扩展JPanel实现ActionListener{
私人JProgressBar progressBar;
私有JButton开始按钮;
专用JTextArea任务输出;
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(()->{
JFrame=新JFrame(“ProgressBarDemo”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setPreferredSize(新维度(500500));
frame.add(newprogressbardemo());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
});
}
公共进步组织(){
progressBar=新的JProgressBar(01100);
startButton=新的JButton(“>”);
taskOutput=新的JTextArea();
addActionListener(这个);
setLayout(新的BorderLayout());
添加(开始按钮,BorderLayout.NORTH);
添加(taskOutput、BorderLayout.CENTER);
添加(progressBar,BorderLayout.SOUTH);
progressBar.setVisible(false);
}
//如果您不关心UI不正确更新的可能性很小,那么您可以直接执行更新,而不是调用invokeLater。
//如果您是在Java 1.8以下编译,则需要将Lambda表达式转换为可运行的,并使目录参数为final。
公共无效上载(文件目录){
//这里不需要调用器,因为它是在AWT事件处理中调用的
startButton.setEnabled(错误);
progressBar.setVisible(true);
新线程(){
@凌驾
公开募捐{
taskOutput.append(“发现文件…\n”);
//List files=Arrays.asList(directory.listFiles())//
//如果要同时处理文件和目录,但仅
//在给定文件夹中,而不是在任何子文件夹中
//List files=Arrays.asList(getAllFiles(directory))//
//如果您只想要该目录中的文件,而不想要子目录中的文件
//目录
List files=getAllFilesRecursive(目录);//如果
//想要全部
//档案
SwingUtilities.invokeLater(()->{
taskOutput.append(“->发现“+文件.size()+”文件。\n”);
progressBar.setMaximum(files.size());
taskOutput.append(“处理文件…\n”);
});
int processedCount=0;
用于(文件:文件){
试一试{
byte[]bytes=Files.readAllBytes(file.toPath());
//TODO:处理/上传或任何你想用它做的事情