oid主(字符串[]参数){ invokeLater(新的Runnable(){ @凌驾 公开募捐{ System.out.println(“我从这里开始”); Runnable myCallback=new Runnable(){ @凌驾 公开募捐{ System.out.println(“这是从Runnable显示的”); } }; //将回调Runnable传递到SwingWorkerExample2的构造函数中 新SwingWorkerExample2(myCallback).displayGUI();/!!未包装在可运行的 System.out.println(“在对话框不再可见后显示”); } }); } } @抑制警告(“串行”) 类ExecuteFrame2扩展了JPanel{ 专用最终JLabel statusLabel=新JLabel(“状态:”,JLabel.CENTER); 私人最终JTextArea textArea=新JTextArea(20,30); 私有StartAction StartAction=新StartAction(“开始”,KeyEvent.VK_S); 私有StopAction StopAction=新的StopAction(“Stop”,KeyEvent.VK\T); 私有JProgressBar=新JProgressBar(); 私人背景任务背景任务; 私人身份; 公共执行机构名称2(){ setBorder(BorderFactory.createEmptyByOrder(5,5,5,5)); setLayout(新边界布局(5,5)); textArea.setFocusable(false); JScrollPane sp=新的JScrollPane(); sp.setboorder(BorderFactory.createTitledBorder(“输出:”); sp.setViewportView(文本区域); stopAction.setEnabled(假); JPanel buttonPanel=新的JPanel(); 添加(新JButton(startAction)); 添加(新的JButton(停止操作)); 按钮面板。添加(条); 添加(statusLabel,BorderLayout.PAGE_START); 添加(sp,BorderLayout.CENTER); 添加(按钮面板,边框布局。页面\结尾); } 公共无效启动进程(){ if(backgroundTask!=null&&!backgroundTask.isDone()){ return;//后台任务尚未完成 } textArea.setText(“”); startAction.setEnabled(错误); stopAction.setEnabled(真); backgroundTask=新的backgroundTask(); addPropertyChangeListener(新的BGTaskListener()); backgroundTask.execute(); bar.setUndeterminate(真); } 公共流程(){ if(backgroundTask!=null&&!backgroundTask.isDone()){ backgroundTask.cancel(true); } } public void processStopped(){ statusLabel.setText((backgroundTask.getState()).toString()+“”+processStatus); stopAction.setEnabled(假); startAction.setEnabled(真); bar.setUndeterminate(假); //Window thisWindow=SwingUtilities.GetWindow祖先(textArea); //thisWindow.dispose(); } public int getProcessStatus(){ 返回进程状态; } 公共类BGTaskListener实现PropertyChangeListener{ @凌驾 公共作废属性更改(属性更改事件evt){ if(evt.getNewValue()==SwingWorker.StateValue.DONE){ processStopped(); } //将此侦听器过滤到主JPanel的道具Chng //听众 ExecuteFrame2.this.firePropertyChange(evt.getPropertyName(),evt.getOldValue(),和, evt.getNewValue()); } } 私有类BackgroundTask扩展SwingWorker{ @凌驾 受保护的整数doInBackground()引发异常{ 列表=新的ArrayList(); 列表。添加(“ping”); 字符串名称=System.getProperty(“os.name”); if(name.startsWith(“Win”)){ 列表。添加(“-n”); }否则{ 列表。添加(“-c”); } 列表。添加(“5”); list.add(“google.com”); 试一试{ ProcessBuilder pb=新的ProcessBuilder(列表); pb.重定向错误流(真); 进程p=pb.start(); 字符串s; BufferedReader标准输出=新的BufferedReader( 新的InputStreamReader(p.getInputStream()); 而((s=stdout.readLine())!=null&&!isCancelled()){ 出版; } 如果(!isCancelled()){ processStatus=p.waitFor(); } p、 getInputStream().close(); p、 getOutputStream().close(); p、 getErrorStream().close(); p、 破坏(); }捕获(IOException | InterruptedException ex){ 例如printStackTrace(System.err); } 返回进程状态; } @凌驾 受保护的无效进程(java.util.List消息){ statusLabel.setText((this.getState()).toString()); 用于(字符串消息:消息){ textArea.append(消息+“\n”); } } } 私有类StartAction扩展了AbstractAction{ 公共StartAction(字符串名称,int助记符){ 超级(姓名); putValue(助记符键,助记符); } @凌驾 已执行的公共无效操作(操作事件e){ startProcess(); } } 私有类StopAction扩展了AbstractAction{ 公共停止操作(字符串名称,int助记符){ 超级(姓名); putValue(助记符键,助记符); } @凌驾 已执行的公共无效操作(操作事件e){ 取消进程(); } } }
最好的解决方案是向SwingWorker添加PropertyChangeListener,并在其回调方法中检查流程是否结束。这将允许您的Swing事件线程运行,并在worker完成时在Swing事件线程上通知您。您甚至可以监听工作程序的更改oid主(字符串[]参数){ invokeLater(新的Runnable(){ @凌驾 公开募捐{ System.out.println(“我从这里开始”); Runnable myCallback=new Runnable(){ @凌驾 公开募捐{ System.out.println(“这是从Runnable显示的”); } }; //将回调Runnable传递到SwingWorkerExample2的构造函数中 新SwingWorkerExample2(myCallback).displayGUI();/!!未包装在可运行的 System.out.println(“在对话框不再可见后显示”); } }); } } @抑制警告(“串行”) 类ExecuteFrame2扩展了JPanel{ 专用最终JLabel statusLabel=新JLabel(“状态:”,JLabel.CENTER); 私人最终JTextArea textArea=新JTextArea(20,30); 私有StartAction StartAction=新StartAction(“开始”,KeyEvent.VK_S); 私有StopAction StopAction=新的StopAction(“Stop”,KeyEvent.VK\T); 私有JProgressBar=新JProgressBar(); 私人背景任务背景任务; 私人身份; 公共执行机构名称2(){ setBorder(BorderFactory.createEmptyByOrder(5,5,5,5)); setLayout(新边界布局(5,5)); textArea.setFocusable(false); JScrollPane sp=新的JScrollPane(); sp.setboorder(BorderFactory.createTitledBorder(“输出:”); sp.setViewportView(文本区域); stopAction.setEnabled(假); JPanel buttonPanel=新的JPanel(); 添加(新JButton(startAction)); 添加(新的JButton(停止操作)); 按钮面板。添加(条); 添加(statusLabel,BorderLayout.PAGE_START); 添加(sp,BorderLayout.CENTER); 添加(按钮面板,边框布局。页面\结尾); } 公共无效启动进程(){ if(backgroundTask!=null&&!backgroundTask.isDone()){ return;//后台任务尚未完成 } textArea.setText(“”); startAction.setEnabled(错误); stopAction.setEnabled(真); backgroundTask=新的backgroundTask(); addPropertyChangeListener(新的BGTaskListener()); backgroundTask.execute(); bar.setUndeterminate(真); } 公共流程(){ if(backgroundTask!=null&&!backgroundTask.isDone()){ backgroundTask.cancel(true); } } public void processStopped(){ statusLabel.setText((backgroundTask.getState()).toString()+“”+processStatus); stopAction.setEnabled(假); startAction.setEnabled(真); bar.setUndeterminate(假); //Window thisWindow=SwingUtilities.GetWindow祖先(textArea); //thisWindow.dispose(); } public int getProcessStatus(){ 返回进程状态; } 公共类BGTaskListener实现PropertyChangeListener{ @凌驾 公共作废属性更改(属性更改事件evt){ if(evt.getNewValue()==SwingWorker.StateValue.DONE){ processStopped(); } //将此侦听器过滤到主JPanel的道具Chng //听众 ExecuteFrame2.this.firePropertyChange(evt.getPropertyName(),evt.getOldValue(),和, evt.getNewValue()); } } 私有类BackgroundTask扩展SwingWorker{ @凌驾 受保护的整数doInBackground()引发异常{ 列表=新的ArrayList(); 列表。添加(“ping”); 字符串名称=System.getProperty(“os.name”); if(name.startsWith(“Win”)){ 列表。添加(“-n”); }否则{ 列表。添加(“-c”); } 列表。添加(“5”); list.add(“google.com”); 试一试{ ProcessBuilder pb=新的ProcessBuilder(列表); pb.重定向错误流(真); 进程p=pb.start(); 字符串s; BufferedReader标准输出=新的BufferedReader( 新的InputStreamReader(p.getInputStream()); 而((s=stdout.readLine())!=null&&!isCancelled()){ 出版; } 如果(!isCancelled()){ processStatus=p.waitFor(); } p、 getInputStream().close(); p、 getOutputStream().close(); p、 getErrorStream().close(); p、 破坏(); }捕获(IOException | InterruptedException ex){ 例如printStackTrace(System.err); } 返回进程状态; } @凌驾 受保护的无效进程(java.util.List消息){ statusLabel.setText((this.getState()).toString()); 用于(字符串消息:消息){ textArea.append(消息+“\n”); } } } 私有类StartAction扩展了AbstractAction{ 公共StartAction(字符串名称,int助记符){ 超级(姓名); putValue(助记符键,助记符); } @凌驾 已执行的公共无效操作(操作事件e){ startProcess(); } } 私有类StopAction扩展了AbstractAction{ 公共停止操作(字符串名称,int助记符){ 超级(姓名); putValue(助记符键,助记符); } @凌驾 已执行的公共无效操作(操作事件e){ 取消进程(); } } },java,swing,class,background,swingworker,Java,Swing,Class,Background,Swingworker,最好的解决方案是向SwingWorker添加PropertyChangeListener,并在其回调方法中检查流程是否结束。这将允许您的Swing事件线程运行,并在worker完成时在Swing事件线程上通知您。您甚至可以监听工作程序的更改 p = Runtime.getRuntime().exec(command, null, new File(directory)); p.waitFor(); method1(); method2(); new SwingWorkerExample(
p = Runtime.getRuntime().exec(command, null, new File(directory));
p.waitFor();
method1();
method2();
new SwingWorkerExample().displayGUI(); //Process continues in background
method3();
while(!backgroundTask.isDone()){
//do nothing
}
public Process getProcess(){
return p;
}
backgroundTask.getProcess().waitFor();
package mcve;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.*;
/**
* @se https://stackoverflow.com/a/20603012/230513
* @see https://stackoverflow.com/a/17763395/230513
* @seehttps://stackoverflow.com/questions/20600721/
*/
public class SwingWorkerExample {
private JFrame frame;
private final JLabel statusLabel = new JLabel("Status: ", JLabel.CENTER);
private final JTextArea textArea = new JTextArea(20, 20);
private JButton startButton = new JButton("Start");
private JButton stopButton = new JButton("Stop");
private JProgressBar bar = new JProgressBar();
private BackgroundTask backgroundTask;
private final ActionListener buttonActions = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
JButton source = (JButton) ae.getSource();
if (source == startButton) {
textArea.setText(null);
startButton.setEnabled(false);
stopButton.setEnabled(true);
backgroundTask = new BackgroundTask();
backgroundTask.execute();
bar.setIndeterminate(true);
} else if (source == stopButton) {
backgroundTask.cancel(true);
backgroundTask.done();
}
}
};
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
panel.setLayout(new BorderLayout(5, 5));
JScrollPane sp = new JScrollPane();
sp.setBorder(BorderFactory.createTitledBorder("Output: "));
sp.setViewportView(textArea);
startButton.addActionListener(buttonActions);
stopButton.setEnabled(false);
stopButton.addActionListener(buttonActions);
JPanel buttonPanel = new JPanel();
buttonPanel.add(startButton);
buttonPanel.add(stopButton);
buttonPanel.add(bar);
panel.add(statusLabel, BorderLayout.PAGE_START);
panel.add(sp, BorderLayout.CENTER);
panel.add(buttonPanel, BorderLayout.PAGE_END);
frame.setContentPane(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private class BackgroundTask extends SwingWorker<Integer, String> {
private int status;
public BackgroundTask() {
statusLabel.setText((this.getState()).toString());
}
@Override
protected Integer doInBackground() {
try {
ProcessBuilder pb = new ProcessBuilder("ping", "-c", "5","google.com");//change -c for -n in windows
pb.redirectErrorStream(true);
Process p = pb.start();
String s;
BufferedReader stdout = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((s = stdout.readLine()) != null && !isCancelled()) {
publish(s);
}
if (!isCancelled()) {
status = p.waitFor();
}
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
p.destroy();
} catch (IOException | InterruptedException ex) {
ex.printStackTrace(System.err);
}
return status;
}
@Override
protected void process(java.util.List<String> messages) {
statusLabel.setText((this.getState()).toString());
for (String message : messages) {
textArea.append(message + "\n");
}
}
@Override
protected void done() {
statusLabel.setText((this.getState()).toString() + " " + status);
stopButton.setEnabled(false);
startButton.setEnabled(true);
bar.setIndeterminate(false);
frame.dispose();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Here I start");
new SwingWorkerExample().displayGUI();
System.out.println("I'll show up when the SwingWorkerExample has finnished");
}
});
}
frame.setVisible(true);
bar.setIndeterminate(true);
try {
ProcessBuilder pb = new ProcessBuilder("ping", "-c", "20", "google.com");
pb.redirectErrorStream(true);
Process p;
p = pb.start();
backgroundTask = new BackgroundTask(p);
backgroundTask.execute();
p.waitFor();
} catch (IOException | InterruptedException ex) {
ex.printStackTrace(System.err);
}
package mcve;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import static javax.swing.Action.MNEMONIC_KEY;
public class SwingWorkerExample {
private JFrame frame;
private ExecuteFrame backgroundTask;
private class properyListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
// the above percolates from the SwingWorker to the containing
// JPanel
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
int processState = backgroundTask.getProcessStatus();
System.out.println("Process State: " + processState + "\n");
}
}
}
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
backgroundTask = new ExecuteFrame();
frame.add(backgroundTask);
backgroundTask.addPropertyChangeListener(new properyListener());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
backgroundTask.startProcess();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Here I start");
SwingUtilities.invokeLater(() -> new SwingWorkerExample().displayGUI());
System.out.println("I'll show up when the SwingWorkerExample has finnished");
}
});
}
}
@SuppressWarnings("serial")
class ExecuteFrame extends JPanel {
private final JLabel statusLabel = new JLabel("Status: ", JLabel.CENTER);
private final JTextArea textArea = new JTextArea(20, 30);
private StartAction startAction = new StartAction("Start", KeyEvent.VK_S);
private StopAction stopAction = new StopAction("Stop", KeyEvent.VK_T);
private JProgressBar bar = new JProgressBar();
private BackgroundTask backgroundTask;
private int processStatus;
public ExecuteFrame() {
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
textArea.setFocusable(false);
JScrollPane sp = new JScrollPane();
sp.setBorder(BorderFactory.createTitledBorder("Output: "));
sp.setViewportView(textArea);
stopAction.setEnabled(false);
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(startAction));
buttonPanel.add(new JButton(stopAction));
buttonPanel.add(bar);
add(statusLabel, BorderLayout.PAGE_START);
add(sp, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
public void startProcess() {
if (backgroundTask != null && !backgroundTask.isDone()) {
return; // background task not yet done
}
textArea.setText("");
startAction.setEnabled(false);
stopAction.setEnabled(true);
backgroundTask = new BackgroundTask();
backgroundTask.addPropertyChangeListener(new BGTaskListener());
backgroundTask.execute();
bar.setIndeterminate(true);
}
public void cancelProcess() {
if (backgroundTask != null && !backgroundTask.isDone()) {
backgroundTask.cancel(true);
}
}
public void processStopped() {
statusLabel.setText((backgroundTask.getState()).toString() + " "
+ processStatus);
stopAction.setEnabled(false);
startAction.setEnabled(true);
bar.setIndeterminate(false);
// Window thisWindow = SwingUtilities.getWindowAncestor(textArea);
// thisWindow.dispose();
}
public int getProcessStatus() {
return processStatus;
}
public class BGTaskListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
processStopped();
}
// percolate this listener up to the main JPanel's Prop Chng
// Listener
ExecuteFrame.this.firePropertyChange(evt.getPropertyName(), evt.getOldValue(),
evt.getNewValue());
}
}
private class BackgroundTask extends SwingWorker<Integer, String> {
@Override
protected Integer doInBackground() throws Exception {
List<String> list = new ArrayList<>();
list.add("ping");
String name = System.getProperty("os.name");
if (name.startsWith("Win")) {
list.add("-n");
} else {
list.add("-c");
}
list.add("5");
list.add("google.com");
try {
ProcessBuilder pb = new ProcessBuilder(list);
pb.redirectErrorStream(true);
Process p = pb.start();
String s;
BufferedReader stdout = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((s = stdout.readLine()) != null && !isCancelled()) {
publish(s);
}
if (!isCancelled()) {
processStatus = p.waitFor();
}
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
p.destroy();
} catch (IOException | InterruptedException ex) {
ex.printStackTrace(System.err);
}
return processStatus;
}
@Override
protected void process(java.util.List<String> messages) {
statusLabel.setText((this.getState()).toString());
for (String message : messages) {
textArea.append(message + "\n");
}
}
}
private class StartAction extends AbstractAction {
public StartAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
startProcess();
}
}
private class StopAction extends AbstractAction {
public StopAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
cancelProcess();
}
}
}
Here I start
I'll show up when the SwingWorkerExample has finnished
Process State: 0
Here I start
Process State: 0
I'll show up when the SwingWorkerExample has finnished
Thread t = new Thread(new Runnable(){
@Override
public void run()
{
//The stuff you want to finish first
}
}).start();
t.join();
private class TaskListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
SwingWorker task = (SwingWorker) evt.getSource();
// here we can listen for changes to the worker's progress property
// if we desire
if ("progress".equals(evt.getPropertyName())) {
int progress = task.getProgress();
progressBar.setValue(progress);
}
// listen for the worker to be done
if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
// always need to know when the SW is done
// so we can call get() and trap exceptions
try {
task.get(); // do something with the result returned?
// !! here do things that you want done when the SwingWorker has completed ***
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
MySwingWorker myWorker = new MySwingWorker();
myWorker.addPropertyChangeListener(new TaskListener());
myWorker.execute();
import java.awt.BorderLayout;
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class SwingWorkerExample2 {
private static void createAndShowGui() {
SWEx2MainPanel mainPanel = new SWEx2MainPanel();
JFrame frame = new JFrame("SwingWorker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class SWEx2MainPanel extends JPanel {
public static final ModalityType DLG_MODALITY_TYPE = ModalityType.MODELESS;
private JTextArea statusArea = new JTextArea(15, 30);
private JDialog workerDialog;
private SWEx2WorkerPanel workerPanel = new SWEx2WorkerPanel();
public SWEx2MainPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new ShowWorkerDialogAction()));
statusArea.setFocusable(false);
JScrollPane scrollPane = new JScrollPane(statusArea);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
add(scrollPane);
add(buttonPanel, BorderLayout.PAGE_END);
workerPanel.addPropertyChangeListener(new WorkerPanelListener());
}
private class WorkerPanelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
// the above percolates from the SwingWorker to the containing
// JPanel
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
int processState = workerPanel.getProcessStatus();
statusArea.append("Process State: " + processState + "\n");
}
}
}
private class ShowWorkerDialogAction extends AbstractAction {
public ShowWorkerDialogAction() {
super("Show Worker");
putValue(MNEMONIC_KEY, KeyEvent.VK_S);
}
@Override
public void actionPerformed(ActionEvent e) {
if (workerDialog == null) {
Window window = SwingUtilities.getWindowAncestor(statusArea);
workerDialog = new JDialog(window, "Worker Dialog", DLG_MODALITY_TYPE);
workerDialog.add(workerPanel);
workerDialog.pack();
workerDialog.setLocationByPlatform(true);
} else if (workerDialog.isVisible()) {
// dialog is still visible -- do nothing
return;
}
workerDialog.setVisible(true);
}
}
}
// class that holds the JPanel that does background communication
@SuppressWarnings("serial")
class SWEx2WorkerPanel extends JPanel {
private final JLabel statusLabel = new JLabel("Status: ", JLabel.CENTER);
private final JTextArea textArea = new JTextArea(20, 30);
private StartAction startAction = new StartAction("Start", KeyEvent.VK_S);
private StopAction stopAction = new StopAction("Stop", KeyEvent.VK_T);
private JProgressBar bar = new JProgressBar();
private BackgroundTask backgroundTask;
private int processStatus;
public SWEx2WorkerPanel() {
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
textArea.setFocusable(false);
JScrollPane sp = new JScrollPane();
sp.setBorder(BorderFactory.createTitledBorder("Output: "));
sp.setViewportView(textArea);
stopAction.setEnabled(false);
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(startAction));
buttonPanel.add(new JButton(stopAction));
buttonPanel.add(bar);
add(statusLabel, BorderLayout.PAGE_START);
add(sp, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
public void startProcess() {
if (backgroundTask != null && !backgroundTask.isDone()) {
return; // background task not yet done
}
textArea.setText("");
startAction.setEnabled(false);
stopAction.setEnabled(true);
backgroundTask = new BackgroundTask();
backgroundTask.addPropertyChangeListener(new BGTaskListener());
backgroundTask.execute();
bar.setIndeterminate(true);
}
public void cancelProcess() {
if (backgroundTask != null && !backgroundTask.isDone()) {
backgroundTask.cancel(true);
}
}
public void processStopped() {
statusLabel.setText((backgroundTask.getState()).toString() + " "
+ processStatus);
stopAction.setEnabled(false);
startAction.setEnabled(true);
bar.setIndeterminate(false);
// Window thisWindow = SwingUtilities.getWindowAncestor(textArea);
// thisWindow.dispose();
}
public int getProcessStatus() {
return processStatus;
}
private class BGTaskListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
processStopped();
}
// percolate this listener up to the main JPanel's Prop Chng
// Listener
SWEx2WorkerPanel.this.firePropertyChange(evt.getPropertyName(), evt.getOldValue(),
evt.getNewValue());
}
}
private class BackgroundTask extends SwingWorker<Integer, String> {
@Override
protected Integer doInBackground() throws Exception {
List<String> list = new ArrayList<>();
list.add("ping");
String name = System.getProperty("os.name");
if (name.startsWith("Win")) {
list.add("-n");
} else {
list.add("-c");
}
list.add("5");
list.add("google.com");
try {
ProcessBuilder pb = new ProcessBuilder(list);
pb.redirectErrorStream(true);
Process p = pb.start();
String s;
BufferedReader stdout = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((s = stdout.readLine()) != null && !isCancelled()) {
publish(s);
}
if (!isCancelled()) {
processStatus = p.waitFor();
}
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
p.destroy();
} catch (IOException | InterruptedException ex) {
ex.printStackTrace(System.err);
}
return processStatus;
}
@Override
protected void process(java.util.List<String> messages) {
statusLabel.setText((this.getState()).toString());
for (String message : messages) {
textArea.append(message + "\n");
}
}
}
private class StartAction extends AbstractAction {
public StartAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
startProcess();
}
}
private class StopAction extends AbstractAction {
public StopAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
cancelProcess();
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Here I start");
// note that the use of invokeLater twice is not necessary
SwingUtilities.invokeLater(() -> new SwingWorkerExample().displayGUI());
// there is nothing in the code that pauses or delays this line of code
System.out.println("I'll show up when the SwingWorkerExample has finnished");
}
});
}
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import static javax.swing.Action.MNEMONIC_KEY;
public class SwingWorkerExample2 {
private JDialog modalDialog; // !! a modal JDialog
private ExecuteFrame backgroundTask;
private Runnable myCallback; // !!
private class properyListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
int processState = backgroundTask.getProcessStatus();
System.out.println("Process State: " + processState + "\n");
// !! added
myCallback.run(); // simply run it. No need to place into a new thread
}
}
}
// !! set myCallback field. This could also be done as a parameter to
// !! the displayGUI(Runnable myCallback) method if desired
public SwingWorkerExample2(Runnable myCallback) {
this.myCallback = myCallback;
}
private void displayGUI() {
// !! create it as a modal dialog
modalDialog = new JDialog(null, "Swing Worker Example", ModalityType.APPLICATION_MODAL);
modalDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); // !!
backgroundTask = new ExecuteFrame();
modalDialog.add(backgroundTask);
backgroundTask.addPropertyChangeListener(new properyListener());
modalDialog.pack();
modalDialog.setLocationByPlatform(true);
modalDialog.setVisible(true);
backgroundTask.startProcess();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Here I start");
Runnable myCallback = new Runnable() {
@Override
public void run() {
System.out.println("This is being displayed from a Runnable");
}
};
// pass callback Runnable into SwingWorkerExample2's constructor
new SwingWorkerExample2(myCallback).displayGUI(); // !! not wrapped in a Runnable
System.out.println("This is displayed after the dialog is no longer visible");
}
});
}
}
@SuppressWarnings("serial")
class ExecuteFrame2 extends JPanel {
private final JLabel statusLabel = new JLabel("Status: ", JLabel.CENTER);
private final JTextArea textArea = new JTextArea(20, 30);
private StartAction startAction = new StartAction("Start", KeyEvent.VK_S);
private StopAction stopAction = new StopAction("Stop", KeyEvent.VK_T);
private JProgressBar bar = new JProgressBar();
private BackgroundTask backgroundTask;
private int processStatus;
public ExecuteFrame2() {
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
textArea.setFocusable(false);
JScrollPane sp = new JScrollPane();
sp.setBorder(BorderFactory.createTitledBorder("Output: "));
sp.setViewportView(textArea);
stopAction.setEnabled(false);
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(startAction));
buttonPanel.add(new JButton(stopAction));
buttonPanel.add(bar);
add(statusLabel, BorderLayout.PAGE_START);
add(sp, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
public void startProcess() {
if (backgroundTask != null && !backgroundTask.isDone()) {
return; // background task not yet done
}
textArea.setText("");
startAction.setEnabled(false);
stopAction.setEnabled(true);
backgroundTask = new BackgroundTask();
backgroundTask.addPropertyChangeListener(new BGTaskListener());
backgroundTask.execute();
bar.setIndeterminate(true);
}
public void cancelProcess() {
if (backgroundTask != null && !backgroundTask.isDone()) {
backgroundTask.cancel(true);
}
}
public void processStopped() {
statusLabel.setText((backgroundTask.getState()).toString() + " " + processStatus);
stopAction.setEnabled(false);
startAction.setEnabled(true);
bar.setIndeterminate(false);
// Window thisWindow = SwingUtilities.getWindowAncestor(textArea);
// thisWindow.dispose();
}
public int getProcessStatus() {
return processStatus;
}
public class BGTaskListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
processStopped();
}
// percolate this listener up to the main JPanel's Prop Chng
// Listener
ExecuteFrame2.this.firePropertyChange(evt.getPropertyName(), evt.getOldValue(),
evt.getNewValue());
}
}
private class BackgroundTask extends SwingWorker<Integer, String> {
@Override
protected Integer doInBackground() throws Exception {
List<String> list = new ArrayList<>();
list.add("ping");
String name = System.getProperty("os.name");
if (name.startsWith("Win")) {
list.add("-n");
} else {
list.add("-c");
}
list.add("5");
list.add("google.com");
try {
ProcessBuilder pb = new ProcessBuilder(list);
pb.redirectErrorStream(true);
Process p = pb.start();
String s;
BufferedReader stdout = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((s = stdout.readLine()) != null && !isCancelled()) {
publish(s);
}
if (!isCancelled()) {
processStatus = p.waitFor();
}
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
p.destroy();
} catch (IOException | InterruptedException ex) {
ex.printStackTrace(System.err);
}
return processStatus;
}
@Override
protected void process(java.util.List<String> messages) {
statusLabel.setText((this.getState()).toString());
for (String message : messages) {
textArea.append(message + "\n");
}
}
}
private class StartAction extends AbstractAction {
public StartAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
startProcess();
}
}
private class StopAction extends AbstractAction {
public StopAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
cancelProcess();
}
}
}