0

因此,我使用 ONE JProgressBar 进行了这项工作。如何更新两个单独的进度条?我正在 doInBackground() 工作线程/swingworker 方法中执行下载。我要更新两个条,第一个是总计,第二个是一个节的总计。例如,21/100 //总计 21/50 /halvsies

我已经在这里问了一个问题,终于弄清楚了这个线程问题。我现在正在寻找提高赌注,可以这么说,让两个进度条开始。感谢阅读,~Kyte

4

4 回答 4

2

您可以通过在更新“部分”进度时触发新的属性更改事件来利用属性更改支持。

您可以通过多种方式实现,具体取决于您可用的信息。

您可以使用类似的东西直接调用它

firePropertyChange("sectionProgress", oldProgress, newProgress);

现在显然,您遇到了可怕的 ETD 同步问题,因为该firePropertyChange方法不是线程安全的。

但是您可以创建一个在您的内部Updater实现的简单类RunnableSwingWorker

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);
        }   

    }

}
于 2012-07-24T01:21:40.620 回答
2

您可以利用用于在和方法中执行中间结果的SwingWorker<T,V>类型参数。例如:Vpublishprocess

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
        }
    }
}
于 2012-07-24T02:40:43.293 回答
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;
  }
}
于 2012-07-24T03:41:04.557 回答
2

你可以走裸机路线:

每当您希望更新它时:

EventQueue.invokeLater(new Runnable(){
    public void run(){
        firstProgressBar.setValue(someInt);
        secondProgressBar.setValue(someOtherInt);
    }
});
于 2012-07-24T03:42:51.700 回答