Jump to content

Поток диспетчеризации событий

(Перенаправлено из темы отправки событий )

Поток диспетчеризации событий (EDT) — это фоновый поток, используемый в Java для обработки событий из Abstract Window Toolkit (AWT) графического пользовательского интерфейса очереди событий . Это пример общей концепции событийно-ориентированного программирования , которая популярна во многих других контекстах, помимо Java, например, в веб-браузерах или веб-серверах .

События в основном представляют собой события обновления, которые заставляют компоненты пользовательского интерфейса перерисовываться, или события ввода с устройств ввода, таких как мышь или клавиатура. AWT использует однопоточную модель рисования , в которой все обновления экрана должны выполняться из одного потока. Поток диспетчеризации событий — единственный допустимый поток, обновляющий визуальное состояние видимых компонентов пользовательского интерфейса. Обновление видимых компонентов из других потоков является источником многих распространенных ошибок в программах Java , использующих Swing . [1] Поток диспетчеризации событий называется первичным рабочим в Adobe Flash и потоком пользовательского интерфейса в SWT , .NET Framework и Android .

Цикл сообщений для сериализации обращений к графическому интерфейсу

[ редактировать ]

Программное приложение обычно состоит из нескольких потоков и одной структуры данных GIT. Это означает, что GIT — это общая структура данных, и необходима некоторая синхронизация, чтобы гарантировать, что только один поток имеет доступ к ней одновременно. Хотя AWT и Swing предоставляют методы ( небезопасные для потоков ) для создания и доступа к компонентам графического пользовательского интерфейса, и эти методы видны всем потокам приложений, как и в других средах графического пользовательского интерфейса, только один поток диспетчеризации событий имеет право выполнять эти методы. [2] [3] [4] Поскольку программисты часто пропускают это требование, сторонние Look and Feels , такие как Substance, доходят до того, что отказываются создавать экземпляры любого компонента Swing, когда он не работает в потоке диспетчеризации событий. [5] чтобы предотвратить такую ​​ошибку кодирования. Доступ к графическому интерфейсу сериализуется, и другие потоки могут отправлять некоторый код для выполнения в EDT через очередь сообщений EDT .

То есть, как и в других средах графического пользовательского интерфейса, поток диспетчеризации событий тратит свою жизнь на перекачку сообщений: он поддерживает очередь сообщений о действиях, которые необходимо выполнить через графический интерфейс. Эти запросы отправляются в очередь системой и любым потоком приложения. EDT использует их один за другим и в ответ обновляет компоненты графического интерфейса. Сообщения могут представлять собой известные действия или включать обратные вызовы, ссылки на пользовательские методы, которые должны быть выполнены с помощью EDT.

Важным требованием, предъявляемым ко всем сообщениям, является то, что они должны выполняться быстро, чтобы графический интерфейс оставался отзывчивым. В противном случае цикл сообщений блокируется и происходит зависание графического интерфейса.

Отправка кода пользователя в EDT

[ редактировать ]

Существуют различные решения для отправки кода в EDT и выполнения длительных задач без блокировки цикла.

Обработчики событий компонентов (прослушиватели)

[ редактировать ]

Компоненты графического пользовательского интерфейса поддерживают списки обратных вызовов, называемые прослушивателями, которые обычно заполняются при создании компонентов. EDT запускает прослушиватели, когда пользователь каким-либо образом возбуждает компоненты (нажимается кнопка, перемещается мышь, выбирается элемент, теряется фокус, изменяется размер компонента и т. д.).

Для коротких задач, которые требуют доступа к графическому интерфейсу пользователя или его изменения периодически или в определенное время, javax.swing.Timer используется. Его можно рассматривать как невидимый компонент графического интерфейса, прослушиватели которого зарегистрированы для срабатывания в определенное время.

Эквиваленты

Запросы из других тем

[ редактировать ]

Другие потоки приложения могут передавать некоторый код для выполнения в потоке диспетчеризации событий с помощью SwingUtilities вспомогательные классы (или EventQueue если вы используете AWT ). Отправленный код должен быть обернут тегом Runnable объект. Два метода этих классов позволяют:

из потока диспетчеризации событий.

Метод invokeAndWait() никогда не следует вызывать из потока диспетчеризации событий — он выдаст исключение . Метод SwingUtilities.isEventDispatchThread() или EventQueue.isDispatchThread() может быть вызван, чтобы определить, является ли текущий поток потоком диспетчеризации событий.

Код, предоставленный с помощью invokeLater и invokeAndWait до EDT должно быть как можно быстрее, чтобы не допустить замерзания. Обычно они предназначены для доставки результатов длительных вычислений в графический интерфейс пользователя (пользователя).

Шаблон проектирования работника

[ редактировать ]

Как выполнение задачи в другом потоке, так и представление результатов в EDT можно совместить с помощью шаблона проектирования Worker . javax.swing.SwingWorker Класс, разработанный Sun Microsystems , представляет собой реализацию шаблона проектирования Worker и, начиная с Java 6, является частью стандартного дистрибутива Swing. SwingWorker обычно вызывается из прослушивателя событий, исполняемых EDT, для выполнения длительной задачи, чтобы не блокировать EDT.

SwingWorker<Document, Void> worker = new SwingWorker<Document, Void>() {
    public Document doInBackground() throws IOException {
        return loadXML(); // heavy task
    }
    
    public void done() {
        try {
            Document doc = get();
            display(doc);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
};
worker.execute();

Если вы используете Groovy и groovy.swing.SwingBuilder, вы можете использовать doLater(), doOutside(), и edt(). Тогда можно написать проще так:

doOutside {
    def doc = loadXML() // heavy task
    edt { display(doc) }
}

Эквиваленты

[ редактировать ]
[ редактировать ]

SwingWorker обычно создается EDT для длительных задач при обработке событий обратного вызова (прослушивателя). Создавая рабочий поток, EDT продолжает обработку текущего сообщения, не дожидаясь завершения рабочего потока. Часто это нежелательно.

Часто ваш EDT обрабатывает действие компонента графического пользовательского интерфейса, которое требует от пользователя сделать выбор с помощью другого диалогового окна, такого как JFileChooser, которое появляется, остается отзывчивым, пока пользователь выбирает свой вариант, и действие продолжается с выбранным файлом только после кнопки «ОК». нажимается. Видите ли, это требует времени (пользователь отвечает в течение нескольких секунд), и вам нужен отзывчивый графический интерфейс (сообщения все еще перекачиваются в EDT) в течение всего этого времени, пока EDT блокируется (он не обрабатывает новые сообщения, например JFileChooser, в очередь до закрытия диалогового окна и завершения текущего действия компонента). Порочный круг разрывается посредством входа EDT в новый цикл сообщений, который отправляет сообщения как обычно до тех пор, пока не придет «модальный диалог завершится» и нормальная обработка сообщения не возобновится с заблокированной позиции в действии компонента.

с открытым исходным кодом Проект Foxtrot эмулирует перекачку цикла сообщений Swing, чтобы обеспечить «синхронный» механизм выполнения произвольных пользовательских задач, который продолжается только после того, как работник завершит задачу.

  button.addActionListener(new ActionListener()
  {
	 public void actionPerformed(ActionEvent e)
	 {
		button.setText("Sleeping...");

		String text = null;
		try
		{
		   text = (String)Worker.post(new Task()
		   {
			  public Object run() throws Exception
			  {
				 Thread.sleep(10000);
				 return "Slept !";
			  }
		   });
		}
		catch (Exception x) ...

		button.setText(text);

		somethingElse();
	 }
  });

Начиная с Java 1.7, Java предоставляет стандартное решение для пользовательских циклов вторичных сообщений , предоставляя createSecondaryLoop () в системной EventQueue ().

См. также

[ редактировать ]
  1. ^ Эта проблема характерна не только для Java Swing . Та же проблема существует в большинстве наборов инструментов Widget , например, в Windows Forms , где класс BackgroundWorker выполняет ту же цель, что и SwingWorker в Java.
  2. ^ «Тема отправки событий» . Сан Микросистемс . Проверено 2 октября 2011 г.
  3. ^ «Отладка Swing — это действительно сложно?» . Александр Поточкин. Архивировано из оригинала 5 августа 2011 г. Проверено 2 октября 2011 г.
  4. ^ «Первоначальные темы» . Сан Микросистемс . Проверено 2 октября 2011 г.
  5. ^ «Более строгие проверки нарушений EDT в Substance · Pushing Pixels» .
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 0cb4d4bfd640505f37c93bbecd376b5e__1711259580
URL1:https://arc.ask3.ru/arc/aa/0c/5e/0cb4d4bfd640505f37c93bbecd376b5e.html
Заголовок, (Title) документа по адресу, URL1:
Event dispatching thread - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)