下面是一个没有像我预期的那样更新Java GUI的SwingWorker实例。
SwingWorker是在按钮的动作侦听器中实现的。定义循环的min
和max
都是“final int”,它们是动作侦听器的本地。
SwingWorker应该在每次迭代时调用NQueens
对象的go()方法,该方法递归地找到n-queens的所有解。然后调用NQueens
对象的toString()
,之后发布String,以便process()方法更新jProgressBar
和jTextArea
。但是按下按钮时没有任何反应。这是我应该如何实现一个加上GUI组件更新的密集过程?
new SwingWorker <Void,String>()
{
private int totalPercent;
@Override
protected Void doInBackground()
{
int diff = max - min + 1;
int percent = 100;
if(diff != 0)
{
percent = 100/diff;
}
totalPercent = 0;
NQueens queens = new NQueens(min);
for(int j = min; j <= max; j++)
{
queens.go();
totalPercent += percent;
String newText = queens.toString();
publish(newText);
queens.nextSet();
}
isCalced = true;
return null;
}
protected void process(String results)
{
jTextArea2.append(results);
jProgressBar1.setValue(totalPercent);
jProgressBar1.repaint();
}
}.execute();
答案 0 :(得分:0)
原因可能是您没有实施正确的流程方法?我相信过程的正确签名是
process(List<String> results) {
for(String result : results) {
jTextArea2.append(result);
}
}
关于更新进度条; doInBackground方法在单独的线程中运行,而进程方法在您调用worker的线程上运行。您不应该从doInBackground写入totalPercent变量并从process()读取它。有关详情,请参阅thread visibility。相反,创建一个名为ProgressUpdateEvent的类,它可以保存百分比值和消息。这样,你可以这样做:
new SwingWorker <Void,ProgressUpdateEvent>() {
protected Void doInBackground() {
for (int i = 0; i <= 100; i++) {
publish(new ProgressUpdateEvent("At " + i + "% right now", i);
}
}
protected void process(List<ProgressUpdateEvent> events) {
for (ProgressUpdateEvent event : events) {
jTextArea2.append(event.getMessage());
jProgressBar1.setValue(event.getPercent());
}
}
}