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 Class
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) 如何使用示例 class.
中的值更新我的 Welcome class 中的文本字段
提前致谢。
只需在 worker2
上调用 execute()
从 worker1
完成:
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();
}
};
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
,它允许您在链中提供一个 link(要调用的下一个工人),它传递此 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);
}
然后在 SwingWorker
s process
方法中,您将能够安全地更新 UI...
@Override
protected void process(List<String> chunks) {
// Grab the last element...
textfield.setText(chunks.get(chunks.size() - 1));
}
}
我正在 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 Class
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) 如何使用示例 class.
中的值更新我的 Welcome class 中的文本字段提前致谢。
只需在 worker2
上调用 execute()
从 worker1
完成:
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();
}
};
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
,它允许您在链中提供一个 link(要调用的下一个工人),它传递此 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);
}
然后在 SwingWorker
s process
方法中,您将能够安全地更新 UI...
@Override
protected void process(List<String> chunks) {
// Grab the last element...
textfield.setText(chunks.get(chunks.size() - 1));
}
}