001: package org.uispec4j.finder;
002:
003: import org.uispec4j.ComponentAmbiguityException;
004: import org.uispec4j.ItemNotFoundException;
005: import org.uispec4j.UIComponent;
006: import org.uispec4j.utils.UIComponentFactory;
007:
008: import javax.swing.*;
009: import java.awt.*;
010: import java.util.ArrayList;
011: import java.util.Collections;
012: import java.util.Iterator;
013: import java.util.List;
014:
015: /**
016: * Generic utility for retrieving AWT/Swing components in a container.
017: */
018: public class ComponentFinder {
019: private Container container;
020:
021: public ComponentFinder(Container container) {
022: this .container = container;
023: }
024:
025: public Component getComponent(ComponentMatcher matcher)
026: throws ComponentAmbiguityException, ItemNotFoundException {
027: return getComponent(new ComponentMatcher[] { matcher }, null,
028: null, new Class[0]);
029: }
030:
031: public Component getComponent(String name, Class[] swingClasses,
032: String componentType) throws ComponentAmbiguityException,
033: ItemNotFoundException {
034: try {
035: return getComponent(getMatchers(name), componentType, name,
036: swingClasses);
037: } catch (ItemNotFoundException e) {
038: Component[] components = findComponents(
039: ComponentMatcher.ALL, swingClasses);
040: List names = new ArrayList();
041: for (int i = 0; i < components.length; i++) {
042: Component component = components[i];
043: UIComponent uiComponent = UIComponentFactory
044: .createUIComponent(component);
045: String componentLabel = uiComponent.getLabel();
046: String componentName = uiComponent.getName();
047: if (componentLabel != null) {
048: names.add(componentLabel);
049: } else if (componentName != null) {
050: names.add(componentName);
051: }
052: }
053: Collections.sort(names);
054: String message = Messages.computeNotFoundMessage(
055: componentType, name, names);
056: throw new ItemNotFoundException(message);
057: }
058: }
059:
060: public Component findComponent(ComponentMatcher matcher)
061: throws ComponentAmbiguityException {
062: return findComponent(new ComponentMatcher[] { matcher }, null,
063: null, new Class[0]);
064: }
065:
066: public Component findComponent(String name, Class[] swingClasses,
067: String componentType) throws ComponentAmbiguityException {
068: return findComponent(getMatchers(name), componentType, name,
069: swingClasses);
070: }
071:
072: public Component[] getComponents(ComponentMatcher matcher) {
073: return findComponents(matcher, new Class[0]);
074: }
075:
076: public Component[] getComponents(String name, Class[] swingClasses) {
077: return getComponents(getMatchers(name), swingClasses);
078: }
079:
080: private Component findComponent(ComponentMatcher[] matchers,
081: String type, String name, Class[] swingClasses)
082: throws ComponentAmbiguityException {
083: Component[] foundComponents = getComponents(matchers,
084: swingClasses);
085: if (foundComponents.length > 1) {
086: throw new ComponentAmbiguityException(Messages
087: .computeAmbiguityMessage(foundComponents, type,
088: name));
089: }
090: return (foundComponents.length == 0) ? null
091: : foundComponents[0];
092: }
093:
094: private Component getComponent(ComponentMatcher[] matchers,
095: String type, String name, Class[] swingClasses)
096: throws ItemNotFoundException, ComponentAmbiguityException {
097: Component foundComponent = findComponent(matchers, type, name,
098: swingClasses);
099: if (foundComponent == null) {
100: throw new ItemNotFoundException(Messages
101: .computeNotFoundMessage(type, name, null));
102: }
103: return foundComponent;
104: }
105:
106: private Component[] getComponents(ComponentMatcher[] matchers,
107: Class[] swingClasses) {
108: for (int i = 0; i < matchers.length; i++) {
109: Component[] foundComponents = findComponents(matchers[i],
110: swingClasses);
111: if (foundComponents.length > 0) {
112: return foundComponents;
113: }
114: }
115: return new Component[0];
116: }
117:
118: private Component[] findComponents(ComponentMatcher matcher,
119: Class[] swingClasses) {
120: List foundComponents = new ArrayList();
121: retrieveComponents(container, foundComponents, matcher,
122: swingClasses);
123: return (Component[]) foundComponents
124: .toArray(new Component[foundComponents.size()]);
125: }
126:
127: private static void retrieveComponents(Container container,
128: List components, ComponentMatcher matcher,
129: Class[] swingClasses) {
130: if (container instanceof JScrollPane) {
131: JScrollPane scroll = (JScrollPane) container;
132: retrieveComponents(scroll.getViewport(), components,
133: matcher, swingClasses);
134: return;
135: }
136: if (container == null) {
137: return;
138: }
139: List containers = new ArrayList();
140: boolean isCardLayout = (container.getLayout() instanceof CardLayout);
141: for (int i = 0, max = container.getComponentCount(); i < max; i++) {
142: Component component = container.getComponent(i);
143: if (isCardLayout && !component.isVisible()) {
144: continue;
145: }
146: if (isClassMatching(component, swingClasses)
147: && matcher.matches(component)) {
148: components.add(component);
149: }
150: if (component instanceof Container) {
151: containers.add(component);
152: }
153: }
154: for (Iterator iterator = containers.iterator(); iterator
155: .hasNext();) {
156: retrieveComponents((Container) iterator.next(), components,
157: matcher, swingClasses);
158: }
159: }
160:
161: private static boolean isClassMatching(Component component,
162: Class[] swingClasses) {
163: if (swingClasses.length == 0) {
164: return true;
165: }
166: for (int i = 0; i < swingClasses.length; i++) {
167: Class expectedClass = swingClasses[i];
168: if (expectedClass.isAssignableFrom(component.getClass())) {
169: return true;
170: }
171: }
172: return false;
173: }
174:
175: private static ComponentMatcher[] getMatchers(String name) {
176: if (name == null) {
177: return new ComponentMatcher[] { ComponentMatcher.ALL };
178: } else {
179: return getPredefinedNameMatchers(name);
180: }
181: }
182:
183: private static ComponentMatcher[] getPredefinedNameMatchers(
184: String name) {
185: return new ComponentMatcher[] {
186: ComponentMatchers.displayedNameIdentity(name),
187: ComponentMatchers.displayedNameSubstring(name),
188: ComponentMatchers.innerNameIdentity(name),
189: ComponentMatchers.innerNameSubstring(name) };
190: }
191: }
|