为什么我的 ProgressBar 没有在 for() 循环中更新?

Why is my ProgressBar not updating in a for() loop?

我有一个 JProgressBar progressBar 应该在 for() 循环中更新。其实我已经看过这个问题了:Progress bar not updating during a loop 我用一个新的线程试了一下,但我不知道为什么它仍然没有更新。

我尝试了什么:

    public void getNewUUID(BufferedWriter output) {
    Menu.progressBar.setMinimum(0);
    Menu.progressBar.setMaximum(100);
    String hashchar = "";
    x = ID_LENGTH/100;
    y=0;

    for(int ch = 0; ch != ID_LENGTH; ch++) {
        done = ch;
        hashchar = "";
        for(int id = 0; id < ID_LENGTH; id++) {
            hashchar = hashchar+ALPHA_CHARS[rnd.nextInt(ALPHA_CHARS.length)];

            try {
                output.write(hashchar);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            hashchar = "";

            new Thread(new Runnable() {
                public void run() {
                    if(done>=x) {
                        x=x+x;
                        y++;
                        Menu.progressBar.setValue(y);

                    }
                }
            }).start();
        }



    }

try {
    output.flush();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
try {
    output.close();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
}

您正在非 UI 线程上执行进度条更新。您将需要使用 SwingUtilities.invokeLater(Runnable r):

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if(done>=x) {
                    x=x+x;
                    y++;
                    Menu.progressBar.setValue(y);

                }
            }
        });

这应该确保进度条更新发生在 UI 线程上,这应该会导致进度条用新值刷新。

根据这些类似的问题:Example 1, Example 2, Example 3, Example 4, Example 5

最好的办法是在 SwingWorker 创建的后台线程中执行长 运行 任务,并在工作程序内部,在代码运行时设置其进度 属性。然后 Swing 应用程序可以使用 PropertyChangeListener 监视工作进程的状态,并在侦听器中设置 JProgressBar 的进度值。可能与此类似:

public void getNewUUID(BufferedWriter output) {
    // JProgressBar should not be a static field
    Menu.progressBar.setMinimum(0);
    Menu.progressBar.setMaximum(100);
    x = ID_LENGTH / 100;
    y = 0;
    MyWorker myWorker = new MyWorker(output);
    myWorker.addPropertyChangeListener(new MyWorkerListener());
    myWorker.execute();
}

private class MyWorkerListener implements PropertyChangeListener {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if ("progress".equals(evt.getPropertyName())) {
            int progress = (int) evt.getNewValue();

            // TODO: set your JProgressBar's value here  *********
        }

        if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
            MyWorker myWorker = (MyWorker) evt.getSource();
            try {
                myWorker.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

private class MyWorker extends SwingWorker<Void, Void> {
    private BufferedWriter output;

    public MyWorker(BufferedWriter output) {
        this.output = output;
    }

    @Override
    protected Void doInBackground() throws Exception {
        String hashchar;
        for (int ch = 0; ch != ID_LENGTH; ch++) {
            done = ch;
            hashchar = "";
            for (int id = 0; id < ID_LENGTH; id++) {
                hashchar = hashchar
                        + ALPHA_CHARS[rnd.nextInt(ALPHA_CHARS.length)];
                try {
                    output.write(hashchar);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                hashchar = "";
                if (done >= x) {
                    x = x + x;
                    y++;
                    setProgress(y);
                }
            }
        }
        try {
            output.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}