java swingworker线程更新main Gui

Posted

技术标签:

【中文标题】java swingworker线程更新main Gui【英文标题】:java swingworker thread to update main Gui 【发布时间】:2013-06-05 10:52:03 【问题描述】:

嗨,我想知道从 swingworkerthread 向 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.");



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

【问题讨论】:

The javadoc 有一个这样做的例子:PrimeNumbersTask。 【参考方案1】:

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

看看publish和process

基本意图是您只需要在事件调度线程内更新 UI,通过 publish 方法将要更新的数据传递给 UI,SwingWorker 将为您调用 process在 EDT 的范围内

【讨论】:

不知道你为什么拒绝我的编辑。现在return numbers;doInBackground之外,protected void process(..) ..PrimeNumbersTask类之外 我在JavaDoc for get() 中读到get() 将冻结GUI / EDT。这会是一个问题吗?我还读到,人们通常会更改done() 并在其中使用get() 以避免冻结。 JavaDoc 页面中的示例没有直接解决冻结问题,因此当有人复制示例时可能会忽略这一点。 @hamena314 一般来说,是的,这是个坏主意。上面的例子其实是用process方法更新ui,在EDT内部调用【参考方案2】:

doInBackground()内,使用publish(V... chunks)process(List&lt;V&gt; chunks)发送数据。

见How SwingWorker works。

【讨论】:

并解释如何设置 SwingWorker 可能是最好的答案

以上是关于java swingworker线程更新main Gui的主要内容,如果未能解决你的问题,请参考以下文章

java遇到的问题及解答

使用Java快速实现进度条

java - JLabel setForeground 在 SwingWorker 中不起作用

发布/处理使 SwingWorker 变慢

Java中的SwingWorker [关闭]

JavaFX SwingWorker 等价物?