因此,我使用 ONE JProgressBar 进行了这项工作。如何更新两个单独的进度条?我正在 doInBackground() 工作线程/swingworker 方法中执行下载。我要更新两个条,第一个是总计,第二个是一个节的总计。例如,21/100 //总计 21/50 /halvsies
我已经在这里问了一个问题,终于弄清楚了这个线程问题。我现在正在寻找提高赌注,可以这么说,让两个进度条开始。感谢阅读,~Kyte
因此,我使用 ONE JProgressBar 进行了这项工作。如何更新两个单独的进度条?我正在 doInBackground() 工作线程/swingworker 方法中执行下载。我要更新两个条,第一个是总计,第二个是一个节的总计。例如,21/100 //总计 21/50 /halvsies
我已经在这里问了一个问题,终于弄清楚了这个线程问题。我现在正在寻找提高赌注,可以这么说,让两个进度条开始。感谢阅读,~Kyte
您可以通过在更新“部分”进度时触发新的属性更改事件来利用属性更改支持。
您可以通过多种方式实现,具体取决于您可用的信息。
您可以使用类似的东西直接调用它
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);
}
}
}
您可以利用用于在和方法中执行中间结果的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
}
}
}
这是一个简单的例子(@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;
}
}
你可以走裸机路线:
每当您希望更新它时:
EventQueue.invokeLater(new Runnable(){
public void run(){
firstProgressBar.setValue(someInt);
secondProgressBar.setValue(someOtherInt);
}
});