001 /* 002 * Created on Aug 6, 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.core; 017 018 import java.awt.Component; 019 020 import org.fest.swing.annotation.RunsInCurrentThread; 021 022 /** 023 * Understands a <code>{@link ComponentMatcher}</code> that matches a <code>{@link Component}</code> by type and some 024 * custom search criteria. 025 * @param <T> the type of <code>Component</code> supported by this matcher. 026 * 027 * @author Yvonne Wang 028 * @author Alex Ruiz 029 */ 030 public abstract class GenericTypeMatcher<T extends Component> extends AbstractComponentMatcher { 031 032 private final Class<T> supportedType; 033 034 /** 035 * Creates a new </code>{@link GenericTypeMatcher}</code>. The component to match does not have to be showing. 036 * @param supportedType the type supported by this matcher. 037 * @throws NullPointerException if the given type is <code>null</code>. 038 */ 039 public GenericTypeMatcher(Class<T> supportedType) { 040 this(supportedType, false); 041 } 042 043 /** 044 * Creates a new </code>{@link GenericTypeMatcher}</code>. 045 * @param supportedType the type supported by this matcher. 046 * @param requireShowing indicates if the component to match should be showing or not. 047 * @throws NullPointerException if the given type is <code>null</code>. 048 */ 049 public GenericTypeMatcher(Class<T> supportedType, boolean requireShowing) { 050 super(requireShowing); 051 if (supportedType == null) throw new NullPointerException("The supported type should not be null"); 052 this.supportedType = supportedType; 053 } 054 055 /** 056 * Verifies that the given <code>{@link Component}</code>: 057 * <ol> 058 * <li>Is an instance of the generic type specified in this <code>{@link ComponentMatcher}</code></li> 059 * <li>Matches some search criteria</li> 060 * </ol> 061 * <p> 062 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are 063 * responsible for calling this method from the EDT. 064 * </p> 065 * @param c the <code>Component</code> to verify. 066 * @return <code>true</code> if the given <code>Component</code> is an instance of the generic type of this matcher 067 * and matches some search criteria. Otherwise, <code>false</code>. 068 */ 069 @RunsInCurrentThread 070 public final boolean matches(Component c) { 071 if (c == null) return false; 072 if (!supportedType.isInstance(c)) return false; 073 try { 074 return (requireShowingMatches(c)) && isMatching(supportedType.cast(c)); 075 } catch(ClassCastException ignored) { 076 return false; 077 } 078 } 079 080 /** 081 * Returns the supported type of this matcher. 082 * @return the supported type of this matcher. 083 */ 084 public final Class<T> supportedType() { 085 return supportedType; 086 } 087 088 /** 089 * Verifies that the given component matches some search criteria. 090 * <p> 091 * <b>Note:</b> Implementations of this method <b>may not</b> be guaranteed to be executed in the event dispatch 092 * thread (EDT.) Clients are responsible for invoking this method in the EDT. 093 * </p> 094 * @param component the <code>Component</code> to verify. 095 * @return <code>true</code> if the given component matches the defined search criteria; otherwise, <code>false</code> 096 * . 097 */ 098 @RunsInCurrentThread 099 protected abstract boolean isMatching(T component); 100 }