blob: 6fd97e76bd4e348815ff6474985bd4118af93d9b [file] [log] [blame]
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
/**
* A helper interface to run the nested event loop.
* <p>
* Objects that implement this interface are created with the
* {@link EventQueue#createSecondaryLoop} method. The interface
* provides two methods, {@link #enter} and {@link #exit},
* which can be used to start and stop the event loop.
* <p>
* When the {@link #enter} method is called, the current
* thread is blocked until the loop is terminated by the
* {@link #exit} method. Also, a new event loop is started
* on the event dispatch thread, which may or may not be
* the current thread. The loop can be terminated on any
* thread by calling its {@link #exit} method. After the
* loop is terminated, the {@code SecondaryLoop} object can
* be reused to run a new nested event loop.
* <p>
* A typical use case of applying this interface is AWT
* and Swing modal dialogs. When a modal dialog is shown on
* the event dispatch thread, it enters a new secondary loop.
* Later, when the dialog is hidden or disposed, it exits
* the loop, and the thread continues its execution.
* <p>
* The following example illustrates a simple use case of
* secondary loops:
*
* <pre>
* SecondaryLoop loop;
*
* JButton jButton = new JButton("Button");
* jButton.addActionListener(new ActionListener() {
* {@code @Override}
* public void actionPerformed(ActionEvent e) {
* Toolkit tk = Toolkit.getDefaultToolkit();
* EventQueue eq = tk.getSystemEventQueue();
* loop = eq.createSecondaryLoop();
*
* // Spawn a new thread to do the work
* Thread worker = new WorkerThread();
* worker.start();
*
* // Enter the loop to block the current event
* // handler, but leave UI responsive
* if (!loop.enter()) {
* // Report an error
* }
* }
* });
*
* class WorkerThread extends Thread {
* {@code @Override}
* public void run() {
* // Perform calculations
* doSomethingUseful();
*
* // Exit the loop
* loop.exit();
* }
* }
* </pre>
*
* @see Dialog#show
* @see EventQueue#createSecondaryLoop
* @see Toolkit#getSystemEventQueue
*
* @author Anton Tarasov, Artem Ananiev
*
* @since 1.7
*/
public interface SecondaryLoop {
/**
* Blocks the execution of the current thread and enters a new
* secondary event loop on the event dispatch thread.
* <p>
* This method can be called by any thread including the event
* dispatch thread. This thread will be blocked until the {@link
* #exit} method is called or the loop is terminated. A new
* secondary loop will be created on the event dispatch thread
* for dispatching events in either case.
* <p>
* This method can only start one new event loop at a time per
* object. If a secondary event loop has already been started
* by this object and is currently still running, this method
* returns {@code false} to indicate that it was not successful
* in starting a new event loop. Otherwise, this method blocks
* the calling thread and later returns {@code true} when the
* new event loop is terminated. At such time, this object can
* again be used to start another new event loop.
*
* @return {@code true} after termination of the secondary loop,
* if the secondary loop was started by this call,
* {@code false} otherwise
*/
public boolean enter();
/**
* Unblocks the execution of the thread blocked by the {@link
* #enter} method and exits the secondary loop.
* <p>
* This method resumes the thread that called the {@link #enter}
* method and exits the secondary loop that was created when
* the {@link #enter} method was invoked.
* <p>
* Note that if any other secondary loop is started while this
* loop is running, the blocked thread will not resume execution
* until the nested loop is terminated.
* <p>
* If this secondary loop has not been started with the {@link
* #enter} method, or this secondary loop has already finished
* with the {@link #exit} method, this method returns {@code
* false}, otherwise {@code true} is returned.
*
* @return {@code true} if this loop was previously started and
* has not yet been finished with the {@link #exit} method,
* {@code false} otherwise
*/
public boolean exit();
}