View Javadoc
1   /*
2    * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.awt;
27  
28  /**
29   * A helper interface to run the nested event loop.
30   * <p>
31   * Objects that implement this interface are created with the
32   * {@link EventQueue#createSecondaryLoop} method. The interface
33   * provides two methods, {@link #enter} and {@link #exit},
34   * which can be used to start and stop the event loop.
35   * <p>
36   * When the {@link #enter} method is called, the current
37   * thread is blocked until the loop is terminated by the
38   * {@link #exit} method. Also, a new event loop is started
39   * on the event dispatch thread, which may or may not be
40   * the current thread. The loop can be terminated on any
41   * thread by calling its {@link #exit} method. After the
42   * loop is terminated, the {@code SecondaryLoop} object can
43   * be reused to run a new nested event loop.
44   * <p>
45   * A typical use case of applying this interface is AWT
46   * and Swing modal dialogs. When a modal dialog is shown on
47   * the event dispatch thread, it enters a new secondary loop.
48   * Later, when the dialog is hidden or disposed, it exits
49   * the loop, and the thread continues its execution.
50   * <p>
51   * The following example illustrates a simple use case of
52   * secondary loops:
53   *
54   * <pre>
55   *   SecondaryLoop loop;
56   *
57   *   JButton jButton = new JButton("Button");
58   *   jButton.addActionListener(new ActionListener() {
59   *       {@code @Override}
60   *       public void actionPerformed(ActionEvent e) {
61   *           Toolkit tk = Toolkit.getDefaultToolkit();
62   *           EventQueue eq = tk.getSystemEventQueue();
63   *           loop = eq.createSecondaryLoop();
64   *
65   *           // Spawn a new thread to do the work
66   *           Thread worker = new WorkerThread();
67   *           worker.start();
68   *
69   *           // Enter the loop to block the current event
70   *           // handler, but leave UI responsive
71   *           if (!loop.enter()) {
72   *               // Report an error
73   *           }
74   *       }
75   *   });
76   *
77   *   class WorkerThread extends Thread {
78   *       {@code @Override}
79   *       public void run() {
80   *           // Perform calculations
81   *           doSomethingUseful();
82   *
83   *           // Exit the loop
84   *           loop.exit();
85   *       }
86   *   }
87   * </pre>
88   *
89   * @see Dialog#show
90   * @see EventQueue#createSecondaryLoop
91   * @see Toolkit#getSystemEventQueue
92   *
93   * @author Anton Tarasov, Artem Ananiev
94   *
95   * @since 1.7
96   */
97  public interface SecondaryLoop {
98  
99      /**
100      * Blocks the execution of the current thread and enters a new
101      * secondary event loop on the event dispatch thread.
102      * <p>
103      * This method can be called by any thread including the event
104      * dispatch thread. This thread will be blocked until the {@link
105      * #exit} method is called or the loop is terminated. A new
106      * secondary loop will be created on the event dispatch thread
107      * for dispatching events in either case.
108      * <p>
109      * This method can only start one new event loop at a time per
110      * object. If a secondary event loop has already been started
111      * by this object and is currently still running, this method
112      * returns {@code false} to indicate that it was not successful
113      * in starting a new event loop. Otherwise, this method blocks
114      * the calling thread and later returns {@code true} when the
115      * new event loop is terminated. At such time, this object can
116      * again be used to start another new event loop.
117      *
118      * @return {@code true} after termination of the secondary loop,
119      *         if the secondary loop was started by this call,
120      *         {@code false} otherwise
121      */
122     public boolean enter();
123 
124     /**
125      * Unblocks the execution of the thread blocked by the {@link
126      * #enter} method and exits the secondary loop.
127      * <p>
128      * This method resumes the thread that called the {@link #enter}
129      * method and exits the secondary loop that was created when
130      * the {@link #enter} method was invoked.
131      * <p>
132      * Note that if any other secondary loop is started while this
133      * loop is running, the blocked thread will not resume execution
134      * until the nested loop is terminated.
135      * <p>
136      * If this secondary loop has not been started with the {@link
137      * #enter} method, or this secondary loop has already finished
138      * with the {@link #exit} method, this method returns {@code
139      * false}, otherwise {@code true} is returned.
140      *
141      * @return {@code true} if this loop was previously started and
142      *         has not yet been finished with the {@link #exit} method,
143      *         {@code false} otherwise
144      */
145     public boolean exit();
146 
147 }