KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > util > AsyncInitSupport


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.openide.util;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.event.ActionEvent JavaDoc;
24 import java.awt.event.ActionListener JavaDoc;
25 import java.awt.event.HierarchyEvent JavaDoc;
26 import java.awt.event.HierarchyListener JavaDoc;
27 import javax.swing.SwingUtilities JavaDoc;
28 import javax.swing.Timer JavaDoc;
29
30 /** Performance helper class, allows to run post-init task for given component.
31  * Can also handle cancel logic if contained in AsyncGUIJob.
32  * Class is designed for one time use, can't be used to perform async init
33  * more then once.
34  * Restrictions: Note that for correct functionality given component must not
35  * be showing at construction time of this class, however shouldn't stay hidden
36  * forever as memory leak may occur.
37  *
38  * @author Dafe Simonek
39  */

40 final class AsyncInitSupport implements HierarchyListener JavaDoc, Runnable JavaDoc, ActionListener JavaDoc {
41     /** lock for access to wasCancelled flag */
42     private static final Object JavaDoc CANCELLED_LOCK = new Object JavaDoc();
43
44     /** task in which post init code from AsyncJob is executed */
45     private Task initTask;
46
47     /** true after cancel request came, false otherwise */
48     private boolean wasCancelled;
49
50     /** Component requesting asynchronous initialization */
51     private Component JavaDoc comp4Init;
52
53     /** Job that performs async init task */
54     private AsyncGUIJob initJob;
55     
56     /** Timer for delaying asynchronous init job to enable some painting first */
57     Timer JavaDoc timer = null;
58
59     /** Creates a new instance of AsyncInitComponent
60      * @param comp4Init Component to be initialized. Mustn't be showing at this
61      * time. IllegalStateException is thrown if component is already showing.
62      * @param initJob Instance of initialization job.
63      */

64     public AsyncInitSupport(Component JavaDoc comp4Init, AsyncGUIJob initJob) {
65         this.comp4Init = comp4Init;
66         this.initJob = initJob;
67         if (comp4Init.isShowing()) {
68             throw new IllegalStateException JavaDoc("Component already shown, can't be inited: " + comp4Init);
69         }
70
71         comp4Init.addHierarchyListener(this);
72     }
73     
74     /** Impl of HierarchyListener, starts init job with delay when component shown,
75      * stops listening to asociated component it isn't showing anymore,
76      * calls cancel if desirable.
77      * @param evt hierarchy event
78      */

79     public void hierarchyChanged(HierarchyEvent JavaDoc evt) {
80         if (((evt.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0)) {
81             boolean isShowing = comp4Init.isShowing();
82             if (timer == null && isShowing) {
83                 timer = new Timer JavaDoc(20, this);
84                 timer.setRepeats(false);
85                 timer.start();
86             } else if (!isShowing) {
87                 comp4Init.removeHierarchyListener(this);
88                 cancel();
89             }
90         }
91     }
92
93     /** Impl of ActionListener, called from hierarchyChanged through a Timer,
94      * starts the job */

95     public void actionPerformed(ActionEvent JavaDoc ae) {
96         if (wasCancelled || (initTask != null)) {
97             //If cancelled or already started, our job is done, go away.
98
detach();
99             return;
100         }
101
102         if ((comp4Init != null) && comp4Init.isDisplayable()) {
103             //If the component has a parent onscreen, we're ready to run.
104
start();
105         }
106     }
107
108     private void start() {
109         detach();
110
111         if (initTask == null) {
112             initTask = RequestProcessor.getDefault().post(this);
113         }
114     }
115
116     private void detach() {
117         if (timer != null) {
118             timer.stop();
119         }
120     }
121
122     /** Body of task executed in RequestProcessor. Runs AsyncGUIJob's worker
123      * method and after its completion posts AsyncJob's UI update method
124      * to AWT thread.
125      */

126     public void run() {
127         if (!SwingUtilities.isEventDispatchThread()) {
128             // first pass, executed in some of RP threads
129
initJob.construct();
130             comp4Init.removeHierarchyListener(this);
131
132             // continue to invoke finished method only if hasn't been cancelled
133
boolean localCancel;
134
135             synchronized (CANCELLED_LOCK) {
136                 localCancel = wasCancelled;
137             }
138
139             if (!localCancel) {
140                 SwingUtilities.invokeLater(this);
141             }
142         } else {
143             // second pass, executed in event dispatch thread
144
initJob.finished();
145         }
146     }
147
148     /** Delegates valid cancel requests to asociated AsyncGUIJob, in the case
149      * job supports cancelling. */

150     private void cancel() {
151         if ((initTask != null) && !initTask.isFinished() && (initJob instanceof Cancellable)) {
152             synchronized (CANCELLED_LOCK) {
153                 wasCancelled = true;
154             }
155             ((Cancellable) initJob).cancel();
156         }
157     }
158     
159 }
160
Popular Tags