Java SwingWorker线程更新主GUI

5

嗨,我想知道在SwingWorker线程中向JTextArea添加文本的最佳方法是什么。我创建了另一个类,通过Threadsclass().execute()被JButton调用,并且该线程可以与以下代码并行运行:

public class Threadsclass extends SwingWorker<Object, Object> {


@Override
protected Object doInBackground() throws Exception {
    for(int x = 0; x< 10;x++)
        try {
            System.out.println("sleep number :"+ x);



        Thread.sleep(1000);
    } catch (InterruptedException ex) {
        Logger.getLogger(eftcespbillpaymentsThreads.class.getName()).log(Level.SEVERE, null, ex);
    }
    throw new UnsupportedOperationException("Not supported yet.");
}

}

现在我想做的是将x的值添加到主GUI上的文本区域中,非常感谢任何想法。


2
Javadoc有一个做这件事情的例子:PrimeNumbersTask。 - JB Nizet
2个回答

9

这里有一个来自JavaDocs的绝佳示例。

class PrimeNumbersTask extends
        SwingWorker<List<Integer>, Integer> {

    PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
        //initialize
    }

    @Override
    public List<Integer> doInBackground() {
        List<Integer> numbers = new ArrayList<Integer>(25);
        while (!enough && !isCancelled()) {
            number = nextPrimeNumber();
            numbers.add(number);
            publish(number);
            setProgress(100 * numbers.size() / numbersToFind);
        }

        return numbers;
    }

    @Override
    protected void process(List<Integer> chunks) {
        for (int number : chunks) {
            textArea.append(number + "\n");
        }
    }
}

JTextArea textArea = new JTextArea();
final JProgressBar progressBar = new JProgressBar(0, 100);
PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
task.addPropertyChangeListener(
 new PropertyChangeListener() {
     public  void propertyChange(PropertyChangeEvent evt) {
         if ("progress".equals(evt.getPropertyName())) {
             progressBar.setValue((Integer)evt.getNewValue());
         }
     }
 });

task.execute();
System.out.println(task.get()); //prints all prime numbers we have got

请查看 publishprocess
其基本意图是,您需要仅在事件分派线程内更新UI,通过将要更新的数据通过publish方法传递给UI,SwingWorker将在EDT上下文中为您调用process

不确定为什么您拒绝了我的编辑..现在return numbers;doInBackground之外,而protected void process(..) {..}PrimeNumbersTask类之外。 - Marc
我在 JavaDoc for get() 中读到,get() 会冻结 GUI / EDT。这对于这里是否会造成问题呢?我还看到,人们通常会更改 done() 并在其中使用 get() 以避免冻结。JavaDoc 页面中的示例没有直接解决冻结问题,因此在有人复制该示例时可能会忽略此问题。 - hamena314
1
通常来说,这是一个不好的想法。上面的例子实际上使用了process方法来更新UI,在EDT中被调用。 - MadProgrammer

6

2
SwingWorker<Xxx, Xxx>的设置方法最好在这里回答。 - mKorbel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接