KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > schlichtherle > swing > EnhancedPanel


1 /*
2  * EnhancedPanel.java
3  *
4  * Created on 21. Februar 2006, 10:17
5  */

6 /*
7  * Copyright 2006 Schlichtherle IT Services
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package de.schlichtherle.swing;
23
24 import de.schlichtherle.swing.event.PanelEvent;
25 import de.schlichtherle.swing.event.PanelListener;
26
27 import java.awt.AWTEvent JavaDoc;
28 import java.awt.Component JavaDoc;
29 import java.awt.LayoutManager JavaDoc;
30 import java.awt.Window JavaDoc;
31 import java.awt.event.ComponentAdapter JavaDoc;
32 import java.awt.event.ComponentEvent JavaDoc;
33 import java.awt.event.ComponentListener JavaDoc;
34 import java.awt.event.HierarchyEvent JavaDoc;
35 import java.awt.event.HierarchyListener JavaDoc;
36 import java.util.EventListener JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38
39 import javax.swing.JPanel JavaDoc;
40 import javax.swing.event.AncestorEvent JavaDoc;
41 import javax.swing.event.AncestorListener JavaDoc;
42 import javax.swing.event.EventListenerList JavaDoc;
43
44 /**
45  * This class adds methods to fire {@link PanelEvent}s.
46  * <p>
47  * Note that in TrueZIP 6.1, this class has been refactored to coalesce
48  * multiple panel events for the same cause by posting them to the AWT's
49  * Event Queue, from which the coalesced event would then be dispatched by
50  * AWT's Event Dispatching Thread.
51  * <p>
52  * However, since TrueZIP 6.4, these events are fired <em>synchronously</em>
53  * again, whereby it is ensured that only a single event is fired for each
54  * cause.
55  *
56  * @author Christian Schlichtherle
57  * @version @version@
58  * @since TrueZIP 5.1
59  */

60 public class EnhancedPanel extends JPanel JavaDoc {
61
62     private static final Logger JavaDoc logger
63             = Logger.getLogger(EnhancedPanel.class.getName());
64     
65     /**
66      * Creates a new <code>EnhancedPanel</code> with the specified layout
67      * manager and buffering strategy.
68      *
69      * @param layout The {@link LayoutManager} to use.
70      * @param isDoubleBuffered A boolean, true for double-buffering, which
71      * uses additional memory space to achieve fast, flicker-free
72      * updates.
73      */

74     public EnhancedPanel(LayoutManager JavaDoc layout, boolean isDoubleBuffered) {
75         super(layout, isDoubleBuffered);
76         init();
77     }
78
79     /**
80      * Create a new buffered <code>EnhancedPanel</code> with the specified
81      * layout manager.
82      *
83      * @param layout The {@link LayoutManager} to use.
84      */

85     public EnhancedPanel(LayoutManager JavaDoc layout) {
86         super(layout);
87         init();
88     }
89
90     /**
91      * Creates a new <code>EnhancedPanel</code> with <code>FlowLayout</code>
92      * and the specified buffering strategy.
93      * If <code>isDoubleBuffered</code> is true, the <code>EnhancedPanel</code>
94      * will use a double buffer.
95      *
96      * @param isDoubleBuffered A boolean, true for double-buffering, which
97      * uses additional memory space to achieve fast, flicker-free
98      * updates.
99      */

100     public EnhancedPanel(boolean isDoubleBuffered) {
101         super(isDoubleBuffered);
102         init();
103     }
104
105     /**
106      * Creates a new <code>EnhancedPanel</code> with a double buffer
107      * and a flow layout.
108      */

109     public EnhancedPanel() {
110         init();
111     }
112
113     private void init() {
114         addHierarchyListener(new HierarchyListener JavaDoc() {
115             public void hierarchyChanged(final HierarchyEvent JavaDoc e) {
116                 if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED)
117                         != HierarchyEvent.SHOWING_CHANGED)
118                     return;
119
120                 /*if (!isVisible())
121                     return;*/

122
123                 final Window JavaDoc window = getAncestorWindow();
124                 final boolean windowShown = window.isShowing();
125                 if (windowShown != isShowing())
126                     return;
127
128                 processPanelEvent(new PanelEvent(EnhancedPanel.this,
129                         windowShown
130                             ? PanelEvent.ANCESTOR_WINDOW_SHOWN
131                             : PanelEvent.ANCESTOR_WINDOW_HIDDEN));
132             }
133         });
134
135         /*final ComponentListener cl = new ComponentAdapter() {
136             public void componentShown(ComponentEvent evt) {
137                 // Depending on which method the ancestor window uses to show
138                 // itself, multiple ComponentEvents may occur for the same event.
139                 // By posting the subsequent PanelEvents to the AWT Event Queue,
140                 // they can be coalesced into one event again.
141                 final PanelEvent event = new PanelEvent(EnhancedPanel.this,
142                         PanelEvent.ANCESTOR_WINDOW_SHOWN);
143                 logger.finer("Posting " + event);
144                 getToolkit().getSystemEventQueue().postEvent(event);
145                 //processPanelEvent(event);
146             }
147
148             public void componentHidden(ComponentEvent evt) {
149                 // Depending on which method the ancestor window uses to hide
150                 // itself, multiple ComponentEvents may occur for the same event.
151                 // By posting the subsequent PanelEvents to the AWT Event Queue,
152                 // they can be coalesced into one event again.
153                 final PanelEvent event = new PanelEvent(EnhancedPanel.this,
154                         PanelEvent.ANCESTOR_WINDOW_HIDDEN);
155                 logger.finer("Posting " + event);
156                 getToolkit().getSystemEventQueue().postEvent(event);
157                 //processPanelEvent(event);
158             }
159         };
160
161         addAncestorListener(new AncestorListener() {
162             public void ancestorAdded(final AncestorEvent evt) {
163                 // Note that with J2SE 1.4.2_10 this event happens BEFORE
164                 // the ancestor window is made visible, while with
165                 // J2SE 1.5.0_06 this event happens AFTER the ancestor is
166                 // made visible.
167                 final Window window = getAncestorWindow(evt.getAncestor());
168                 window.addComponentListener(cl);
169                 final boolean windowShown = window.isShowing();
170                 //assert windowShown == isShowing();
171                 if (windowShown)
172                     cl.componentShown(null);
173             }
174
175             public void ancestorRemoved(final AncestorEvent evt) {
176                 // Note that with J2SE 1.4.2_10 this event happens BEFORE
177                 // the ancestor window is made visible, while with
178                 // J2SE 1.5.0_06 this event happens AFTER the ancestor is
179                 // made visible.
180                 final Window window = getAncestorWindow(evt.getAncestor());
181                 window.removeComponentListener(cl);
182                 final boolean windowShown = window.isShowing();
183                 //assert windowShown == isShowing();
184                 if (!windowShown)
185                     cl.componentHidden(null);
186             }
187
188             public void ancestorMoved(AncestorEvent evt) {
189             }
190         });*/

191     }
192
193     /**
194      * Overridden in order to prevent this component to deliver a
195      * {@link PanelEvent} multiple times from the same source.
196      *
197      * @deprecated See {@link EnhancedPanel}.
198      */

199     protected AWTEvent JavaDoc coalesceEvents(
200             final AWTEvent JavaDoc existingEvent,
201             final AWTEvent JavaDoc newEvent) {
202         assert existingEvent.getSource() == newEvent.getSource();
203         
204         // Coalesce arbitrary sequences of ANCESTOR_WINDOW_* events into
205
// the last one.
206
if (existingEvent instanceof PanelEvent && newEvent instanceof PanelEvent) {
207             assert false : "This is dead code since the refactoring for TrueZIP 6.4!";
208             final int id = newEvent.getID();
209             assert id == existingEvent.getID();
210             switch (id) {
211                 case PanelEvent.ANCESTOR_WINDOW_SHOWN:
212                 case PanelEvent.ANCESTOR_WINDOW_HIDDEN:
213                     return newEvent;
214             }
215         }
216
217         return super.coalesceEvents(existingEvent, newEvent);
218     }
219
220     /**
221      * Overridden in order to process {@link PanelEvent}s.
222      *
223      * @deprecated See {@link EnhancedPanel}.
224      */

225     protected void processEvent(final AWTEvent JavaDoc event) {
226         if (event instanceof PanelEvent) {
227             //assert false : "This is dead code since the refactoring for TrueZIP 6.4!";
228
processPanelEvent((PanelEvent) event);
229         } else {
230             super.processEvent(event);
231         }
232     }
233
234     /**
235      * Calls {@link #fireAncestorWindowShown} or
236      * {@link #fireAncestorWindowHidden}, depending on the ID of the given
237      * <code>event</code>.
238      */

239     protected void processPanelEvent(final PanelEvent event) {
240         logger.fine("Processing " + event);
241         switch (event.getID()) {
242             case PanelEvent.ANCESTOR_WINDOW_SHOWN:
243                 fireAncestorWindowShown(event);
244                 break;
245
246             case PanelEvent.ANCESTOR_WINDOW_HIDDEN:
247                 fireAncestorWindowHidden(event);
248                 break;
249
250             default:
251                 throw new AssertionError JavaDoc();
252         }
253     }
254
255     /**
256      * Returns the ancestor {@link Window} of this <code>Panel</code> or
257      * <code>null</code> if the component is not (yet) placed in a
258      * <code>Window</code>.
259      */

260     public Window JavaDoc getAncestorWindow() {
261         return getAncestorWindow(this);
262     }
263
264     private static final Window JavaDoc getAncestorWindow(Component JavaDoc c) {
265         while (c != null && !(c instanceof Window JavaDoc))
266             c = c.getParent();
267
268         return (Window JavaDoc) c;
269     }
270
271     /**
272      * Utility field used by event firing mechanism.
273      * Note that the listeners don't get serialized with this component!
274      */

275     private transient EventListenerList JavaDoc listenerList;
276
277     /**
278      * Adds the <code>listener</code> to the list of receivers for
279      * {@link PanelEvent}s.
280      * <p>
281      * Note that the listener doesn't get serialized with this component!
282      *
283      * @param listener The listener to add.
284      * If this method is called <code>n</code> times with the same
285      * listener, any events generated will be delivered to this
286      * listener <code>n</code> times.
287      *
288      * @throws NullPointerException If <code>listener</code> is
289      * <code>null</code>.
290      */

291     public void addPanelListener(final PanelListener listener) {
292         if (listener == null)
293             throw new NullPointerException JavaDoc();
294         if (listenerList == null )
295             listenerList = new EventListenerList JavaDoc();
296         listenerList.add(PanelListener.class, listener);
297     }
298
299     /**
300      * Removes the <code>listener</code> from the list of receivers for
301      * {@link PanelEvent}s.
302      *
303      * @param listener The listener to remove.
304      * If this listener has been {@link #addPanelListener added}
305      * multiple times, it is removed from the list only once.
306      *
307      * @throws NullPointerException If <code>listener</code> is
308      * <code>null</code>.
309      */

310     public void removePanelListener(final PanelListener listener) {
311         if (listener == null)
312             throw new NullPointerException JavaDoc();
313         if (listenerList == null)
314             return;
315         listenerList.remove(PanelListener.class, listener);
316     }
317
318     /**
319      * Returns an array of all the panel listeners
320      * registered on this component.
321      *
322      * @return All of this panel's <code>PanelListener</code>s or an empty
323      * array if no panel listeners are currently registered.
324      *
325      * @see #addPanelListener
326      * @see #removePanelListener
327      */

328     public PanelListener[] getPanelListeners() {
329         if (listenerList != null)
330             return (PanelListener[]) listenerList.getListeners(PanelListener.class);
331         else
332             return new PanelListener[0];
333     }
334
335     public EventListener JavaDoc[] getListeners(Class JavaDoc listenerType) {
336         if (listenerType == PanelListener.class)
337             return getPanelListeners();
338         else
339             return super.getListeners(listenerType);
340     }
341
342     /**
343      * Notifies all registered listeners about the event.
344      * This is a synchronous operation.
345      *
346      * @param event The event to be fired.
347      *
348      * @deprecated You should not call this method directly.
349      */

350     protected void fireAncestorWindowShown(final PanelEvent event) {
351         if (listenerList == null)
352             return;
353         final Object JavaDoc[] listeners = listenerList.getListenerList();
354         for (int i = listeners.length - 2; i >= 0; i -= 2) {
355             if (listeners[i] == PanelListener.class)
356                 ((PanelListener) listeners[i+1]).ancestorWindowShown(event);
357         }
358     }
359
360     /**
361      * Notifies all registered listeners about the event.
362      * This is a synchronous operation.
363      *
364      * @param event The event to be fired.
365      *
366      * @deprecated You should not call this method directly.
367      */

368     protected void fireAncestorWindowHidden(final PanelEvent event) {
369         if (listenerList == null)
370             return;
371         final Object JavaDoc[] listeners = listenerList.getListenerList();
372         for (int i = listeners.length - 2; i >= 0; i -= 2) {
373             if (listeners[i] == PanelListener.class)
374                 ((PanelListener) listeners[i+1]).ancestorWindowHidden(event);
375         }
376     }
377 }
378
Popular Tags