为什么我的 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;
}
}
我有一个 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;
}
}