Рубрики

SwingWorker на Java

SwingWorker — это абстрактный класс, разработанный для библиотеки Swing языка программирования Java. Он используется для выполнения длительных задач взаимодействия с графическим интерфейсом в фоновом потоке. При разработке приложений иногда GUI зависает, когда пытается выполнить какую-то огромную или длительную задачу. Это отставание является большим узким местом. Для таких целей разработан SwingWorker, который планирует выполнение этой длительной задачи в другом потоке, в то время как графический интерфейс все еще остается отзывчивым.

Язык Java имеет три потока , а именно:

  • Текущий поток (исходный поток): это поток, в котором выполняется исходная логика приложения.
  • Поток отправки событий : весь код обработки событий выполняется в этом потоке.
  • Рабочие потоки : также известны как фоновые потоки, где выполняются все трудоемкие фоновые задачи.

SwingWorker позволяет пользователю планировать выполнение фоновой задачи в рабочем потоке. Но как пользователь узнает, когда задача закончила свое выполнение или нужно ли пользователю обновлять графический интерфейс (запущенный в начальном потоке) в соответствии с выполнением потока? Это подразумевает, что нам также нужна межпотоковая связь . SwingWorker разработан для таких сложных ситуаций, которые обеспечивают связь в потоке диспетчеризации событий.

Важные методы SwingWorker:

  1. doInBackground () : эта функция содержит нашу логику фоновой задачи, то есть то, что мы хотим, чтобы наш поток делал. Эта функция выполняется в рабочем потоке и ее необходимо реализовать.
    protected abstract T doInBackground()
                                 throws Exception
    Computes a result, or throws an exception if unable to do so. 
    This method is executed in a background thread.
    Returns:
    the computed result
    Throws:
    Exception - if unable to compute a result
  2. done () : эта функция вызывается, когда поток завершает выполнение. Также любое значение, возвращаемое функцией doInBackground (), может быть получено внутри этой функции с помощью get (). Кроме того, обновления могут быть сделаны в GUI внутри этой функции. Таким образом, функция выполняется в потоке диспетчеризации событий после завершения метода doInBackground.
    protected void done()
  3. execute () : планирует этот SwingWorker для выполнения в рабочем потоке.
    public final void execute()
  4. publish () : этот метод должен использоваться внутри метода doInBackground для доставки промежуточных результатов для обработки в потоке диспетчеризации событий внутри метода процесса.
    protected final void publish(V... chunks)
  5. process () : асинхронно получает фрагменты данных из метода публикации в потоке диспетчеризации событий. Поскольку этот метод вызывается асинхронно, publish () мог вызываться несколько раз.
    protected void process(List chunks)
    Parameters:
    chunks - intermediate results to process
  6. run (): устанавливает это будущее как результат вычисления, если оно не было отменено.
    public final void run()
  7. setProgress: устанавливает свойство выполнения прогресса. Значение должно быть от 0 до 100.
    protected final void setProgress(int progress)
    
    Example:
    setProgress(1);
    setProgress(2);
    setProgress(3);
     
    might result in a single PropertyChangeListener 
    notification with the value 3.
    Parameters:
    progress - the progress value to set
    Throws:
    IllegalArgumentException - is value not from 0 to 100
  8. getProgress: возвращает свойство, связанное с прогрессом.
    public final int getProgress()
    Returns:
    the progress bound property.
  9. отменить: Пытается отменить выполнение этого задания. Эта попытка потерпит неудачу, если задача уже завершена, уже отменена или не может быть отменена по какой-либо другой причине. Если успешно, и эта задача не была запущена при вызове отмены, эта задача никогда не должна выполняться. Если задача уже началась, параметр mayInterruptIfRunning определяет, следует ли прерывать поток, выполняющий эту задачу, в попытке остановить задачу.
    После возврата этого метода последующие вызовы Future.isDone () всегда будут возвращать true. Последующие вызовы Future.isCancelled () всегда будут возвращать true, если этот метод вернул true.
    public final boolean cancel(boolean mayInterruptIfRunning)
    Parameters:
    mayInterruptIfRunning - true if the thread executing this task 
    should be interrupted; otherwise, in-progress tasks 
    are allowed to complete
    Returns:
    false if the task could not be cancelled, typically 
    because it has already completed normally; true otherwise
  10. isCancelled: возвращает true, если эта задача была отменена до ее нормального завершения.
    public final boolean isCancelled()
    Returns:
    true if this task was cancelled before it completed
  11. isDone: возвращает true, если эта задача выполнена. Завершение может быть связано с обычным завершением, исключением или отменой — во всех этих случаях этот метод будет возвращать true.
    public final boolean isDone()
    Returns:
    true if this task completed
  12. get: При необходимости ожидает завершения вычисления, а затем извлекает его результат.
    public final T get()
                throws InterruptedException,
                       ExecutionException
  13. getState: возвращает свойство, связанное с состоянием SwingWorker.
    public final SwingWorker.StateValue getState()
    Returns:
    the current state
    

Пример для иллюстрации SwingWorker

Мы хотим, чтобы поток запускался при нажатии кнопки. Смотрите startThread () внутри слушателя действия кнопки. Функция startThread определяет нового работника качания типа javax.swing.SwingWorker, где:
T — тип результата, возвращаемый этим методом SwInWorker doInBackground и get, который является строкой в приведенном ниже коде.
V — тип, используемый для выполнения промежуточных результатов методами публикации и обработки этого SwingWorker, который представляет собой Integer в приведенном ниже коде.

// Java-программа для иллюстрации
// работа SwingWorker

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.util.List;

import java.util.concurrent.ExecutionException;

  

import javax.swing.*;

  

  

public class SwingWorkerSample 

{

      

    private static JLabel statusLabel;

    private static JFrame mainFrame;

      

    public static void swingWorkerSample () 

    {

        mainFrame = new JFrame("Swing Worker");

        mainFrame.setSize(400, 400);

        mainFrame.setLayout(new GridLayout(2,1));

          

        mainFrame.addWindowListener(new WindowAdapter() 

        {

  

            @Override

            public void windowClosing(WindowEvent e) 

            {

                System.exit(0);

            }

              

        });

          

        statusLabel = new JLabel("Not Completed", JLabel.CENTER);

        mainFrame.add(statusLabel);

          

        JButton btn = new JButton("Start counter");

        btn.setPreferredSize(new Dimension(5,5));

          

        btn.addActionListener(new ActionListener() 

        {

  

            @Override

            public void actionPerformed(ActionEvent e) 

            {

                System.out.println("Button clicked, thread started");

                startThread(); 

            }

              

        });

          

        mainFrame.add(btn);

        mainFrame.setVisible(true);

    }

      

    private static void startThread() 

    {

  

        SwingWorker sw1 = new SwingWorker() 

        {

  

            @Override

            protected String doInBackground() throws Exception 

            {

                // определить, что поток будет делать здесь

                for ( int i=10; i>=0; i-- ) 

                {

                    Thread.sleep(100);

                    System.out.println("Value in thread : " + i);

                    publish(i);

                }

                  

                String res = "Finished Execution";

                return res;

            }

  

            @Override

            protected void process(List chunks)

            {

                // определяем, что поток обработки события

                // сделаем с полученными промежуточными результатами

                // во время выполнения потока

                int val = chunks.get(chunks.size()-1);

                  

                statusLabel.setText(String.valueOf(val));

            }

  

            @Override

            protected void done() 

            {

                // этот метод вызывается, когда фон

                // поток завершает выполнение

                try 

                {

                    String statusMsg = get();

                    System.out.println("Inside done function");

                    statusLabel.setText(statusMsg);

                      

                

                catch (InterruptedException e) 

                {

                    e.printStackTrace();

                

                catch (ExecutionException e) 

                {

                    e.printStackTrace();

                }

            }

        };

          

        // выполняет рабочий качели в рабочем потоке

        sw1.execute(); 

    }

      

    public static void main(String[] args) 

    {

        swingWorkerSample();

          

    }

  
}

  1. Запустите приведенный выше код, нажмите кнопку, и вы увидите уменьшение счетчика. Одновременно делайте что-нибудь с пользовательским интерфейсом, он все равно будет отзывчивым.
  2. Список чанков является параметром функции process () и содержит список всех результатов, опубликованных потоком до этого времени типа данных Integer. Тип данных Integer должен соответствовать нашему объявлению Swingworker.

Заявка:
Создание индикатора выполнения, показывающего ход выполнения задачи.

Ссылки:
Ссылка 1
Ссылка 2

Эта статья предоставлена Ekta Goel . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

SwingWorker на Java

0.00 (0%) 0 votes