All Downloads are FREE. Search and download functionalities are using the official Maven repository.

junit.extensions.jfcunit.TestHelper Maven / Gradle / Ivy

The newest version!
package junit.extensions.jfcunit;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import junit.extensions.jfcunit.eventdata.AbstractKeyEventData;
import junit.extensions.jfcunit.eventdata.AbstractMouseEventData;
import junit.extensions.jfcunit.eventdata.DragEventDataEx;
import junit.extensions.jfcunit.eventdata.KeyEventDataEx;
import junit.extensions.jfcunit.eventdata.MouseWheelEventDataEx;
import junit.extensions.jfcunit.finder.Finder;
import junit.extensions.jfcunit.keyboard.DefaultKeyMapping;
import junit.extensions.jfcunit.keyboard.JFCKeyStroke;
import junit.extensions.jfcunit.keyboard.KeyMapping;

/**
 * A helper class that provides facilities for locating and posting events to
 * components within a GUI. To use, create a new instance of TestHelper in your
 * setUp. Caveat: Windows can only be located once they have been shown once to
 * the user.
 * 
 * @author Matt Caswell
 * @author Vijay Aravamudhan :
 *         ThoughtWorks Inc.
 */
public abstract class TestHelper extends ATestHelper
{
	/**
	 * KeyMapping to be used with the helper.
	 */
	private static KeyMapping s_keyMapping = null;

	/**
	 * Lock for setting the key mapping.
	 */
	private static final Object LOCK = new Object();

	/**
	 * Step size for mouse movement events.
	 */
	private int m_step = 10;

	/**
	 * Constructor.
	 */
	protected TestHelper()
	{
		// no impl
	}

	/**
	 * Set the key mapping to be used.
	 * 
	 * @param km
	 *            KeyMapping to be used.
	 */
	public static void setKeyMapping(final KeyMapping km)
	{
		synchronized (LOCK)
		{
			s_keyMapping = km;
			LOCK.notifyAll();
		}
	}

	/**
	 * Get the key mapping to be used.
	 * 
	 * @return the key mapping.
	 */
	public static KeyMapping getKeyMapping()
	{
		synchronized (LOCK)
		{
			if (s_keyMapping == null)
			{
				setKeyMapping(new DefaultKeyMapping());
			}

			LOCK.notifyAll();
		}

		return s_keyMapping;
	}

	/**
	 * Find the index of the component given.
	 * 
	 * @param finder
	 *            Finder used for indexing.
	 * @param cont
	 *            Container to look for the component in.
	 * @param comp
	 *            Component to find the index of.
	 * @return Index of the component
	 */
	public static int indexOf(final Finder finder, final Container cont, final Component comp)
	{
		Container[] containers = null;

		if (cont != null)
		{
			if (!cont.isShowing())
			{
				finder.setIgnoreVisibility(true);
			}

			containers = new Container[]
			{ cont };
		} else
		{
			containers = getAllWindows();
		}

		int index = 0;

		for (int i = 0; i < containers.length; i++)
		{
			final List list = Finder.findComponentList(finder, containers[i], new ArrayList(), 999);

			if (list.contains(comp))
			{
				return index + list.indexOf(comp);
			} else
			{
				index += list.size();
			}
		}

		return -1;
	}

	/**
	 * Set the step size of mouse move events.
	 * 
	 * @param step
	 *            size in pixels.
	 */
	public void setStep(final int step)
	{
		this.m_step = step;
	}

	/**
	 * Returns the step size for the move events.
	 * 
	 * @return int size in pixels.
	 */
	public int getStep()
	{
		return this.m_step;
	}

	/**
	 * Helper method to fire appropriate events to click(s) a component with a
	 * custom wait method.
	 * 
	 * @param evtData
	 *            The event data container
	 */
	@Deprecated
	public void enterClickAndLeave(final AbstractMouseEventData evtData)
	{
		JFCUnit.enterClickAndLeave(evtData);
	}

	/**
	 * Helper method to fire appropriate events to drag and drop a component
	 * with a custom wait method.
	 * 
	 * Note this will not work with java.awt.dnd API implementations. The
	 * java.awt.dnd implementation is driven from a level below the AWT
	 * EventQueue. Use the RobotTestHelper to work with java.awt.dnd.
	 * 
	 * @param srcEvtData
	 *            The source event data container
	 * @param dstEvtData
	 *            The destination event data container
	 * @param incr
	 *            Amount to increment the coords while "moving" from source to
	 *            destination.
	 */
	@Deprecated
	public void enterDragAndLeave(final AbstractMouseEventData srcEvtData, final AbstractMouseEventData dstEvtData,
			final int incr)
	{
		JFCUnit.enterDragAndLeave(srcEvtData, dstEvtData, incr);
	}

	/**
	 * Helper method to fire appropriate events to drag and drop a component
	 * with a custom wait method.
	 * 
	 * Note this will not work with java.awt.dnd API implementations. The
	 * java.awt.dnd implementation is driven from a level below the AWT
	 * EventQueue. Use the RobotTestHelper to work with java.awt.dnd.
	 * 
	 * @param ded
	 *            The destination event data container
	 */
	@Deprecated
	public void enterDragAndLeave(final DragEventDataEx ded)
	{
		JFCUnit.enterDragAndLeave(ded);
	}

	/**
	 * Enter a mouseWheel event.
	 * 
	 * @param evtData
	 *            MouseWheelEventData to be processed.
	 */
	@Deprecated
	public void enterMouseWheel(final MouseWheelEventDataEx evtData)
	{
		JFCUnit.enterMouseWheel(evtData);
	}

	/**
	 * This method is used to send KeyPressed, KeyTyped and KeyReleased events
	 * (in that order) to the specified component. This method should be used
	 * only to send Action key events. NOTE: This method will not call
	 * 'requestFocus()' on the component - the developer should include it in
	 * the test code if needed.
	 * 
	 * @param evtData
	 *            The event data container.
	 */
	@Deprecated
	public void sendKeyAction(final KeyEventDataEx evtData)
	{
		sendString(evtData);
	}

	/**
	 * This method is used to send KeyPressed, KeyTyped and KeyReleased events
	 * (in that order) to the specified component. This method can also
	 * differentiate between upper and lower case characters in the specified
	 * string. NOTE: This method will not call 'requestFocus()' on the component
	 * - the developer should include it in the test code if needed.
	 * 
	 * @param evtData
	 *            The event data container.
	 */
	@Deprecated
	public void sendString(final AbstractKeyEventData evtData)
	{
		JFCUnit.sendString(evtData);
	}

	/**
	 * Send the modifier key release event for the modifiers.
	 * 
	 * @param ultimate
	 *            Component to receive the events.
	 * @param modifiers
	 *            The modifiers to be released.
	 * @param newModifiers
	 *            The new modifiers which should be pressed.
	 */
	protected final void adjustModifiers(final Component ultimate, final int modifiers, final int newModifiers)
	{
		if (modifiers == newModifiers)
		{
			return;
		}

		final boolean s1 = (modifiers & InputEvent.SHIFT_MASK) > 0;
		final boolean s2 = (newModifiers & InputEvent.SHIFT_MASK) > 0;
		final boolean c1 = (modifiers & InputEvent.CTRL_MASK) > 0;
		final boolean c2 = (newModifiers & InputEvent.CTRL_MASK) > 0;
		final boolean m1 = (modifiers & InputEvent.META_MASK) > 0;
		final boolean m2 = (newModifiers & InputEvent.META_MASK) > 0;
		final boolean a1 = (modifiers & InputEvent.ALT_MASK) > 0;
		final boolean a2 = (newModifiers & InputEvent.ALT_MASK) > 0;
		final boolean g1 = (modifiers & InputEvent.ALT_GRAPH_MASK) > 0;
		final boolean g2 = (newModifiers & InputEvent.ALT_GRAPH_MASK) > 0;

		int mods = modifiers;

		if (s1 && !s2)
		{
			// Release shift
			mods = mods & (-1 ^ InputEvent.SHIFT_MASK);

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_SHIFT);
			strokes[0].setModifiers(mods);
			keyReleased(ultimate, strokes[0]);
		} else if (!s1 && s2)
		{
			// Press shift
			mods = mods | InputEvent.SHIFT_MASK;

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_SHIFT);
			strokes[0].setModifiers(mods);
			keyPressed(ultimate, strokes[0]);
		}

		if (c1 && !c2)
		{
			// Release control
			mods = mods & (-1 ^ InputEvent.CTRL_MASK);

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_CONTROL);
			strokes[0].setModifiers(mods);
			keyReleased(ultimate, strokes[0]);
		} else if (!c1 && c2)
		{
			// Press control
			mods = mods | InputEvent.CTRL_MASK;

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_CONTROL);
			strokes[0].setModifiers(mods);
			keyPressed(ultimate, strokes[0]);
		}

		if (a1 && !a2)
		{
			// Release alt
			mods = mods & (-1 ^ InputEvent.ALT_MASK);

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_ALT);
			strokes[0].setModifiers(mods);
			keyReleased(ultimate, strokes[0]);
		} else if (!a1 && a2)
		{
			// Press alt
			mods = mods | InputEvent.ALT_MASK;

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_ALT);
			strokes[0].setModifiers(mods);
			keyPressed(ultimate, strokes[0]);
		}

		if (g1 && !g2)
		{
			// Release alt graph
			mods = mods & (-1 ^ InputEvent.ALT_GRAPH_MASK);

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_ALT_GRAPH);
			strokes[0].setModifiers(mods);
			keyReleased(ultimate, strokes[0]);
		} else if (!g1 && g2)
		{
			// Press alt graph
			mods = mods | InputEvent.ALT_GRAPH_MASK;

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_ALT_GRAPH);
			strokes[0].setModifiers(mods);
			keyPressed(ultimate, strokes[0]);
		}

		if (m1 && !m2)
		{
			// Release meta
			mods = mods & (-1 ^ InputEvent.META_MASK);

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_META);
			strokes[0].setModifiers(mods);
			keyReleased(ultimate, strokes[0]);
		} else if (!m1 && m2)
		{
			// Press meta
			mods = mods | InputEvent.META_MASK;

			final JFCKeyStroke[] strokes = getKeyMapping().getKeyStrokes(KeyEvent.VK_META);
			strokes[0].setModifiers(mods);
			keyPressed(ultimate, strokes[0]);
		}
	}

	/**
	 * Send the modifier key press event for the modifiers.
	 * 
	 * @param ultimate
	 *            Component to receive the events.
	 * @param modifiers
	 *            The modifiers to be pressed.
	 */
	protected final void pressModifiers(final Component ultimate, final int modifiers)
	{
		adjustModifiers(ultimate, 0, modifiers);
	}

	/**
	 * Send the modifier key release event for the modifiers.
	 * 
	 * @param ultimate
	 *            Component to receive the events.
	 * @param modifiers
	 *            The modifiers to be released.
	 */
	protected final void releaseModifiers(final Component ultimate, final int modifiers)
	{
		adjustModifiers(ultimate, modifiers, 0);
	}

	/**
	 * Process a key press event on a component.
	 * 
	 * @param ultimate
	 *            The ultimate parent Component
	 * @param stroke
	 *            The JFCKeyStroke to be performed.
	 */
	protected abstract void keyPressed(final Component ultimate, final JFCKeyStroke stroke);

	/**
	 * Process a key release event on a component.
	 * 
	 * @param ultimate
	 *            The ultimate parent Component
	 * @param stroke
	 *            The JFCKeyStroke to be performed.
	 */
	protected abstract void keyReleased(final Component ultimate, final JFCKeyStroke stroke);

	/**
	 * Process a mouse move event on a component. eve
	 * 
	 * @param ultimate
	 *            The ultimate parent Component
	 * @param x
	 *            The x coordinate of the point where the mouse is being moved
	 *            to.
	 * @param y
	 *            The y coordinate of the point where the mouse is being moved
	 *            to.
	 */
	protected abstract void mouseMoved(final Component ultimate, final int x, final int y);

	/**
	 * Process a mouse press event on a component.
	 * 
	 * @param ultimate
	 *            The ultimate parent Component
	 * @param modifiers
	 *            The modifiers associated with this mouse event.
	 * @param click
	 *            The number of clicks associated with this mouse event.
	 * @param isPopupTrigger
	 *            Whether this mouse event will generate a popup.
	 */
	protected abstract void mousePressed(final Component ultimate, final int modifiers, final int click,
			final boolean isPopupTrigger);

	/**
	 * Process a mouse release event on a component.
	 * 
	 * @param ultimate
	 *            The ultimate parent Component
	 * @param modifiers
	 *            The modifiers associated with this mouse event.
	 * @param click
	 *            The number of clicks associated with this mouse event.
	 * @param isPopupTrigger
	 *            Whether this mouse event will generate a popup.
	 */
	protected abstract void mouseReleased(final Component ultimate, final int modifiers, final int click,
			final boolean isPopupTrigger);

	/**
	 * Simulate rotating the mouseWheel.
	 * 
	 * @param ultimate
	 *            Component to fire the events on.
	 * @param amount
	 *            Amount to scroll for each rotation.
	 * @param rotation
	 *            clicks to rotate the mouse wheel.
	 */
	protected abstract void mouseWheel(final Component ultimate, final int amount, final int rotation);
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy