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