001    /*
002     * Created on Jun 18, 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 static java.lang.String.valueOf;
019    import static org.fest.util.Strings.concat;
020    
021    import java.awt.Component;
022    
023    import org.fest.swing.annotation.RunsInCurrentThread;
024    
025    /**
026     * Understands <code>{@link java.awt.Component}</code> matching by type.
027     *
028     * @author Alex Ruiz
029     */
030    public final class TypeMatcher extends AbstractComponentMatcher {
031    
032      private final Class<? extends Component> type;
033    
034      /**
035       * Creates a new <code>{@link TypeMatcher}</code>. The component to match does not have to be showing.
036       * @param type the type of the component we are looking for.
037       * @throws NullPointerException if the given type is <code>null</code>.
038       */
039      public TypeMatcher(Class<? extends Component> type) {
040        this(type, false);
041      }
042    
043      /**
044       * Creates a new <code>{@link TypeMatcher}</code>.
045       * @param type the type of the component we are looking for.
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 TypeMatcher(Class<? extends Component> type, boolean requireShowing) {
050        super(requireShowing);
051        if (type == null)
052          throw new NullPointerException("The type of component to find should not be null");
053        this.type = type;
054      }
055    
056      /**
057       * Indicates whether the type and visibility of the given <code>{@link java.awt.Component}</code> matches the value
058       * specified in this matcher.
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       * @return <code>true</code> if the type and visibility of the given <code>Component</code> matches the values
064       * specified in this matcher, <code>false</code> otherwise.
065       */
066      @RunsInCurrentThread
067      public boolean matches(Component c) {
068        return type.isAssignableFrom(c.getClass()) && requireShowingMatches(c);
069      }
070    
071      @Override public String toString() {
072        return concat(
073            getClass().getName(), "[",
074            "type=", type.getName(), ", ",
075            "requireShowing=", valueOf(requireShowing()),
076            "]"
077        );
078      }
079    }