Java Swingworker陆续更新GUI

标签 java swing swingworker

我正在使用一些多线程应用程序开发java swing。情况是这样的,我需要一个又一个地执行线程,即我的一个输出与第二个线程相关。我做了以下事情。

// Class one
public class Samp implements Runnable{
    public Samp(String name) {
       this.setName = name;
    }
    public void run (){
      // Here I have a file extraction method called
      extract(this.getName);
    }

   // Extract Method
   public Boolean extract(String filename){
     // Some extraction Operation.
     // I want to update the jTextField with the current filename under     extraction.
   }
}

//GUI 类

public class Welcome extends javax.swing.JFrame {
   SwingWorker<Boolean, Void>worker =  new SwingWorker<Boolean, Void>() {
        @Override
        protected Boolean doInBackground() throws Exception {
            Thread t1 = new Thread(new ZipUtility(fileName));
            t1.start();
            return true;
        }

        // Can safely update the GUI from this method.
        @Override
        protected void done() {
            // Here when this worker is done I wanted to Run worker 2
        }
    };

    SwingWorker<Boolean, Void>worker2 = .........

   // Again when worker2 is done I wanted to run worker 3 and so on.    
 }

我的问题是:

1) 如何以完美的顺序运行所有工作人员。即当worker1完成后启动worker 2,当worker2完成后启动worker 3,依此类推。

2) 如何使用 Samp 类中的值更新我的 Welcome 类中的文本字段。

提前致谢。

最佳答案

1) How to run all the workers in a perfect sequencial order. i.e when worker1 is done then start worker 2, when worker2 is done then start worker 3 and so on.

要记住一个小技巧,您可以将 SwingWorker 放入 ExecutorService

所以,使用类似...

public static class Worker extends SwingWorker {

    private int sequence;

    public Worker(int sequence) {
        this.sequence = sequence;
    }

    @Override
    protected Object doInBackground() throws Exception {
        System.out.println(sequence + "...");
        Thread.sleep(500);
        return null;
    }

}

作为测试,您可以使用类似...

ExecutorService es = Executors.newFixedThreadPool(1);
for (int index = 0; index < 10; index++) {
    es.submit(new Worker(index));
}
es.shutdown();

(您不需要调用shutdown,但否则我的测试从未允许 JVM 终止;))

它将按照提交的顺序运行工作人员。

现在,如果您想将值从一个 SwingWorker 提供给另一个,您可以执行以下操作...

public abstract class ChainedWorker<T, V> extends SwingWorker<T, V> {

    private ChainedWorker<T, ?> next;
    private T previousValue;

    public ChainedWorker(ChainedWorker<T, ?> next) {
        this.next = next;
    }

    public void setPreviousValue(T previousValue) {
        this.previousValue = previousValue;
    }

    @Override
    protected void done() {
        try {
            T previous = get();
            if (next != null) {
                next.setPreviousValue(previous);
                next.execute();
            }
        } catch (InterruptedException | ExecutionException ex) {
            ex.printStackTrace();
        }
    }

}

这只是一个 SwingWorker,它允许您在链中提供一个链接(下一个要调用的工作程序),该链接传递此 SwingWorker 生成的值。 .或者一些类似的

现在,如果你真的很疯狂并且想扮演自己的角色,也许像......

public class ChainedWorkerBuilder {

    private List<SwingWorker> workers;
    private SwingWorker current;

    public ChainedWorkerBuilder() {
        workers = new ArrayList<>(25);
    }

    public ChainedWorkerBuilder add(SwingWorker worker) {
        workers.add(worker);
        return this;
    }

    public void execute() {
        if (!workers.isEmpty()) {
            SwingWorker worker = workers.remove(0);
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("state".equals(evt.getPropertyName())) {
                        SwingWorker source = (SwingWorker)evt.getSource();
                        switch (source.getState()) {
                            case DONE:
                                source.removePropertyChangeListener(this);
                                execute();
                                break;
                        }
                    }
                }
            });
        }
    }

}

2) How to update a textfield in my Welcome class, with the values from the Samp class.

我不认为我直接遵循你的代码,但是,如果你做了类似的事情......

SwingWorker<Boolean, Void>worker =  new SwingWorker<Boolean, String>() {

    protected Boolean doInBackground() throws Exception {
        publish(fileName);
        ZipUtility zu = new ZipUtility(fileName));
        return zu.extract(fileName);
    }

然后在 SwingWorkerprocess 方法中,您将能够安全地更新 UI...

    @Override
    protected void process(List<String> chunks) {
        // Grab the last element...
        textfield.setText(chunks.get(chunks.size() - 1));
    }
}

关于Java Swingworker陆续更新GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31580805/

相关文章:

java - 为什么不能同时使用 Mock 和 InjectMocks?

java - 为什么 JPopupMenu 中的 JLabel 不尊重其外观和感觉?

java - 如何用 Java 制作响应式 MVP Swing GUI?

java - Swingworker.done() 在完成后卡住 GUI 几秒钟

java - 在java中加载 Sprite 图像

java - 将二进制字符串转换为十六进制字符串JAVA

java - 重做 foreach 到 .stream().map

java - 如何让 JLabel 文字显示 1 秒?

Java Swing 摆脱 Null 布局

java - 更新 Swing 组件,同时阻止 GUI