簡體   English   中英

Java Swingworker接連更新GUI

[英]Java Swingworker one after another and update GUI

我正在使用一些多線程應用程序進行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)如何以完美的順序運行所有工人。 即,當worker1完成后,再啟動worker 2,當worker2完成后,再啟動worker 3,依此類推。

記住一點小技巧,您可以將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)如何使用Samp類中的值更新我的Welcome類中的文本字段。

我不認為我會直接遵循您的代碼,但是,如果您做了類似的事情……

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));
    }
}

只需從worker1的完成對worker2調用execute()

final SwingWorker<Boolean, Void> worker2 =  new SwingWorker<Boolean, Void>() {
   ...
}

final SwingWorker<Boolean, Void> worker1 =  new SwingWorker<Boolean, Void>() {
    @Override
    protected Boolean doInBackground() throws Exception {
        // Don't start a thread, do your work, otherwise the done will fire
        // too early, also it's pointless to use worker and thread like that
        return true;
    }

    // Can safely update the GUI from this method.
    @Override
    protected void done() {
        // update some ui
        // and start the second part
        worker2.execute();
    }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM