Introduction to Swing EventQueue

xiaoxiao2021-03-06  15

In Swing's GUI program, EventQueue is an important part that is responsible for all AWTEVENTs (and their subclasses)

EventQueue Simple working principle

Simply, there is a DispatchThread in EventQueue. This is a thread class. It is responsible for the distribution of events. When there is an event in the queue, it will pick up the previous event and distribute the corresponding object to process, etc. Get the next one, and the thread is waiting when there is no event in the queue.

When there is an event trigger, the system calls EventQueue's PUSH method to add the AWTEVENT to EventQueue, while waking up DispatchThread.

Why is the interface will die?

So you can see that Swing's event is actually synchronized, and it is handled in the thread of DispatchThread, that is, an event is handled, if there is a very long time to process very long time Other incidents will be blocked there, from the phenomenon, it is died, if the interface is returned to the front after the interface is covered by other windows, it will turn into a gray, because Paintevent is blocked It cannot be distributed.

Why is MODAL DIALOG (FRAME) popping up the interface will not die

When the event is handled, if you pop up a Modal Dialog, then the process will stop there and wait for Modal Dialog destruction. At this time, DispatchThread will stop there, such an other event will not be distributed, Then the interface should also die. In fact, in the process of waiting for MODAL Dialog destruction, if it is possible to ensure that the event can be smoothly distributed, the interface will not die. Let's see this example first.

import javax.swing.JDialog; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.EventQueue; import java.awt.AWTEvent; import java.awt .ActiveEvent; import java.awt.event.paintevent; import java.awt.component; import java.awt.Menucomponent;

Public class test {public static void main (string [] args) {final jdialog dlg = new jdialog (); DLG.SetTitle ("test evenet queue"); jbutton btn = new jButton ("test"); DLG.GetContentPane ) .add (btn); btn.addActionListener (new ActionListener () {public void actionPerformed (ActionEvent e) {long now = System.currentTimeMillis (); EventQueue theQueue = dlg.getToolkit () getSystemEventQueue ();. System.out. println ( "at least 5000 millis"); while (System.currentTimeMillis () - now <5000l) {try {// This is essentially the body of EventDispatchThread AWTEvent event = theQueue.getNextEvent (); Object src = event.getSource ( ); If (event instanceof activity) {((ActiveEvent) .dispatch ();} else if (SRC IN stanceof Component) {((Component) src) .dispatchEvent (event);} else if (src instanceof MenuComponent) {((MenuComponent) src) .dispatchEvent (event);}} catch (Exception ex) {ex.printStackTrace () }}} System.out.println ("end");}}); DLG.PACK (); DLG.SHOW ();}}

In the above example, when the operationPerformed method is triggered, the actionPerformed method will first help the EventQueue distribute the event until a minimum of 5 seconds, then it can be seen at least 5 seconds, but During this process, Dialog can still work normally, just because in this 5 seconds are not Sleep, but in helping EventQueue distribute events, if the code is changed to thread.sleep (5000);, the interface will die.

Public class test {public static void main (string [] args) {final jdialog dlg = new jdialog (); DLG.SetTitle ("test evenet queue"); jbutton btn = new jButton ("test"); DLG.GetContentPane ) .add (btn); btn.addActionListener (new ActionListener () {public void actionPerformed (ActionEvent e) {long now = System.currentTimeMillis (); EventQueue theQueue = dlg.getToolkit () getSystemEventQueue ();. System.out. println ( "at least 5000 millis"); while (System.currentTimeMillis () - now <5000l) {try {// This is essentially the body of EventDispatchThread AWTEvent event = theQueue.getNextEvent (); Object src = event.getSource ( ); If (event instanceof activity) {((ActiveEvent) .dispatch ();} else if (SRC IN stanceof Component) {((Component) src) .dispatchEvent (event);} else if (src instanceof MenuComponent) {((MenuComponent) src) .dispatchEvent (event);}} catch (Exception ex) {ex.printStackTrace () }}} System.out.println ("end");}}); DLG.PACK (); DLG.SHOW ();}}

In the above example, when the operationPerformed method is triggered, the actionPerformed method will first help the EventQueue distribute the event until a minimum of 5 seconds, then it can be seen at least 5 seconds, but During this process, Dialog can still work normally, just because in this 5 seconds are not Sleep, but in helping EventQueue distribute events, if the code is changed to thread.sleep (5000);, the interface will die. So when MODAL DIALOG pops up, in fact, as long as it can realize the above code in the show method, ensure that the event can be distributed normally (simultaneously cut off some events of the father window, filter out some of the events that trigger an action), then the parent window The interface will not die.

What should I do if the event processing method has been done for a long time?

If the event processing method takes a long time to perform, if you need to ensure that the interface is not dead, you can only use multithreading, although the above method achieves the event processing, this is not dead, but this is different from the general event processing. The above method is actually doing anything when processing, and we generally need to have its own operation (such as accessing the database, accessing the network, reading and writing operations, etc.), it is impossible to do it. At one while processing Event distribution, only new a thread is just a forward.

Some methods about EventQueue

WINDOW.GETTOOLKIT (). GetSystemEventQueue (); get the system's EventQueue

Swingutilities.iseventdispatchthread (); current thread is EventDispatchthRead

EventQueue.push (EventQueue Queue); as an EventQueue as the current EventQueue's nextqueue, actually the event is distributed by the last EventQueue

EventQueue.getnextevent (); get the next event, if not, wait until there is another return

EventQueue.postevent (AWTEVENT theevent); Add an Event

However, many EventQueue and EventDispatchthread methods are encapsulated inside them, and they are not visible, resulting in some modifications that cannot be made, a bit uncomfortable. In addition, the AWTEVENT in EventQueue is generally for the topmost object, such as the top-level JDialog or JFrame, and then distributed to other Component by JDialog or JFrame, but I don't know how to find true owners from the AWTEVENT event, this Little is relatively depressed

转载请注明原文地址:https://www.9cbs.com/read-46726.html

New Post(0)