所以,我使用了一个JProgressBar。如何更新两个单独的进度条?我正在doInBackground()工作线程/ swingworker方法中执行下载。我想更新两个吧,第一个是总数,第二个是总数的一部分。例如,总共21/100 // 21/50 / halvsies
我已经问了一个问题here,最后弄清楚了这个线程。我现在正在考虑提高赌注,并获得两个进度表。谢谢阅读, 凯特〜
答案 0 :(得分:2)
您可以在更新“部分”进度时通过触发新的属性更改事件来利用属性更改支持。
根据您提供的信息,您可以通过多种方式实现这一目标。
您可以使用
之类的东西直接调用它firePropertyChange("sectionProgress", oldProgress, newProgress);
现在显然,您遇到了可怕的ETD同步问题,因为firePropertyChange
方法不是线程安全的。
但您可以创建一个简单的Updater
类,在Runnable
SwingWorker
private class TwoWorker extends SwingWorker<Double, Double> {
protected Double doInBackGround() throws Exception {
//... Do some work
SwingUtilities.invokeLater(new Updater(oldProgress, newProgress));
}
public class Updater implements Runnable {
private int oldProgress;
private int newProgress;
public Updater(int oldProgress, int newProgress) {
this.oldProgress = oldProgress;
this.newProgress = newProgress;
}
public void run() {
firePropertyChange("sectionProgress", oldProgress, newProgress);
}
}
}
答案 1 :(得分:2)
您可以利用SwingWorker<T,V>
类型参数V
,该参数用于在publish
和process
方法中执行中间结果。例如:
class DownloadProgress {
private int totalProgress;
private int currentTaskProgress;
public DownloadProgress(int totalProgress, int currentTaskProgress) {
this.totalProgress = totalProgress;
this.currentTaskProgress = currentTaskProgress;
}
}
public class DownloadWorker extends SwingWorker<Double, DownloadProgress> {
@Override
protected Double doInBackground() throws Exception {
...
publish(new DownloadProgress(1, 50));
}
@Override
protected void process(List<DownloadProgress> progressList) {
for (DownloadProgress p : progressList){
//update progress bars
}
}
}
答案 2 :(得分:2)
这是一个简单的例子(@Max已经说过):
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.Random;
import javax.swing.*;
public class TwoProgressBarsTest {
private final JTextArea area = new JTextArea();
private final JPanel statusPanel = new JPanel(new BorderLayout(0,2));
private final JButton runButton = new JButton(new RunAction());
private SwingWorker<String, DownloadProgress> worker;
public JComponent makeUI() {
area.setEditable(false);
JPanel p = new JPanel(new BorderLayout(5,5));
p.add(new JScrollPane(area));
p.add(runButton, BorderLayout.NORTH);
p.add(statusPanel, BorderLayout.SOUTH);
p.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
return p;
}
class RunAction extends AbstractAction {
public RunAction() {
super("run");
}
@Override public void actionPerformed(ActionEvent evt) {
final JProgressBar bar1 = new JProgressBar();
final JProgressBar bar2 = new JProgressBar();
runButton.setEnabled(false);
statusPanel.add(bar1, BorderLayout.NORTH);
statusPanel.add(bar2, BorderLayout.SOUTH);
statusPanel.revalidate();
worker = new SwingWorker<String, DownloadProgress>() {
@Override public String doInBackground() {
int current = 0;
int lengthOfTask = 12; //filelist.size();
publish(new DownloadProgress(Target.LOG, "Length Of Task: "+lengthOfTask));
publish(new DownloadProgress(Target.LOG, "\n-------------------------\n"));
while(current<lengthOfTask && !isCancelled()) {
if(!bar1.isDisplayable()) {
return "Disposed";
}
try {
convertFileToSomething();
} catch(InterruptedException ie) {
return "Interrupted";
}
publish(new DownloadProgress(Target.LOG, "*"));
publish(new DownloadProgress(Target.TOTAL, 100*current/lengthOfTask));
current++;
}
publish(new DownloadProgress(Target.LOG, "\n"));
return "Done";
}
private final Random r = new Random();
private void convertFileToSomething() throws InterruptedException {
int current = 0;
//long lengthOfTask = file.length();
int lengthOfTask = 10+r.nextInt(50);
while(current<=lengthOfTask && !isCancelled()) {
int iv = 100 * current / lengthOfTask;
Thread.sleep(20); // dummy
publish(new DownloadProgress(Target.FILE, iv+1));
current++;
}
}
@Override protected void process(List<DownloadProgress> chunks) {
for(DownloadProgress s: chunks) {
switch(s.component) {
case TOTAL:
bar1.setValue((Integer)s.value);
break;
case FILE:
bar2.setValue((Integer)s.value);
break;
case LOG:
area.append((String)s.value);
break;
}
}
}
@Override public void done() {
runButton.setEnabled(true);
statusPanel.removeAll();
statusPanel.revalidate();
String text = null;
if(isCancelled()) {
text = "Cancelled";
} else {
try {
text = get();
} catch(Exception ex) {
ex.printStackTrace();
text = "Exception";
}
}
area.append(text);
area.setCaretPosition(area.getDocument().getLength());
}
};
worker.execute();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() { createAndShowGUI(); }
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TwoProgressBarsTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
enum Target { TOTAL, FILE, LOG }
class DownloadProgress {
public final Object value;
public final Target component;
public DownloadProgress(Target component, Object value) {
this.component = component;
this.value = value;
}
}
答案 3 :(得分:2)
你可以走裸机路线:
每当您想要更新它时:
EventQueue.invokeLater(new Runnable(){
public void run(){
firstProgressBar.setValue(someInt);
secondProgressBar.setValue(someOtherInt);
}
});