Выполнять SwingWorker за другой (Синхронизировать SwingWorker) - PullRequest
0 голосов
/ 15 октября 2018

Я хочу запустить SwingWorker после завершения другого.Мои 2 потока находятся в разных методах одного и того же класса, и я хочу использовать их по порядку из другого класса, например:

int x = runn.runProcessStart();
int y = runn. runProcessEnd();

РАБОЧИЙ КЛАСС

public class MyClass {

    private int counter = 0;

    public int runProcessStart() {
        int result = 0;

        SwingWorker<Integer, String> worker = new SwingWorker<Integer, String>() {
            @Override
            protected Integer doInBackground() throws Exception {
                for (int i = 0; i < 10; i++) {
                    publish("start message number " + counter++);
                    Thread.sleep(500);
                }

                return 0;
            }

            @Override
            protected void process(List<String> chunks) {
                // this is called on the Swing event thread
                for (String text : chunks) {
                    Sysem.out.println(text);
                }
            }
        };

        worker.execute();

        if (worker.getState() == SwingWorker.StateValue.DONE) {
            try {
                result = worker.get();
            } catch (ExecutionException | InterruptedException ex) {
                Sysem.out.println(ex.getMEssage());
            }

        }

        return result;
    }

    public int runProcessEnd() {
        int result = 0;

        SwingWorker<Integer, String> worker = new SwingWorker<Integer, String>() {
            @Override
            protected Integer doInBackground() throws Exception {
                for (int i = 0; i < 10; i++) {
                    publish("end message number " + counter++);
                    Thread.sleep(500);
                }

                return 0;
            }

            @Override
            protected void process(List<String> chunks) {
                // this is called on the Swing event thread
                for (String text : chunks) {
                    Sysem.out.println(text);
                }
            }
        };

        worker.execute();

        if (worker.getState() == SwingWorker.StateValue.DONE) {
            try {
                result = worker.get();
            } catch (ExecutionException | InterruptedException ex) {
                Sysem.out.println(ex.getMEssage());
            }

        }

        return result;
    }

}

Как я могу это сделатьthis?

Другой вопрос ... правильно ли я использую .get () для получения значения процесса doInBackground?

1 Ответ

0 голосов
/ 16 октября 2018

Используйте SwingWorker # done метод, как показано в следующем mcve:

import java.awt.BorderLayout;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingWorker;

public class MyClass {

    private int counter = 0;
    private JLabel showCounter;
    private JButton start;

    public MyClass() {

        JFrame window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        start = new JButton("Start");
        start.addActionListener(e -> runProcessStart());
        window.add(start, BorderLayout.PAGE_START);

        showCounter = new JLabel(String.valueOf("Click button to start" ));
        window.add(showCounter, BorderLayout.PAGE_END);
        window.pack();
        window.setVisible(true);
    }

    public void runProcessStart() {

        start.setEnabled(false);

        SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
            @Override
            protected Void doInBackground() throws Exception {
                for (int i = 0; i < 10; i++) {
                    publish(counter++);
                    Thread.sleep(2000);
                }

                return null;
            }

            @Override
            protected void process(List<Integer> chunks) {
                for (int i : chunks) {
                    showCounter.setText("Process Start running "+ i);
                }
            }

            @Override
            protected void done() {
                showCounter.setText("Process Start finished");
                runProcessEnd();
            }
        };

        worker.execute();
    }

    public void runProcessEnd() {

        SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
            @Override
            protected Void doInBackground() throws Exception {
                for (int i = 0; i < 10; i++) {
                    Thread.sleep(2000);
                    publish(counter--);
                }

                return null;
            }

            @Override
            protected void process(List<Integer> chunks) {

                 for (int i : chunks) {
                     showCounter.setText("Process End running "+ i);
                 }
            }

            @Override
            protected void done() {
                start.setEnabled(true);
                showCounter.setText("All done");
            }
        };

        worker.execute();
    }

    public static void main(String[] args) {
        new MyClass();
    }
}

Обратите внимание, что значения, возвращаемые

int x = runn.runProcessStart();
int y = runn.runProcessEnd();

в вашем коде, являютсявероятно, не то, что вы ожидаете, потому что runProcessStart() и runProcessEnd() возвращаются до того, как SwingWorker закончится.

...