001 /*
002 * Created on Oct 19, 2007
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 *
014 * Copyright @2007-2010 the original author or authors.
015 */
016 package org.fest.swing.hierarchy;
017
018 import static org.fest.swing.awt.AWT.isAppletViewer;
019 import static org.fest.swing.awt.AWT.isSharedInvisibleFrame;
020
021 import java.awt.*;
022 import java.util.Collection;
023
024 import org.fest.swing.annotation.RunsInCurrentThread;
025 import org.fest.swing.monitor.WindowMonitor;
026 import org.fest.util.VisibleForTesting;
027
028 /**
029 * Understands access to the current AWT hierarchy.
030 *
031 * @author Alex Ruiz
032 * @author Yvonne Wang
033 */
034 public class ExistingHierarchy implements ComponentHierarchy {
035
036 private static WindowMonitor windowMonitor = WindowMonitor.instance();
037
038 private final ParentFinder parentFinder;
039 private final ChildrenFinder childrenFinder;
040
041 /** Creates a new </code>{@link ExistingHierarchy}</code>. */
042 public ExistingHierarchy() {
043 this(new ParentFinder(), new ChildrenFinder());
044 }
045
046 @VisibleForTesting
047 ExistingHierarchy(ParentFinder parentFinder, ChildrenFinder childrenFinder) {
048 this.parentFinder = parentFinder;
049 this.childrenFinder = childrenFinder;
050 }
051
052 /** {@inheritDoc} */
053 public Collection<? extends Container> roots() {
054 return windowMonitor.rootWindows();
055 }
056
057 /**
058 * Return the parent for the given component.
059 * <p>
060 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
061 * responsible for calling this method from the EDT.
062 * </p>
063 * @param c the given component.
064 * @return the parent for the given component.
065 */
066 @RunsInCurrentThread
067 public Container parentOf(Component c) {
068 return parentFinder.parentOf(c);
069 }
070
071 /**
072 * Returns whether the given component is reachable from any of the root windows. The default is to consider all
073 * components to be contained in the hierarchy, whether they are reachable or not.
074 * @param c the given component.
075 * @return <code>true</code>.
076 */
077 public boolean contains(Component c) {
078 return true;
079 }
080
081 /**
082 * Returns all descendants of interest of the given component.
083 * <p>
084 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
085 * responsible for calling this method from the EDT.
086 * </p>
087 * @param c the given component.
088 * @return all descendants of interest of the given component.
089 */
090 @RunsInCurrentThread
091 public Collection<Component> childrenOf(Component c) {
092 return childrenFinder.childrenOf(c);
093 }
094
095 /**
096 * Properly dispose of the given window, making it and its native resources available for garbage collection.
097 * <p>
098 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
099 * responsible for calling this method from the EDT.
100 * </p>
101 * @param w the window to dispose.
102 */
103 @RunsInCurrentThread
104 public void dispose(Window w) {
105 if (isAppletViewer(w)) return;
106 for (Window owned : w.getOwnedWindows()) dispose(owned);
107 if (isSharedInvisibleFrame(w)) return;
108 w.dispose();
109 }
110
111 ParentFinder parentFinder() { return parentFinder; }
112 ChildrenFinder childrenFinder() { return childrenFinder; }
113 }