Jemmy Primer

The first thing you have to do when using Jemmy, like any Swing tester, is find the primary frame of the app you're dealing with. Since we're looking for a JFrame object, we use a JFrameOperator to find it. Windows are particularly simple to find since we just need to give our JFrameOperator the title of the window we're looking for in its constructor. In the SwingSet test app that title is, unsurprisingly, SwingSet.

private JFrameOperator getOuterFrameOperator(){
 // We'll need this object later to drill down to our widgets
 if (outerFrameOperator == null){ outerFrameOperator = new JFrameOperator("SwingSet");
 } return outerFrameOperator;

We'll be using that outerFrameOperator as the source from which Jemmy will navigate to whatever object we're interested in working with. Once we've got that, we can then drill down to the widgets we really care about. First, though, we need to find the right tab. It’s crucial that we select the correct tab because, in Swing, you can't access any object that hasn't been displayed yet. And if we don't select the tab we're interested in, then its components won't be displayed. So we set up a JTabbedPaneOperator:

private JTabbedPaneOperator getTabbedPaneOperator(){
 if (jtpo == null){
 jtpo = new JTabbedPaneOperator(getOuterFrameOperator());
 return jtpo;

We're setting the JFrameOperator and JTabbedPaneOperator up in “get” methods so we won’t need to instantiate them again and again throughout the code. You'll notice that the constructor here took our outerFrameOperator as an argument. This tells the JTabbedPaneOperator to drill down from the JFrame object referenced by the JFrameOperator until it hits a JTabbedPane. What if you have more than one JTabbedPane? Operator classes generally have a variety of constructors at your disposal with enough arguments to let you tell the Operator exactly which component to drill down to. Here are JTabbedPaneOperator's:

  1. JTabbedPaneOperator(ContainerOperator cont)

  2. JTabbedPaneOperator(ContainerOperator cont, ComponentChooser chooser)
  3. JTabbedPaneOperator(ContainerOperator cont, ComponentChooser chooser, int index)
  4. JTabbedPaneOperator(ContainerOperator cont, int index)
  5. JTabbedPaneOperator(ContainerOperator cont, java.lang.String text)
  6. JTabbedPaneOperator(ContainerOperator cont, java.lang.String text, int index)
  7. JTabbedPaneOperator(ContainerOperator cont, java.lang.String text, int tabIndex, int index)
  8. JTabbedPaneOperator(javax.swing.JTabbedPane b)

While the constructors available differ from Operator to Operator, JTabbedPaneOperator gives us a good selection to walk you through. If the object you're trying to find can have a title, you're generally going to want to use 5 from the list above. This basically says, "Start here and use the first one you find with this title." Usually you will only have one object with a given title, but just in case you have more than one, you can use number 6. The int you're passing is the zero-based index of the object you're looking for. For example, if there were two items with the title "foo" then you would write the following to get the second one:

new JTabbedPaneOperator(myJFrameOperator, "foo", 1);

When you're hunting for objects with unknown titles or that have no title, you can use number 4.

You'll notice that a number of the constructors take a ComponentChooser as one of their parameters. Different ComponentChoosers take different arguments depending on the type of object they're trying to find. In the case of the JtabbedPaneOperator, you should use a JTabbedPaneOperator .JtabbedPaneByItemFinder, which takes a String and int, and optionally, an Operator.StringComparator. It uses the String and int to compare to the titles of JTabbedPane objects it encounters at the index denoted by the int. Other ComponentChoosers work differently based on the type of Swing object they're testing, but they all essentially take the parameters you give them and use them to compare against objects of the appropriate type that it finds. In general, you don't have to do this because the object will just create, and use, a ComponentChooser for you.