001    /*
002     * Created on Jul 16, 2008
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 @2008-2010 the original author or authors.
015     */
016    package org.fest.swing.core.matcher;
017    
018    import static java.lang.String.valueOf;
019    import static org.fest.util.Strings.concat;
020    
021    import java.awt.Frame;
022    import java.util.regex.Pattern;
023    
024    import org.fest.swing.annotation.RunsInCurrentThread;
025    
026    /**
027     * Understands matching a <code>{@link Frame}</code>  by type, name or title.
028     *
029     * @author Alex Ruiz
030     */
031    public final class FrameMatcher extends NamedComponentMatcherTemplate<Frame> {
032    
033      private Object title;
034    
035      /**
036       * Creates a new <code>{@link FrameMatcher}</code> that matches a <code>{@link Frame}</code> that:
037       * <ol>
038       * <li>has a matching name</li>
039       * <li>(optionally) has matching title</li>
040       * <li>(optionally) is showing on the screen</li>
041       * <p>
042       * The following code listing shows how to match a <code>{@link Frame}</code> by name and title:
043       * <pre>
044       * FrameMatcher m = {@link #withName(String) withName}("myApp").{@link #andTitle(String) andTitle}("My App");
045       * </pre>
046       * </p>
047       * <p>
048       * The following code listing shows how to match a <code>{@link Frame}</code>, that should be showing on the screen,
049       * by name and title:
050       * <pre>
051       * FrameMatcher m = {@link #withName(String) withName}("myApp").{@link #andTitle(String) andTitle}("My App").{@link #andShowing() andShowing}();
052       * </pre>
053       * </p>
054       * @param name the id to match.
055       * @return the created matcher.
056       */
057      public static FrameMatcher withName(String name) {
058        return new FrameMatcher(name, ANY);
059      }
060    
061      /**
062       * Creates a new <code>{@link FrameMatcher}</code> that matches a <code>{@link Frame}</code> by its title.
063       * <p>
064       * The following code listing shows how to match a <code>{@link Frame}</code> by title:
065       * <pre>
066       * FrameMatcher m = {@link #withTitle(String) withTitle}("My App");
067       * </pre>
068       * </p>
069       * <p>
070       * The following code listing shows how to match a <code>{@link Frame}</code>, that should be showing on the screen,
071       * by title:
072       * <pre>
073       * FrameMatcher m = {@link #withTitle(String) withTitle}("My App").{@link #andShowing() andShowing}();
074       * </pre>
075       * </p>
076       * @param title the title to match. It can be a regular expression.
077       * @return the created matcher.
078       */
079      public static FrameMatcher withTitle(String title) {
080        return new FrameMatcher(ANY, title);
081      }
082    
083      /**
084       * Creates a new <code>{@link FrameMatcher}</code> that matches a <code>{@link Frame}</code> by its title.
085       * <p>
086       * The following code listing shows how to match a <code>{@link Frame}</code> by title, using a regular expression
087       * matcher:
088       * <pre>
089       * FrameMatcher m = {@link #withTitle(Pattern) withTitle}(Pattern.compile("My.*"));
090       * </pre>
091       * </p>
092       * <p>
093       * The following code listing shows how to match a <code>{@link Frame}</code>, that should be showing on the screen,
094       * by title:
095       * <pre>
096       * FrameMatcher m = {@link #withTitle(Pattern) withTitle}(Pattern.compile("My.*")).{@link #andShowing() andShowing}();
097       * </pre>
098       * </p>
099       * @param titlePattern the title to match.
100       * @return the created matcher.
101       * @since 1.2
102       */
103      public static FrameMatcher withTitle(Pattern titlePattern) {
104        return new FrameMatcher(ANY, titlePattern);
105      }
106    
107      /**
108       * Creates a new <code>{@link FrameMatcher}</code> that matches any <code>{@link Frame}</code>.
109       * @return the created matcher.
110       */
111      public static FrameMatcher any() {
112        return new FrameMatcher(ANY, ANY);
113      }
114    
115      private FrameMatcher(Object name, Object title) {
116        super(Frame.class, name);
117        this.title = title;
118      }
119    
120      /**
121       * Specifies the title to match. If this matcher was created using <code>{@link #withTitle(String)}</code> or
122       * <code>{@link FrameMatcher#withTitle(Pattern)}</code>, this method will simply update the title to match.
123       * @param newTitle the new title to match. It can be a regular expression.
124       * @return this matcher.
125       */
126      public FrameMatcher andTitle(String newTitle) {
127        title = newTitle;
128        return this;
129      }
130    
131      /**
132       * Specifies the title to match. If this matcher was created using <code>{@link #withTitle(String)}</code> or
133       * <code>{@link FrameMatcher#withTitle(Pattern)}</code>, this method will simply update the title to match.
134       * @param titlePattern the regular expression pattern to match.
135       * @return this matcher.
136       * @since 1.2
137       */
138      public FrameMatcher andTitle(Pattern titlePattern) {
139        title = titlePattern;
140        return this;
141      }
142    
143      /**
144       * Indicates that the <code>{@link Frame}</code> to match should be showing on the screen.
145       * @return this matcher.
146       */
147      public FrameMatcher andShowing() {
148        requireShowing(true);
149        return this;
150      }
151    
152      /**
153       * Indicates whether the title of the given <code>{@link Frame}</code> is equal to the title in this matcher.
154       * <p>
155       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
156       * responsible for calling this method from the EDT.
157       * </p>
158       * @param frame the <code>Frame</code> to match.
159       * @return <code>true</code> if the title in the <code>Frame</code> is equal to the title in this matcher,
160       * <code>false</code> otherwise.
161       */
162      @RunsInCurrentThread
163      protected boolean isMatching(Frame frame) {
164        if (!isNameMatching(frame.getName())) return false;
165        return arePropertyValuesMatching(title, frame.getTitle());
166      }
167    
168      @Override public String toString() {
169        return concat(
170            getClass().getName(), "[",
171            "name=", quotedName(), ", ",
172            "title=", quoted(title), ", ",
173            "requireShowing=", valueOf(requireShowing()),
174            "]"
175        );
176      }
177    }