【问题标题】:SwingWorker publish() not working properlySwingWorker 发布()无法正常工作
【发布时间】:2021-04-17 22:08:25
【问题描述】:
public class Actualizacion extends SwingWorker<Void, String>{
    
    private final String cmd;
    private final JTextArea jTextArea1;
    
    public Actualizacion (String c, JTextArea j){
        
        cmd = c;
        jTextArea1 = j;
        
    }

    @Override
    protected Void doInBackground() throws Exception {
        Process powerShellProcess = Runtime.getRuntime().exec(cmd);
                        // Getting the results
        powerShellProcess.getOutputStream().close();
        String line;
        BufferedReader stdout = new BufferedReader(new InputStreamReader(
                powerShellProcess.getInputStream()));

        while ((line = stdout.readLine()) != null) {
            publish(line + "\n");
            //System.out.println("" + line);
        }

        stdout.close();

        BufferedReader stderr = new BufferedReader(new InputStreamReader(
                powerShellProcess.getErrorStream()));
        while ((line = stderr.readLine()) != null) {
            publish(line + "\n");
            //System.out.println("" + line);
        }
        stderr.close();
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    @Override
    protected void done(){
        
        
        publish("\nDone");
        try {
            get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        
        
    }
    
    @Override
    protected void process(List<String> lines){
        
       lines.forEach((String line) -> {
       
           jTextArea1.append(line);
       
       });
        
    }
    
}

这是我的 SwingWorker 类,它应该使用命令“cmd”的输出实时更新 jTextArea,所以正如我所说,输出应该实时写入,但它发生在命令执行结束时,并且我也有例外。

我已经阅读了很多关于线程以及 Java Swing 如何具有 EventDispatchThread 的内容,但我被卡住了。

这是程序执行的输出:


run:
java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: Not supported yet.
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at javax.swing.SwingWorker.get(SwingWorker.java:602)
    at destreamer.Actualizacion.done(Actualizacion.java:66)
    at javax.swing.SwingWorker$5.run(SwingWorker.java:737)
    at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832)
    at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
    at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842)
    at javax.swing.Timer.fireActionPerformed(Timer.java:313)
    at javax.swing.Timer$DoPostEvent.run(Timer.java:245)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.UnsupportedOperationException: Not supported yet.
    at destreamer.Actualizacion.doInBackground(Actualizacion.java:57)
    at destreamer.Actualizacion.doInBackground(Actualizacion.java:22)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:295)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at javax.swing.SwingWorker.run(SwingWorker.java:334)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

非常感谢!

【问题讨论】:

  • 可以从删除throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.这一行开始
  • 所以,SwingWorker 的特点之一是process 需要找时间运行。因此,如果您在很短的时间内多次调用publish,则不会调用process,直到有足够的延迟。您可以尝试在后处理中添加Thread.yieldThread.sleep 看看会发生什么
  • 我还推荐ProcessBuilder 而不是简单的Runtime.getRuntime().exec,它将有助于解决许多其他问题
  • readline() 方法将阻塞,直到有数据要读取。您应该在使用 System.out.println() 显示数据的同时,在文本区域中显示输出。发布 minimal reproducible example 来证明问题。
  • 好的,伙计们......我刚刚尝试“调整”@MadProgrammer 在最后一条评论中发布的最后一个示例,它可以工作。现在我想弄清楚是怎么回事哈哈哈.. 非常感谢!!!!!!!你们真是太棒了!

标签: java multithreading swing command swingworker


【解决方案1】:

这是我的问题的解决方案:

首先我将 Runtime.getRuntime().exec 更改为 ProcessBuilder

然后我意识到我在 UI 中执行了一个可怕的循环,所以这就是 Swing Worker 线程在 EventDispatchThread 之后执行的主要原因。

不要在 UI 人员内部使用疯狂循环,在我的例子中是:

while (!file.exist()){

}

我知道这个错误可能是一个基本错误,但我希望这篇文章将来可以帮助你。

感谢@MadProgrammer 和@camickr 这么快给我答复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-06
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2016-03-09
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多