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 }