Подтвердить что ты не робот

Как использовать SwingWorker в Java?

Связано с моим предыдущим вопросом: переименовать вызов из другого класса на Java?

Я новичок в Java, и я ознакомился с некоторыми учебниками по SwingWorker. Тем не менее, я не уверен, как реализовать его с примером кода, который я дал в предыдущем вопросе.

Может кто-нибудь объяснить, как использовать SwingWorker в отношении моего фрагмента кода и/или указать мне на достойный учебник? Я посмотрел, но я не уверен, что понимаю.

4b9b3361

Ответ 1

Как правило, SwingWorker используется для выполнения длительных задач в Swing.

Выполнение длительных задач в потоке отправки событий (EDT) может привести к блокировке GUI, поэтому одна из вещей, которые были сделаны, - это использовать SwingUtilities.invokeLater и invokeAndWait, который поддерживает графический интерфейс, который определяет приоритеты других событий AWT перед запуском нужной задачи (в форма a Runnable).

Однако проблема с SwingUtilities заключается в том, что она не позволяла возвращать данные из выполненного Runnable в исходный метод. Это то, что SwingWorker предназначено для адресации.

В учебнике Java есть раздел SwingWorker.

Здесь пример, когда a SwingWorker используется для выполнения трудоемкой задачи в отдельном потоке и отображает окно сообщения через секунду с ответом.

Прежде всего, будет создан класс SwingWorker:

class AnswerWorker extends SwingWorker<Integer, Integer>
{
    protected Integer doInBackground() throws Exception
    {
        // Do a time-consuming task.
        Thread.sleep(1000);
        return 42;
    }

    protected void done()
    {
        try
        {
            JOptionPane.showMessageDialog(f, get());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Тип возврата методов doInBackground и get задается как первый тип SwingWorker, а второй тип - тип, возвращаемый для методов publish и process, которые не используются в этом примере.

Затем, чтобы вызвать SwingWorker, вызывается метод execute. В этом примере мы подключим ActionListener к JButton, чтобы выполнить AnswerWorker:

JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
        new AnswerWorker().execute();
    }
});

Вышеприведенная кнопка может быть добавлена ​​в JFrame и нажата, чтобы получить окно сообщения через секунду. Для инициализации GUI для приложения Swing можно использовать следующее:

private void makeGUI()
{
    final JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().setLayout(new FlowLayout());

    // include: "class AnswerWorker" code here.
    // include: "JButton" b code here.

    f.getContentPane().add(b);
    f.getContentPane().add(new JButton("Nothing"));
    f.pack();
    f.setVisible(true);
}

После запуска приложения будут две кнопки. Один помечен как "Ответ!". и другое "Ничто". Когда вы нажимаете "Ответ!", сначала ничего не произойдет, но нажатие кнопки "Ничто" будет работать и продемонстрировать, что графический интерфейс реагирует.

И, через секунду, результат AnswerWorker появится в окне сообщения.

Ответ 2

Принимаю

Запуск длительных задач в потоке отправки событий (EDT) может привести к блокировке GUI.

Не соглашайтесь:

поэтому одна из вещей, которые были сделаны, - это использовать SwingUtilities.invokeLater и invokeAndWait, который поддерживает графический интерфейс.

invokeLater все еще запускает код на EDT и может заморозить ваш интерфейс! Попробуйте следующее:

SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

По крайней мере, я не могу перемещать мышь, как только я нажимаю кнопку, которая запускает actionPerformed с вышеуказанным кодом. Я что-то пропустил?