/** * Copyright (c) 2002-2005, Simone Bordet * All rights reserved. * * This software is distributable under the BSD license. * See the terms of the BSD license in the documentation provided with this software. */ package foxtrot; import foxtrot.workers.SingleWorkerThread; /** * The class that execute time-consuming {@link Task}s and {@link Job}s. <br /> * It is normally used in event listeners that must execute time-consuming operations without * freezing the Swing GUI. <br /> * Usage example (simplified from the Foxtrot examples): * <pre> * JButton button = new JButton("Take a nap!"); * button.addActionListener(new ActionListener() * { * public void actionPerformed(ActionEvent e) * { * try * { * Worker.post(new Task() * { * public Object run() throws Exception * { * Thread.sleep(10000); * return null; * } * }); * } * catch (Exception ignored) {} * } * }); * </pre> * While normally not necessary, it is possible to customize the two core components of this * class, the {@link EventPump} and the {@link WorkerThread} via the corrispondent setter * methods. <br /> * This class uses by default a WorkerThread that enqueues Tasks; Tasks will be executed one * after the other. This is the behavior needed by most applications that want to rely on a * synchronous model. For an alternative behavior, see {@link ConcurrentWorker} * @version $Revision: 1.23 $ */ public class Worker extends AbstractSyncWorker { private static Worker instance = new Worker(); /** * Cannot be instantiated, use static methods only. */ private Worker() { } /** * Returns the WorkerThread used to run {@link foxtrot.Task}s subclasses in a thread * that is not the Event Dispatch Thread. * By default, the WorkerThread will enqueue the Tasks and execute them one after the * other. * @see #setWorkerThread */ public static WorkerThread getWorkerThread() { return instance.workerThread(); } /** * Sets the WorkerThread used to run {@link foxtrot.Task}s subclasses in a thread * that is not the Event Dispatch Thread. * @see #getWorkerThread * @throws java.lang.IllegalArgumentException If workerThread is null */ public static void setWorkerThread(WorkerThread workerThread) { instance.workerThread(workerThread); } WorkerThread createDefaultWorkerThread() { return new SingleWorkerThread(); } /** * Returns the EventPump used to pump events from the AWT Event Queue. <br /> * If no calls to {@link #setEventPump} have been made a default pump is returned; * this default pump is obtained by instantiating the suitable pump for the * Java version that is running the code. * @see #setEventPump */ public static EventPump getEventPump() { return instance.eventPump(); } /** * Sets the EventPump to be used to pump events from the AWT Event Queue. <br /> * After calling this method, subsequent invocation of {@link #post(Task)} * or {@link #post(Job)} will use the newly installed EventPump. * Use with care, since implementing correcly a new EventPump is not easy. * Foxtrot's default EventPumps are normally sufficient. * @see #getEventPump * @throws IllegalArgumentException If eventPump is null */ public static void setEventPump(EventPump eventPump) { instance.eventPump(eventPump); } /** * Enqueues the given Task to be executed by the WorkerThread, while dequeueing * AWT events. <br /> * If this method is called from the Event Dispatch Thread, it blocks until the task * has been executed, either by finishing normally or throwing an exception. <br /> * If this method is called from a worker thread, it executes the new Task * immediately in the same thread and then returns the control to the calling Task. <br /> * While Tasks are executed, AWT events are dequeued from the AWT Event Queue; * even in case of AWT events that throw RuntimeExceptions or Errors, this method will * not return until the first Task (posted from the Event Dispatch Thread) is finished. * @throws IllegalStateException if is not called from the Event Dispatch Thread nor * from a worker thread. * @see #post(Job job) */ public static Object post(Task task) throws Exception { return instance.post(task, getWorkerThread(), getEventPump()); } /** * Enqueues the given Job to be executed in the worker thread. <br /> * This method behaves exactly like {@link #post(Task task)}, but it does not throw checked exceptions. * @throws IllegalStateException if is not called from the Event Dispatch Thread nor from another Job or Task. * @see #post(Task) */ public static Object post(Job job) { return instance.post(job, getWorkerThread(), getEventPump()); } }