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.JLabel;
024    
025    import org.fest.swing.annotation.RunsInCurrentThread;
026    
027    /**
028     * Understands matching a <code>{@link JLabel}</code> by type, name or text.
029     *
030     * @author Alex Ruiz
031     */
032    public final class JLabelMatcher extends NamedComponentMatcherTemplate<JLabel> {
033    
034      private Object text;
035    
036      /**
037       * Creates a new <code>{@link JLabelMatcher}</code> that matches a <code>{@link JLabel}</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 JLabel}</code> by name and text:
044       * <pre>
045       * JLabelMatcher m = {@link #withName(String) withName}("firstName").{@link #andText(String) andText}("First Name:");
046       * </pre>
047       * </p>
048       * <p>
049       * The following code listing shows how to match a <code>{@link JLabel}</code>, that should be showing on the screen,
050       * by name and text:
051       * <pre>
052       * JLabelMatcher m = {@link #withName(String) withName}("firstName").{@link #andText(String) andText}("First Name:").{@link #andShowing() andShowing}();
053       * </pre>
054       * </p>
055       * @param name the id to match.
056       * @return the created matcher.
057       */
058      public static JLabelMatcher withName(String name) {
059        return new JLabelMatcher(name, ANY);
060      }
061    
062      /**
063       * Creates a new <code>{@link JLabelMatcher}</code> that matches a <code>{@link JLabel}</code> by its text.
064       * <p>
065       * The following code listing shows how to match a <code>{@link JLabel}</code> by text:
066       * <pre>
067       * JLabelMatcher m = {@link #withText(String) withText}("First Name:");
068       * </pre>
069       * </p>
070       * <p>
071       * The following code listing shows how to match a <code>{@link JLabel}</code>, that should be showing on the screen,
072       * by text:
073       * <pre>
074       * JLabelMatcher m = {@link #withText(String) withText}("First Name:").{@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 JLabelMatcher withText(String text) {
081        return new JLabelMatcher(ANY, text);
082      }
083    
084      /**
085       * Creates a new <code>{@link JLabelMatcher}</code> that matches a <code>{@link JLabel}</code> by its text.
086       * <p>
087       * The following code listing shows how to match a <code>{@link JLabel}</code> by text:
088       * <pre>
089       * JLabelMatcher m = {@link #withText(Pattern) withText}(Pattern.compile("F.*");
090       * </pre>
091       * </p>
092       * <p>
093       * The following code listing shows how to match a <code>{@link JLabel}</code>, that should be showing on the screen,
094       * by text:
095       * <pre>
096       * JLabelMatcher m = {@link #withText(Pattern) withText}(Pattern.compile("F.*").{@link #andShowing() andShowing}();
097       * </pre>
098       * </p>
099       * @param textPattern the regular expression pattern to match.
100       * @return the created matcher.
101       * @since 1.2
102       */
103      public static JLabelMatcher withText(Pattern textPattern) {
104        return new JLabelMatcher(ANY, textPattern);
105      }
106    
107      /**
108       * Creates a new <code>{@link JLabelMatcher}</code> that matches any <code>{@link JLabel}</code>.
109       * @return the created matcher.
110       */
111      public static JLabelMatcher any() {
112        return new JLabelMatcher(ANY, ANY);
113      }
114    
115      private JLabelMatcher(Object name, Object text) {
116        super(JLabel.class, name);
117        this.text = text;
118      }
119    
120      /**
121       * Specifies the text to match. If this matcher was created using <code>{@link #withText(String)}</code> or
122       * <code>{@link #withText(Pattern)}</code>, this method will simply update the text to match.
123       * @param newText the new text to match. It can be a regular expression.
124       * @return this matcher.
125       */
126      public JLabelMatcher andText(String newText) {
127        text = newText;
128        return this;
129      }
130    
131      /**
132       * Specifies the text to match. If this matcher was created using <code>{@link #withText(String)}</code> or
133       * <code>{@link #withText(Pattern)}</code>, this method will simply update the text to match.
134       * @param textPattern the regular expression pattern to match.
135       * @return this matcher.
136       * @since 1.2
137       */
138      public JLabelMatcher andText(Pattern textPattern) {
139        text = textPattern;
140        return this;
141      }
142    
143      /**
144       * Indicates that the <code>{@link JLabel}</code> to match should be showing on the screen.
145       * @return this matcher.
146       */
147      public JLabelMatcher andShowing() {
148        requireShowing(true);
149        return this;
150      }
151    
152      /**
153       * Indicates whether the text of the given <code>{@link JLabel}</code> is equal to the text 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 button the <code>JLabel</code> to match.
159       * @return <code>true</code> if the text in the <code>JLabel</code> is equal to the text in this matcher,
160       * <code>false</code> otherwise.
161       */
162      @RunsInCurrentThread
163      protected boolean isMatching(JLabel button) {
164        if (!isNameMatching(button.getName())) return false;
165        return arePropertyValuesMatching(text, button.getText());
166      }
167    
168      @Override public String toString() {
169        return concat(
170            getClass().getName(), "[",
171            "name=", quotedName(), ", ",
172            "text=", quoted(text), ", ",
173            "requireShowing=", valueOf(requireShowing()),
174            "]"
175        );
176      }
177    }