To help us in ensuring that all our event handling code gets executed  dịch - To help us in ensuring that all our event handling code gets executed  Việt làm thế nào để nói

To help us in ensuring that all our

To help us in ensuring that all our event handling code gets executed only from within the event-dispatching thread, Swing provides a very helpful class that, among other things, allows us to add Runnable objects to the system event queue. This class is called SwingUtilities and it contains two methods that we are interested in here: invokeLater() and invokeAndWait(). The first method adds a Runnable to the system event queue and returns immediately. The second method adds a Runnable and waits for it to be dispatched, then returns after it finishes. The basic syntax of each follows:

Runnable trivialRunnable = new Runnable() {
public void run() {
doWork(); // do some work
}
};
SwingUtilities.invokeLater(trivialRunnable);

try {
Runnable trivialRunnable2 = new Runnable() {
public void run() {
doWork(); // do some work
}
};
SwingUtilities.invokeAndWait(trivialRunnable2);
}
catch (InterruptedException ie) {
System.out.println("...waiting thread interrupted!");
}
catch (InvocationTargetException ite) {
System.out.println(
"...uncaught exception within Runnable’s run()");
}

Because these Runnables are placed into the system event queue for execution within the event-dispatching thread, we should be just as careful that they execute quickly, as any other event handling code. In the above two examples, if the doWork() method did something that takes a long time (like loading a large file) we would find that the application would freeze up until the load finishes. In time-intensive cases such as this, we should use our own separate thread to maintain responsiveness.

The following code shows a typical way to build our own thread to do some time-intensive work. In order to safely update the state of any components from inside this thread, we must use invokeLater() or invokeAndWait():

Thread workHard = new Thread() {
public void run() {
doToughWork(); // do some really time-intensive work
SwingUtilities.invokeLater( new Runnable () {
public void run() {
updateComponents(); // update the state of component(s)
}
});
}
};
workHard.start();

Note: invokeLater() should be instead of invokeAndWait() whenever possible. If we do have to use invokeAndWait(), we should make sure that there are no locks (i.e.synchronized blocks) held by the calling thread that another thread might need during the operation.

This solves the problem of responsiveness, and it does dispatch component-related code to the event-dispatching thread, but it still cannot be considered completely user-friendly. Normally the user should be able to interrupt a time-intensive procedure. If we are waiting to establish a network connection, we certainly don’t want to continue waiting indefinitely if the destination no longer exists. In most circumstances the user should have the option to interrupt our thread. The following pseudocode code shows a typical way to accomplish this, where stopButton causes the thread to be interrupted, updating component state accordingly:

Thread workHarder = new Thread() {
public void run() {
doTougherWork();
SwingUtilities.invokeLater( new Runnable () {
public void run() {
updateMyComponents(); // update the state of component(s)
}
});
}
};
workHarder.start();

public void doTougherWork() {
try {
// [some sort of loop]
// ...if, at any point, this involves changing
// component state we’ll have to use invokeLater
// here because this is a separate thread.
//
// We must do at least one of the following:
// 1. Periodically check Thread.interrupted()
// 2. Periodically sleep or wait
if (Thread.interrupted()) {
throw new InterruptedException();
}
Thread.wait(1000);
}
catch (InterruptedException e) {
// let somebody know we’ve been interrupted
// ...if this involves changing component state
// we’ll have to use invokeLater here.
}
}

JButton stopButton = new JButton("Stop");
ActionListener stopListener = new ActionListener() {
public void actionPerformed(ActionEvent event) {
// interrupt the thread and let the user know the
// thread has been interrupted by disabling the
// stop button.
// ...this will occur on the regular event dispatch thread
workHarder.interrupt();
stopButton.setEnabled(false);
}
};
stopButton.addActionListener(stopListener);

Our stopButton interrupts the workHarder thread when pressed. There are two ways that doTougherWork() will know whether workHarder, the thread it is executed in, has been interrupted. If it is currently sleeping or waiting, an InterruptedException will be thrown which we can catch and process accordingly. The only other way to detect interruption is to periodically check the interrupted state by calling Thread.interrupted().

This approach is commonly used for constructing and displaying complex dialogs, I/O processes that result in component state changes (such as loading a document into a text component), intensive class loading or calculations, waiting for messages or to establish a network connection, etc.

Reference: Members of the Swing team have written a few articles about using threads with Swing, and have provided a class called SwingWorker that makes managing the type of multithreading described here more convenient. See http://java.sun.com/products/jfc/tsc/archive/tech_topics_arch/threads/threads.html

2.3.1 Special cases
There are some special cases in which we do not need to delegate code affecting the state of components to the event-dispatching thread:

1. Some methods in Swing, although few and far between, are marked as thread-safe and do not need special consideration. Some methods are thread-safe but are not marked as such: repaint(), revalidate(), and invalidate().

2. A component can be constructed and manipulated in any fashion we like, without regard for threads, as long as it has not yet been realized (i.e. its has been displayed or a repaint request has been queued). Top-level containers (JFrame, JDialog, JApplet) are realized after any of setVisible(true), show(), or pack() have been called on them. Also note that a component is considered realized as soon as it is added to a realized container.

3. When dealing with Swing applets (JApplets) all components can be constructed and manipulated without regard to threads until the start() method has been called, which occurs after the init() method.
2.3.2 How do we build our own thread-safe methods?
This is quite easy. Here is a thread-safe method template we can use to guarantee this method’s code only executes in the event-dispatching thread:

public void doThreadSafeWork() {
if (SwingUtilities.isEventDispatchThread()) {
//
// do all work here...
//
}
else {
Runnable callDoThreadSafeWork = new Runnable() {
public void run() {
doThreadSafeWork();
}
};
SwingUtilities.invokeLater(callDoThreadSafeWork);
}
}
2.3.3 How do invokeLater() and invokeAndWait() work?
class javax.swing.SystemEventQueueUtilities [package private]
When SwingUtilities receives a Runnable object through invokeLater(), it passes it immediately to the postRunnable() method of a class called SystemEventQueueUtilities. If a Runnable is received through invokeAndWait(), first the current thread is checked to make sure that it is not the event-dispatching thread. (It would be fatal to allow invokeAndWait() to be invoked from the event-dispatch thread itself!) An error is thrown if this is the case. Otherwise, we construct an Object to use as the lock on a critical section (i.e. a synchronized block). This block contains two statements. The first sends the Runnable to SystemEventQueueUtilities’ postRunnable() method, along with a reference to the lock object. The second waits on the lock object so the calling thread won’t proceed until this object is notified--hence “invoke and wait.”

The postRunnable() method first communicates with the private SystemEventQueue, an inner class of SystemEventQueueUtilities, to return a reference to the system event queue. We then wrap the Runnable in an instance of RunnableEvent, another private inner class. The RunnableEvent constructor takes a Runnable and an Object representing the lock object (null if invokeLater() was called) as parameters.

The RunnableEvent class is a subclass of AWTEvent, and defines its own static int event ID -- EVENT_ID. (Note that whenever we define our own event we are expected to use an event ID greater than the value of AWTEvent.RESERVED_ID_MAX.) RunnableEvent‘s EVENT_ID is AWTEvent.RESERVED_ID_MAX + 1000. RunnableEvent also contains a static instance of a RunnableTarget, yet another private inner class. RunnableTarget is a subclass of Component and its only purpose is to act as the source and target of RunnableEvents.

How does RunnableTarget do this? Its constructor enables events with event ID matching RunnableEvent’s ID:

enableEvents(RunnableEvent.EVENT_ID);

It also overrides Component’s protected processEvent() method to receive RunnableEvents. Inside this method it first checks to see if the event passed as parameter is in fact an instance of RunnableEvent. If it is, it is passed to SystemEventQueueUtilities’ processRunnableEvent() method (this occurs after the RunnableEvent has been dispatched from the system event queue.)

Now back to RunnableEvent. The RunnableEvent constructor calls its superclass (AWTEvent) constructor passing its static instance of RunnableTarget as the event source, and EVENT_ID as the event ID.
0/5000
Từ: -
Sang: -
Kết quả (Việt) 1: [Sao chép]
Sao chép!
To help us in ensuring that all our event handling code gets executed only from within the event-dispatching thread, Swing provides a very helpful class that, among other things, allows us to add Runnable objects to the system event queue. This class is called SwingUtilities and it contains two methods that we are interested in here: invokeLater() and invokeAndWait(). The first method adds a Runnable to the system event queue and returns immediately. The second method adds a Runnable and waits for it to be dispatched, then returns after it finishes. The basic syntax of each follows:

Runnable trivialRunnable = new Runnable() {
public void run() {
doWork(); // do some work
}
};
SwingUtilities.invokeLater(trivialRunnable);

try {
Runnable trivialRunnable2 = new Runnable() {
public void run() {
doWork(); // do some work
}
};
SwingUtilities.invokeAndWait(trivialRunnable2);
}
catch (InterruptedException ie) {
System.out.println("...waiting thread interrupted!");
}
catch (InvocationTargetException ite) {
System.out.println(
"...uncaught exception within Runnable’s run()");
}

Because these Runnables are placed into the system event queue for execution within the event-dispatching thread, we should be just as careful that they execute quickly, as any other event handling code. In the above two examples, if the doWork() method did something that takes a long time (like loading a large file) we would find that the application would freeze up until the load finishes. In time-intensive cases such as this, we should use our own separate thread to maintain responsiveness.

The following code shows a typical way to build our own thread to do some time-intensive work. In order to safely update the state of any components from inside this thread, we must use invokeLater() or invokeAndWait():

Thread workHard = new Thread() {
public void run() {
doToughWork(); // do some really time-intensive work
SwingUtilities.invokeLater( new Runnable () {
public void run() {
updateComponents(); // update the state of component(s)
}
});
}
};
workHard.start();

Note: invokeLater() should be instead of invokeAndWait() whenever possible. If we do have to use invokeAndWait(), we should make sure that there are no locks (i.e.synchronized blocks) held by the calling thread that another thread might need during the operation.

This solves the problem of responsiveness, and it does dispatch component-related code to the event-dispatching thread, but it still cannot be considered completely user-friendly. Normally the user should be able to interrupt a time-intensive procedure. If we are waiting to establish a network connection, we certainly don’t want to continue waiting indefinitely if the destination no longer exists. In most circumstances the user should have the option to interrupt our thread. The following pseudocode code shows a typical way to accomplish this, where stopButton causes the thread to be interrupted, updating component state accordingly:

Thread workHarder = new Thread() {
public void run() {
doTougherWork();
SwingUtilities.invokeLater( new Runnable () {
public void run() {
updateMyComponents(); // update the state of component(s)
}
});
}
};
workHarder.start();

public void doTougherWork() {
try {
// [some sort of loop]
// ...if, at any point, this involves changing
// component state we’ll have to use invokeLater
// here because this is a separate thread.
//
// We must do at least one of the following:
// 1. Periodically check Thread.interrupted()
// 2. Periodically sleep or wait
if (Thread.interrupted()) {
throw new InterruptedException();
}
Thread.wait(1000);
}
catch (InterruptedException e) {
// let somebody know we’ve been interrupted
// ...if this involves changing component state
// we’ll have to use invokeLater here.
}
}

JButton stopButton = new JButton("Stop");
ActionListener stopListener = new ActionListener() {
public void actionPerformed(ActionEvent event) {
// interrupt the thread and let the user know the
// thread has been interrupted by disabling the
// stop button.
// ...this will occur on the regular event dispatch thread
workHarder.interrupt();
stopButton.setEnabled(false);
}
};
stopButton.addActionListener(stopListener);

Our stopButton interrupts the workHarder thread when pressed. There are two ways that doTougherWork() will know whether workHarder, the thread it is executed in, has been interrupted. If it is currently sleeping or waiting, an InterruptedException will be thrown which we can catch and process accordingly. The only other way to detect interruption is to periodically check the interrupted state by calling Thread.interrupted().

This approach is commonly used for constructing and displaying complex dialogs, I/O processes that result in component state changes (such as loading a document into a text component), intensive class loading or calculations, waiting for messages or to establish a network connection, etc.

Reference: Members of the Swing team have written a few articles about using threads with Swing, and have provided a class called SwingWorker that makes managing the type of multithreading described here more convenient. See http://java.sun.com/products/jfc/tsc/archive/tech_topics_arch/threads/threads.html

2.3.1 Special cases
There are some special cases in which we do not need to delegate code affecting the state of components to the event-dispatching thread:

1. Some methods in Swing, although few and far between, are marked as thread-safe and do not need special consideration. Some methods are thread-safe but are not marked as such: repaint(), revalidate(), and invalidate().

2. A component can be constructed and manipulated in any fashion we like, without regard for threads, as long as it has not yet been realized (i.e. its has been displayed or a repaint request has been queued). Top-level containers (JFrame, JDialog, JApplet) are realized after any of setVisible(true), show(), or pack() have been called on them. Also note that a component is considered realized as soon as it is added to a realized container.

3. When dealing with Swing applets (JApplets) all components can be constructed and manipulated without regard to threads until the start() method has been called, which occurs after the init() method.
2.3.2 How do we build our own thread-safe methods?
This is quite easy. Here is a thread-safe method template we can use to guarantee this method’s code only executes in the event-dispatching thread:

public void doThreadSafeWork() {
if (SwingUtilities.isEventDispatchThread()) {
//
// do all work here...
//
}
else {
Runnable callDoThreadSafeWork = new Runnable() {
public void run() {
doThreadSafeWork();
}
};
SwingUtilities.invokeLater(callDoThreadSafeWork);
}
}
2.3.3 How do invokeLater() and invokeAndWait() work?
class javax.swing.SystemEventQueueUtilities [package private]
When SwingUtilities receives a Runnable object through invokeLater(), it passes it immediately to the postRunnable() method of a class called SystemEventQueueUtilities. If a Runnable is received through invokeAndWait(), first the current thread is checked to make sure that it is not the event-dispatching thread. (It would be fatal to allow invokeAndWait() to be invoked from the event-dispatch thread itself!) An error is thrown if this is the case. Otherwise, we construct an Object to use as the lock on a critical section (i.e. a synchronized block). This block contains two statements. The first sends the Runnable to SystemEventQueueUtilities’ postRunnable() method, along with a reference to the lock object. The second waits on the lock object so the calling thread won’t proceed until this object is notified--hence “invoke and wait.”

The postRunnable() method first communicates with the private SystemEventQueue, an inner class of SystemEventQueueUtilities, to return a reference to the system event queue. We then wrap the Runnable in an instance of RunnableEvent, another private inner class. The RunnableEvent constructor takes a Runnable and an Object representing the lock object (null if invokeLater() was called) as parameters.

The RunnableEvent class is a subclass of AWTEvent, and defines its own static int event ID -- EVENT_ID. (Note that whenever we define our own event we are expected to use an event ID greater than the value of AWTEvent.RESERVED_ID_MAX.) RunnableEvent‘s EVENT_ID is AWTEvent.RESERVED_ID_MAX + 1000. RunnableEvent also contains a static instance of a RunnableTarget, yet another private inner class. RunnableTarget is a subclass of Component and its only purpose is to act as the source and target of RunnableEvents.

How does RunnableTarget do this? Its constructor enables events with event ID matching RunnableEvent’s ID:

enableEvents(RunnableEvent.EVENT_ID);

It also overrides Component’s protected processEvent() method to receive RunnableEvents. Inside this method it first checks to see if the event passed as parameter is in fact an instance of RunnableEvent. If it is, it is passed to SystemEventQueueUtilities’ processRunnableEvent() method (this occurs after the RunnableEvent has been dispatched from the system event queue.)

Now back to RunnableEvent. The RunnableEvent constructor calls its superclass (AWTEvent) constructor passing its static instance of RunnableTarget as the event source, and EVENT_ID as the event ID.
đang được dịch, vui lòng đợi..
Kết quả (Việt) 2:[Sao chép]
Sao chép!
Để giúp chúng tôi trong việc đảm bảo rằng tất cả các sự kiện xử lý mã của chúng tôi được thực hiện chỉ từ bên trong event-dispatching, Swing cung cấp một lớp học rất hữu ích đó, trong số những thứ khác, cho phép chúng tôi để thêm đối tượng Runnable vào hàng đợi sự kiện hệ thống. Lớp này được gọi là SwingUtilities và nó có chứa hai phương pháp mà chúng ta quan tâm ở đây: invokeLater () và invokeAndWait (). Phương pháp đầu tiên thêm một Runnable vào hàng đợi sự kiện hệ thống và trả về ngay lập tức. Phương pháp thứ hai cho biết thêm một Runnable và đợi cho nó để được gửi đi, sau đó trở về sau khi nó kết thúc. Cú pháp cơ bản của mỗi sau: Runnable trivialRunnable = new Runnable () { public void run () { DoWork (); // Thực hiện một số công việc } }; SwingUtilities.invokeLater (trivialRunnable); try { Runnable trivialRunnable2 = new Runnable () { public void run () { DoWork (); // Thực hiện một số công việc } }; SwingUtilities.invokeAndWait (trivialRunnable2); } catch (InterruptedException ie) { System.out.println ("... chờ đợi đề gián đoạn!"); } catch (InvocationTargetException ite) { System.out. println ( "... ngoại lệ còn tự do trong vòng chạy Runnable của ()"); } Bởi vì những Runnables được đặt vào hàng đợi sự kiện hệ thống để thực hiện trong các event-dispatching, chúng ta nên được chỉ là cẩn thận rằng họ thực hiện một cách nhanh chóng, như bất kỳ khác kiện xử lý mã. Trong hai ví dụ trên, nếu DoWork () phương pháp đã làm một cái gì đó mà phải mất một thời gian dài (như tải một tập tin lớn) chúng ta sẽ thấy rằng các ứng dụng sẽ đóng băng cho đến khi kết thúc tải. Trong trường hợp thời gian thâm canh như thế này, chúng ta nên sử dụng chủ đề riêng biệt của riêng của chúng tôi để duy trì đáp ứng. Các mã sau đây cho thấy một cách điển hình để xây dựng chủ đề của riêng của chúng tôi để làm một số công việc tốn thời gian. Để cập nhật một cách an toàn trạng thái của bất kỳ thành phần từ bên trong chủ đề này, chúng ta phải sử dụng invokeLater () hoặc invokeAndWait (): chủ workHard = new Thread () { public void run () { doToughWork (); // Thực hiện một số thực sự tốn thời gian làm việc SwingUtilities.invokeLater (new Runnable () { public void run () { updateComponents (); // cập nhật trạng thái của thành phần (s) } }); } }; workHard.start () ; Lưu ý: invokeLater () nên thay vì invokeAndWait () bất cứ khi nào có thể. Nếu chúng ta phải sử dụng invokeAndWait (), chúng ta cần phải bảo đảm rằng không có ổ khóa (khối iesynchronized) được tổ chức bởi các thread kêu gọi rằng chủ đề khác có thể cần trong quá trình hoạt động. Điều này giải quyết các vấn đề của sự đáp ứng, và nó có công văn component- code liên quan đến event-dispatching, nhưng nó vẫn không thể được coi là hoàn toàn sử dụng. Thông thường người dùng sẽ có thể làm gián đoạn một thủ tục tốn thời gian. Nếu chúng ta đang chờ đợi để thiết lập kết nối mạng, chúng tôi chắc chắn không muốn tiếp tục chờ đợi vô thời hạn nếu các điểm đến không còn tồn tại. Trong hầu hết các trường hợp, người sử dụng nên có các tùy chọn để làm gián đoạn chủ đề của chúng tôi. Các mã giả sau đây cho thấy một cách điển hình để thực hiện điều này, nơi stopButton gây ra các chủ đề để bị gián đoạn, cập nhật trạng thái thành phần phù hợp: chủ workHarder = new Thread () { public void run () { doTougherWork (); SwingUtilities.invokeLater (new Runnable () { public void run () { updateMyComponents (); // cập nhật trạng thái của thành phần (s) } }); } }; workHarder.start (); public void doTougherWork () { try { // [một số loại loop] // ... nếu, tại bất kỳ điểm nào, điều này liên quan đến việc thay đổi // trạng thái thành phần chúng ta sẽ phải sử dụng invokeLater // ở đây vì đây là một chủ đề riêng biệt. // // Chúng ta phải làm ít nhất một trong các cách sau : // 1. Định kỳ kiểm tra Thread.interrupted () // 2. Định kỳ ngủ hoặc chờ if (Thread.interrupted ()) { ném InterruptedException mới (); } Thread.wait (1000); } catch (InterruptedException e) { // cho ai đó biết chúng ta đã bị gián đoạn // ... nếu điều này liên quan đến việc thay đổi trạng thái thành phần // chúng ta sẽ phải sử dụng invokeLater đây. } } JButton stopButton = new JButton ("Stop"); ActionListener stopListener = new ActionListener () { public void (sự kiện ActionEvent) actionPerformed { // ngắt lời các chủ đề và cho phép người dùng biết // Chủ đề đã bị gián đoạn bởi việc vô hiệu hóa các nút // dừng. // ... điều này sẽ xảy ra trên các văn kiện thường xuyên stopButton ngắt thread workHarder khi ép. Có hai cách mà doTougherWork () sẽ biết liệu workHarder, thread nó được thực hiện trong, đã bị gián đoạn. Nếu nó đang ngủ hay chờ đợi, một InterruptedException sẽ được ném ra mà chúng ta có thể bắt và chế biến cho phù hợp. Chỉ cách khác để phát hiện sự gián đoạn là để kiểm tra định kỳ tình trạng gián đoạn bằng cách gọi Thread.interrupted (). Phương pháp này thường được sử dụng để xây dựng và hiển thị các hộp thoại phức tạp, I / O quá trình dẫn đến sự thay đổi trạng thái thành phần (ví dụ như tải một tài liệu thành một phần văn bản), tải lớp chuyên sâu hay tính toán, chờ đợi cho các tin nhắn hoặc để thiết lập một kết nối mạng, vv tham khảo: Các thành viên của nhóm Swing đã viết một vài bài viết về việc sử dụng đề với Swing, và đã cung cấp một lớp được gọi là SwingWorker đó làm cho việc quản lý các loại hình đa luồng mô tả ở đây thuận tiện hơn. Xem http://java.sun.com/products/jfc/tsc/archive/tech_topics_arch/threads/threads.html 2.3.1 Trường hợp đặc biệt có một số trường hợp đặc biệt mà chúng ta không cần phải ủy đang ảnh hưởng đến trạng thái của các thành phần để event-dispatching: 1. Một số phương pháp trong Swing, mặc dù ít và xa giữa, được đánh dấu là thread-an toàn và không cần quan tâm đặc biệt. Một số phương pháp là thread-an toàn nhưng không được đánh dấu như vậy: repaint (), xác thực lại (), và vô hiệu (). 2. Một thành phần có thể được xây dựng và thao tác trong bất kỳ thời trang chúng tôi thích, mà không quan tâm cho chủ đề, miễn là nó vẫn chưa được thực hiện (tức là nó đã được hiển thị hoặc một yêu cầu vẽ lại đã được xếp hàng đợi). Container cấp cao (JFrame, JDialog, JApplet) được thực hiện sau khi các setVisible (true), show (), hoặc pack () đã được gọi vào chúng. Cũng lưu ý rằng một thành phần được coi là đã nhận ra ngay khi nó được đưa vào một container nhận ra. 3. Khi giao dịch với Swing applet (JApplets) tất cả các thành phần có thể được xây dựng và thao tác mà không liên quan đến chủ đề cho đến khi bắt đầu () phương pháp đã được gọi là, xảy ra sau khi các phương pháp init (). 2.3.2 Làm thế nào để chúng ta xây dựng của chúng ta thread-an toàn phương pháp? Điều này là khá dễ dàng. Dưới đây là một chủ đề an toàn phương pháp mẫu chúng ta có thể sử dụng để đảm bảo mã của phương pháp này chỉ thực hiện trong event-dispatching: public void doThreadSafeWork () { if (SwingUtilities.isEventDispatchThread ()) { // // làm tất cả công việc ở đây .. . // } else { Runnable callDoThreadSafeWork = new Runnable () { public void run () { doThreadSafeWork (); } }; SwingUtilities.invokeLater (callDoThreadSafeWork); } } 2.3.3 Làm thế nào để invokeLater () và invokeAndWait () làm việc? javax.swing.SystemEventQueueUtilities lớp [gói tin] Khi SwingUtilities nhận một đối tượng Runnable qua invokeLater (), nó vượt qua nó ngay lập tức để các postRunnable () phương thức của một lớp được gọi là SystemEventQueueUtilities. Nếu một Runnable nhận được thông qua invokeAndWait (), lần đầu tiên các chủ đề hiện tại đang kiểm tra để chắc chắn rằng nó không phải là event-dispatching. (Nó sẽ gây tử vong cho phép invokeAndWait () được gọi từ event-công văn chính nó!) Một lỗi xảy ra nếu điều này là trường hợp. Nếu không, chúng ta xây dựng một đối tượng sử dụng như là các khóa trên một phần quan trọng (ví dụ như một khối đồng bộ). Khối này chứa hai câu. Người đầu tiên gửi Runnable để SystemEventQueueUtilities 'phương pháp postRunnable (), cùng với một tham chiếu đến các đối tượng khóa. Việc chờ đợi thứ hai trên đối tượng khóa nên đang gọi sẽ không tiếp tục cho đến khi đối tượng này được thông báo - do đó "gọi và chờ đợi." The () phương pháp postRunnable đầu tiên giao tiếp với SystemEventQueue tin, một lớp bên trong của SystemEventQueueUtilities, để trả lại một tham chiếu đến hàng đợi sự kiện hệ thống. Chúng tôi sau đó quấn Runnable trong một thể hiện của RunnableEvent, một lớp bên trong nhân. Các nhà xây dựng RunnableEvent mất một Runnable và một đối tượng đại diện cho các đối tượng khóa (null nếu invokeLater () đã được gọi) là tham số. Các lớp RunnableEvent là một lớp con của AWTEvent, và định nghĩa ID static int sự kiện riêng của mình - event_id. (Lưu ý rằng bất cứ khi nào chúng ta định nghĩa sự kiện riêng của chúng tôi, chúng tôi dự kiến sẽ sử dụng một ID sự kiện lớn hơn giá trị của AWTEvent.RESERVED_ID_MAX.) Event_id RunnableEvent là AWTEvent.RESERVED_ID_MAX + 1000. RunnableEvent cũng có một trường hợp tĩnh của một RunnableTarget, nhưng một bên tin class. RunnableTarget là một lớp con của Hợp phần và mục đích duy nhất của nó là hoạt động như nguồn và mục tiêu của RunnableEvents. Làm thế nào để RunnableTarget làm điều này? Constructor của nó cho phép các sự kiện với ID sự kiện phù hợp với ID của RunnableEvent: enableEvents (RunnableEvent.EVENT_ID); Nó cũng đè processEvent bảo vệ () phương pháp của Hợp phần để nhận RunnableEvents. Bên trong phương pháp này nó kiểm tra trước để xem các sự kiện thông qua như là tham số thực chất là một thể hiện của RunnableEvent. Nếu có, nó sẽ chuyển qua SystemEventQueueUtilities 'processRunnableEvent () phương pháp (điều này xảy ra sau khi RunnableEvent đã được gửi đi từ hàng đợi sự kiện hệ thống.) Bây giờ trở lại RunnableEvent. Các nhà xây dựng RunnableEvent gọi của lớp cha (AWTEvent) constructor đi qua trường hợp tĩnh của RunnableTarget là nguồn sự kiện, và event_id như các ID sự kiện.









































































































































đang được dịch, vui lòng đợi..
 
Các ngôn ngữ khác
Hỗ trợ công cụ dịch thuật: Albania, Amharic, Anh, Armenia, Azerbaijan, Ba Lan, Ba Tư, Bantu, Basque, Belarus, Bengal, Bosnia, Bulgaria, Bồ Đào Nha, Catalan, Cebuano, Chichewa, Corsi, Creole (Haiti), Croatia, Do Thái, Estonia, Filipino, Frisia, Gael Scotland, Galicia, George, Gujarat, Hausa, Hawaii, Hindi, Hmong, Hungary, Hy Lạp, Hà Lan, Hà Lan (Nam Phi), Hàn, Iceland, Igbo, Ireland, Java, Kannada, Kazakh, Khmer, Kinyarwanda, Klingon, Kurd, Kyrgyz, Latinh, Latvia, Litva, Luxembourg, Lào, Macedonia, Malagasy, Malayalam, Malta, Maori, Marathi, Myanmar, Mã Lai, Mông Cổ, Na Uy, Nepal, Nga, Nhật, Odia (Oriya), Pashto, Pháp, Phát hiện ngôn ngữ, Phần Lan, Punjab, Quốc tế ngữ, Rumani, Samoa, Serbia, Sesotho, Shona, Sindhi, Sinhala, Slovak, Slovenia, Somali, Sunda, Swahili, Séc, Tajik, Tamil, Tatar, Telugu, Thái, Thổ Nhĩ Kỳ, Thụy Điển, Tiếng Indonesia, Tiếng Ý, Trung, Trung (Phồn thể), Turkmen, Tây Ban Nha, Ukraina, Urdu, Uyghur, Uzbek, Việt, Xứ Wales, Yiddish, Yoruba, Zulu, Đan Mạch, Đức, Ả Rập, dịch ngôn ngữ.

Copyright ©2025 I Love Translation. All reserved.

E-mail: