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){ 取消进程(); } } }

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(

最好的解决方案是向SwingWorker添加PropertyChangeListener,并在其回调方法中检查流程是否结束。这将允许您的Swing事件线程运行,并在worker完成时在Swing事件线程上通知您。您甚至可以监听工作程序的更改
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();
        }
    }
}