001 /* 002 * Created on Dec 2, 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; 017 018 import static java.lang.String.valueOf; 019 import static org.fest.util.Objects.areEqual; 020 import static org.fest.util.Strings.*; 021 022 import java.awt.Component; 023 024 import javax.swing.JLabel; 025 026 import org.fest.swing.annotation.RunsInCurrentThread; 027 028 /** 029 * Understands <code>{@link java.awt.Component}</code> matching by the text of the associated 030 * <code>{@link JLabel}</code> and (optionally) by type. 031 * @see JLabel#getLabelFor() 032 * @see JLabel#setLabelFor(Component) 033 * 034 * @author Alex Ruiz 035 */ 036 public class LabelMatcher extends AbstractComponentMatcher { 037 038 private final String label; 039 private final Class<? extends Component> type; 040 041 /** 042 * Creates a new <code>{@link LabelMatcher}</code>. The component to match does not have to be showing. 043 * @param label the text of the label associated to the component we are looking for. 044 * @throws NullPointerException if the given label is <code>null</code>. 045 * @throws IllegalArgumentException if the given label is empty. 046 */ 047 public LabelMatcher(String label) { 048 this(label, false); 049 } 050 051 /** 052 * Creates a new <code>{@link LabelMatcher}</code>. 053 * @param label the text of the label associated to the component we are looking for. 054 * @param requireShowing indicates if the component to match should be showing or not. 055 * @throws NullPointerException if the given label is <code>null</code>. 056 * @throws IllegalArgumentException if the given label is empty. 057 */ 058 public LabelMatcher(String label, boolean requireShowing) { 059 this(label, Component.class, requireShowing); 060 } 061 062 /** 063 * Creates a new <code>{@link LabelMatcher}</code>. The component to match does not have to be showing. 064 * @param label the text of the label associated to the component we are looking for. 065 * @param type the type of the component we are looking for. 066 * @throws NullPointerException if the given label is <code>null</code>. 067 * @throws IllegalArgumentException if the given label is empty. 068 * @throws NullPointerException if the given type is <code>null</code>. 069 */ 070 public LabelMatcher(String label, Class<? extends Component> type) { 071 this(label, type, false); 072 } 073 074 /** 075 * Creates a new <code>{@link LabelMatcher}</code>. 076 * @param label the text of the label associated to the component we are looking for. 077 * @param type the type of the component we are looking for. 078 * @param requireShowing indicates if the component to match should be showing or not. 079 * @throws NullPointerException if the given label is <code>null</code>. 080 * @throws IllegalArgumentException if the given label is empty. 081 * @throws NullPointerException if the given type is <code>null</code>. 082 */ 083 public LabelMatcher(String label, Class<? extends Component> type, boolean requireShowing) { 084 super(requireShowing); 085 if (label == null) 086 throw new NullPointerException("The text of the label associated to the component to find should not be null"); 087 if (isEmpty(label)) 088 throw new IllegalArgumentException("The text of the label associated to the component to find should not be empty"); 089 if (type == null) throw new NullPointerException("The type of component to find should not be null"); 090 this.label = label; 091 this.type = type; 092 } 093 094 /** 095 * Indicates whether the given <code>{@link java.awt.Component}</code> matches the criteria specified in this 096 * matcher: 097 * <ol> 098 * <li>the text of the <code>{@link JLabel}</code></li> attached to the component to look for matches the text 099 * specified in this matcher 100 * <li>the component to look for is of the type specified in this matcher (if specified)</li> 101 * <li>visibility of the given <code>{@link java.awt.Component}</code> matches the value specified in this matcher 102 * </li> 103 * </ol> 104 * <p> 105 * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are 106 * responsible for calling this method from the EDT. 107 * </p> 108 * @return <code>true</code> if the name and visibility of the given <code>Component</code> matches the values 109 * specified in this matcher, <code>false</code> otherwise. 110 */ 111 @RunsInCurrentThread 112 public boolean matches(Component c) { 113 if (!(c instanceof JLabel)) return false; 114 JLabel labelForComponent = (JLabel)c; 115 if (!areEqual(labelForComponent.getText(), label)) return false; 116 Component labeled = labelForComponent.getLabelFor(); 117 return type.isInstance(labeled) && requireShowingMatches(labeled); 118 } 119 120 @Override public String toString() { 121 return concat( 122 getClass().getName(), "[", 123 "label=", quote(label), ", ", 124 "type=", type.getName(), ", ", 125 "requireShowing=", valueOf(requireShowing()), 126 "]" 127 ); 128 } 129 }