// Copyright 2013 SICK AG. All rights reserved. package de.sick.guicheck.swing; import java.awt.Component; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.swing.JComponent; import de.sick.guicheck.GcAssertException; import de.sick.guicheck.GcException; import de.sick.guicheck.GcUtils; import de.sick.guicheck.fx.GcUtilsFX; /** * @author linggol (created) */ abstract class GcComponentSwing<T extends GcComponentSwing<T>> { /** * @return The Swing {@link JComponent} wrapped by this component. */ public abstract JComponent getComponent(); /** * @return The Swing component wrapped by this component. In most cases this is the same as the {@link JComponent} * returned by {@link #getComponent()} */ public abstract <Z extends Component> Z getSwingComponent(); private JComponent findComponent(final String name) { return GcUtilsSwing.eval(new GcUtils.IEvaluator<JComponent>() { @Override public JComponent eval() { JComponent l_found = findComponent(getComponent(), name); if (l_found != null) { return l_found; } throw new GcAssertException("Cannot find JComponent for name: " + name); } }); } private JComponent findComponent(final String name, int evalRetries, int evalDelay) { return GcUtilsSwing.eval(new GcUtils.IEvaluator<JComponent>() { @Override public JComponent eval() { JComponent l_found = findComponent(getComponent(), name); if (l_found != null) { return l_found; } throw new GcAssertException("Cannot find JComponent for name: " + name); } }, evalRetries, evalDelay); } private JComponent findComponent(final Class<?> clazz) { return GcUtilsSwing.eval(new GcUtils.IEvaluator<JComponent>() { @Override public JComponent eval() { JComponent l_found = findComponent(getComponent(), clazz); if (l_found != null) { return l_found; } throw new GcAssertException("Cannot find JComponent for class: " + clazz); } }); } private JComponent findComponent(JComponent parent, Class<?> clazz) { for (Component c : parent.getComponents()) { if (c instanceof JComponent) { if (clazz.isAssignableFrom(c.getClass())) { return (JComponent)c; } } } for (Component c : parent.getComponents()) { if (c instanceof JComponent) { JComponent l_found = findComponent((JComponent)c, clazz); if (l_found != null) { return l_found; } } } return null; } private JComponent findComponent(JComponent parent, String name) { for (Component c : parent.getComponents()) { if (c instanceof JComponent) { if (GcUtils.startsWithOrMatches(c.getName(), name)) { return (JComponent)c; } } } for (Component c : parent.getComponents()) { if (c instanceof JComponent) { JComponent l_found = findComponent((JComponent)c, name); if (l_found != null) { return l_found; } } } return null; } /** * Find the first child {@link JComponent} for the given name. */ public GcJComponentSwing component(String name) { return new GcJComponentSwing(findComponent(name)); } /** * Find the first child {@link JComponent} for the given name. */ public GcJComponentSwing component(String name, int evalRetries, int evalDelay) { return new GcJComponentSwing(findComponent(name, evalRetries, evalDelay)); } /** * Find the first child {@link JComponent} for the given class. */ public GcJComponentSwing component(Class<?> clazz) { return new GcJComponentSwing(findComponent(clazz)); } @SuppressWarnings("unchecked") final <TT> T propertyIs(final Object obj, final String property, final TT value, final boolean expectedResult) { try { // Get the property getter method ... final Class<?> l_clazz = value == null ? null : value.getClass(); final Method l_method = obj.getClass().getMethod(GcUtils.getPropertyGetter(property, l_clazz), (Class<?>[])null); GcUtilsFX.eval(new GcUtils.IEvaluator<Void>() { @Override public Void eval() { TT l_value; try { // ... get the value of the property ... l_value = (TT)l_method.invoke(obj, (Object[])null); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new GcException("Failed to access property " + property, e); } // ... and check it against the expected value if ((value == l_value || (value != null && value.equals(l_value))) != expectedResult) { final StringBuilder l_sb = new StringBuilder("Unexpected value of "); l_sb.append(property).append(": ").append(expectedResult ? "Expected: " : "Not expected: ").append(value).append(", Actual: ").append(l_value); throw new GcAssertException(l_sb.toString()); } return null; } }); // Return this instance again according to the fluent API style return (T)this; } catch (NoSuchMethodException e) { throw new GcException("Failed to access property " + property, e); } } /** * Check if the given property has the given value. This method follows the fluent API style. */ public final <TT> T propertyIs(String property, TT value) { return propertyIs(getSwingComponent(), property, value, true); } /** * Check if the given property does not have the given value. This method follows the fluent API style. */ public final <TT> T propertyIsNot(String property, TT value) { return propertyIs(getSwingComponent(), property, value, false); } }