/******************************************************************************* * Copyright (c) 2012 Google, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.runtime.swt.internal.abbot.matcher; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Widget; import abbot.finder.matchers.swt.AbstractMatcher; import com.windowtester.swt.locator.SWTHierarchyHelper; /** * Matches a widget that is immediately adjacent to (e.g., following) * a Label widget with the given label text. * <p> * For instance, this matcher: * <pre> * new LabeledWidgetMatcher(Text.class, "File:"); * </pre> * matches a Text widget that is preceded by the "File:" label. * * <p> * @author Phil Quitslund * */ public class LabeledWidgetMatcher extends AbstractMatcher { private final String _labelText; private final Class _cls; private SWTHierarchyHelper _helper; /** * Create an instance that matches an instance of a given class and preceded by a * Label with the given text. * @param cls class of the widget to match * @param labelText the text of the label preceding it */ public LabeledWidgetMatcher(Class cls, String labelText) { _cls = cls; _labelText = labelText; } /* (non-Javadoc) * @see abbot.finder.swt.Matcher#matches(org.eclipse.swt.widgets.Widget) */ public boolean matches(final Widget w) { Display d = w.getDisplay(); Widget parent = getHelper(d).getParent(w); if (!(parent instanceof Composite)) return false; final Composite comp = (Composite)parent; final boolean result[]= new boolean[1]; d.syncExec(new Runnable() { public void run() { final int index = getLabelIndex(comp); if (index == -1) return; //short-circuit //get the next widget that matches the target class in the list of children //if it matches our target widget, success! Control[] children = comp.getChildren(); //fixed: increment index by one to get NEXT for (int i=index+1; i < children.length; ++i) { if (children[i].getClass().equals(_cls)) { if (children[i] == w) result[0] = true; return; //either way return } } } }); return result[0]; } /** * Get the index of the target label in the list of our parent's children. * @return - the label's index (-1 indicates an error) */ private int getLabelIndex(Composite parent) { Control[] children = parent.getChildren(); for (int i=0; i < children.length; ++i) { if (children[i] instanceof Label) { Label label = (Label)children[i]; if (stringsMatch(_labelText, label.getText())) return i; } } return -1; } private SWTHierarchyHelper getHelper(Display display) { if (_helper == null) _helper = new SWTHierarchyHelper(display); return _helper; } }