Java Swing don'中的线程;行不通

Java Swing don'中的线程;行不通,java,multithreading,swing,event-dispatch-thread,jprogressbar,Java,Multithreading,Swing,Event Dispatch Thread,Jprogressbar,我有一些带有for循环的简单代码。在循环的每个过程中,我必须增加JProgressBar;然而,这是行不通的。见下文: public void atualizarBarraDeProgresso(final int valorGeral, final int valorAtual) { Thread threadProgressoCarregamento = new Thread() { @Override public void run() {

我有一些带有
for
循环的简单代码。在循环的每个过程中,我必须增加JProgressBar;然而,这是行不通的。见下文:

public void atualizarBarraDeProgresso(final int valorGeral, final int valorAtual) {
    Thread threadProgressoCarregamento = new Thread() {
        @Override
        public void run() {
             jProgressBarPersistindo.setValue(valorAtual);
        }
    };
    threadProgressoCarregamento.start();
}
我在下面的循环中调用方法“atuanizarbaradeprogresso”:

progressBar.setMinimum(0);
progressBar.setMaximum(qtd);
for(int i = 0; i < qtd; i++) { 
    atualizarBarraDeProgresso(qtd, i + 1);
    doSomething();
}
progressBar.setMinimum(0);
进度条设置最大值(qtd);
对于(inti=0;i

但是我的progressBar没有发生任何变化。

尝试在for语句之前添加一个线程。我希望它能起作用

    progressBar.setMinimum(0);
    progressBar.setMaximum(qtd);

    new Thread(){
        @Override
        public void run() {
            for(int i = 0; i < qtd; i++) { 
                atualizarBarraDeProgresso(qtd, i + 1);
                doSomething();
            }
        }
    }.start();
progressBar.setMinimum(0);
进度条设置最大值(qtd);
新线程(){
@凌驾
公开募捐{
对于(inti=0;i
这应该可以通过实现轻松管理<代码>SwingWorker
s在您需要“做某事”但不想在执行时阻塞GUI时非常有用。该类还为您提供了一个有用的API,用于在通过
publish()/process()
方法执行其他工作时需要更新GUI组件时与EDT通信

下面的实现处理工作线程上的循环,以便它不会阻塞EDT(GUI线程)。对
publish(Integer…
的调用作为对
process(List)
的调用中继到EDT,您要在这里更新您的JProgressBar,因为与所有Swing组件一样,您应该只更新EDT上的JProgressBar

public class MySwingWorker extends SwingWorker<Void, Integer> {

    private final int qtd;
    private final JProgressBar progressBar;

    public MySwingWorker(JProgressBar progressBar, int qtd){
        this.qtd = qtd;
        this.progressBar = progressBar;
    }

    /* This method is called off the EDT so it doesn't block the GUI. */
    @Override
    protected Void doInBackground() throws Exception {
        for(int i = 0; i < qtd; i++) { 

            /* This sends the arguments to the process(List) method 
             * so they can be handled on the EDT. */
            publish(i + 1);

            /* Do your stuff. */
            doSomething();
        }
        return null;
    }

    /* This method is called on the EDT in response to a 
     * call to publish(Integer...) */
    @Override
    protected void process(List<Integer> chunks) {
        progressBar.setValue(chunks.get(chunks.size() - 1));
    }
}
公共类MyWingWorker扩展SwingWorker{
私人最终int qtd;
私人最终JProgressBar progressBar;
公共MySwingWorker(JProgressBar progressBar,int qtd){
this.qtd=qtd;
this.progressBar=progressBar;
}
/*此方法在EDT中被取消,因此不会阻塞GUI*/
@凌驾
受保护的Void doInBackground()引发异常{
对于(inti=0;i
你可以这样开始

int qtd = ...;

progressBar.setMinimum(0);
progressBar.setMaximum(qtd);

SwingWorker<? ,?> worker = new MySwingWorker(progressBar, qtd);

worker.execute();
intqtd=。。。;
progressBar.setMinimum(0);
进度条设置最大值(qtd);
SwingWorker工人=新的MySwingWorker(progressBar,qtd);
worker.execute();

您真的需要那么多线程吗?在任何情况下,我怀疑问题在于循环本身发生在ADT上(即在“单击处理程序”中),并阻止Swing UI交互和更新,直到它完成。考虑使用A-使用这样正确可能会消除所有问题。另外,请确保只更新ADT上的Swing对象。在任意点设置值后,是否在包含的JPanel上调用repaint()?这可能是缺少的全部内容。调用repaint()方法,顺便说一句,解决方案非常糟糕。@user2246674(礼貌咳嗽)by'ADT'DYM'EDT'?对于OP,一个一般提示。不要阻止EDT(事件调度线程)-发生这种情况时,GUI将“冻结”。不要调用
Thread.sleep(n)
为重复任务执行Swing
计时器,或为长时间运行的任务执行
SwingWorker
。有关更多详细信息,请参阅。这是对所需逻辑的有趣反转:不是确保Swing
组件的修改发生在EDT内部,而是确保修改是EDT之外的唯一操作。