Notepad Tutorial

In this example, we will develop a basic robot, which will be able to use the notepad for typing text. We will see several ways to make our robot wait for an application to open.

Source Code

Description Link
Source Code robot-tutorial-notepad.zip

Configuration

Environment

  • Development:
    • IDE: Eclipse
    • JDK 1.8
    • Maven 3
    • Appian RPA modules:
      • Client
  • Resource:
    • OS: Windows
    • JRE 1.8
    • Applications:
      • Notepad

Eclipse Project

You must import the Eclipse project included in the zip file attached at the beginning of this tutorial. After importing the project, it is very important to modify the pom.xml file. You have to fill in the parent tag with the version of Appian RPA you are using, and change the profile tag with the configuration of your repository.

Workflow

In essence, the workflow of this robot is identical to the previous ones. Initializing, opening the application, performing operations and ending the execution by closing the application.

You must to create a new Workflow with this structure.

rpa-notepad-workflow.png

You can import this workflow using this file. To import the workflow, you have to click in the import button (2233684.png), and paste the data included in the file.

Implementation

The main class of this robot, called NotepadRobot, declares the typical attributes that we have seen so far, including the specific items for this example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Robot
public class NotepadRobot implements IRobot {

    /**
     * Regular expression to search the window for the application Notepad. It
     * changes depending on the platform language.
     */
    private static final String NOTEPAD_REGEXP = ".*(Bloc de notas|Notepad)";

    /**
     * Default pause between actions imitating human behavior.
     */
    private static final int PAUSE = 500;
    
    /**
     * Items to process.
     */
    private static final String[] ITEMS = new String[] {
            "This is the "Hello World!" Appian RPA Robot",
            "It shows how to write into the notepad"
    };
    
    /**
     * Server.
     */
    private IJidokaServer< ? > server;
    
    /**
     * Windows module.
     */
    private IWindows windows;
    
    /**
     * Current item index. The first one is the number '1'.
     */
    private int currentItemIndex = 1;

The method startUp and init are similar to the previous robots.

Now, we will focus on the method openNotepad, of which we will show two different ways to make the robot wait for the notepad to open.

Let's see the code for the first one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* Action 'Open Notepad'.
*


* First way to open Notepad.
*/
public void openNotepadAlt1() {

    try {
        // Win+R
        client.keyboard().windows("r").pause().type("notepad").enter().pause();

        // Wait during 10 seconds until the application window is present
        if (client.waitFor(this).window(10, NOTEPAD_REGEXP) == null) {

            /*
             * If the window is not present at the end of the wait, the robot must fail.
             */
            throw new JidokaFatalException("Notepad could not be opened");
        }

        // Maximize the window
        client.showWindow(client.getWindow(NOTEPAD_REGEXP).getId(), EClientShowWindowType.MAXIMIZE);
    } catch (Exception e) {
        throw new JidokaFatalException("Error opening notepad");
    }
}

The first way uses the method waitFor of the instance windows, which is an alias of getWaitFor, and receives an IRobot type parameter. Our robot, like every Appian RPA robot, is an instance of this type, so we will pass this as an argument. It will return an instance of type IWaitFor, which includes some predefined methods for waiting. This is the case of the method window, which receives as parameters the maximum waiting time in seconds and a regular expression. The method will try to match this regular expression with the title of the opened windows available and will return the regular expression itself in case the window is found, or null otherwise. We decide to throw an exception of type JidokaFatalException in case the application cannot open, though by implementing the wait in this way, we have the advantage of handling the situation with any other strategy, without throwing exceptions.

Now, we will see the code of the second way to open the notepad:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Action 'Open Notepad'.
*


* Second way to open Notepad.
*
* @throws JidokaUnsatisfiedConditionException if some conditions are not met
*/
public void openNotepadAlt2() throws JidokaUnsatisfiedConditionException {

    try {
        // Win+R
        client.keyboard().windows("r").pause().type("notepad").enter().pause();

        // Using a custom condition for waiting
        client.waitCondition(10, 1000, "Wait for Notepad to be opened", null, true,
                (i, c) -> client.getWindow(NOTEPAD_REGEXP) != null);

        // Maximize the window
        client.showWindow(client.getWindow(NOTEPAD_REGEXP).getId(), EClientShowWindowType.MAXIMIZE);
    } catch (Exception e) {
        throw new JidokaFatalException("Error opening notepad");
    }
}

We accomplish it by using waitCondition, but instead of writing the condition from scratch, we use the functional interface ICondition. This way, we aim to obtain an existing opened window which matches the regular expression received as an argument, following the same logic as in the previous alternative.

The functional interface ICondition includes the implementation of the method satisfied, which can be called by using lambda expressions.

We will throw an exception or not, depending on the value of the corresponding parameter of the method waitCondition (true or false).

Finally, in both alternatives the notepad is maximized through the method showWindow of the instance windows, to which we will pass as parameters the window's reference, of type HWND, and the way in which we want it to show itself, SW_MAXIMIZE in our case.

The next method shown below is processItem, responsible for performing the action "Process line" defined in the workflow. It will be called while there are items to process within the constant ITEMS.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Action 'Process line'.
*/
public void processItem() {

    try {
        // Get the current item
        String item = ITEMS[currentItemIndex - 1];

        /*
         * Notify the server the item treatment starts. Important to calculate
         * statistics and execution times. The second parameter is used to make it
         * easier to find registers in the execution log.
         */
        server.setCurrentItem(currentItemIndex, item);

        // Type the string into de Notepad and press Enter
        client.keyboard().type(item).pause().enter();

        /*
         * Notify the item result. In this case, a the detail message is not specified.
         */
        server.setCurrentItemResultToOK();
    } catch (Exception e) {
        throw new JidokaItemException("Error processing the item");
    }
}

Here, we will highlight that, through the method keyboard of IWindows, we get access to the instance IKeyboard, to write the text with the method type.

As in the robots of the previous tutorials, there will be a method to check whether there are items left to process. Depending on this, we will process the next items or end the robot's execution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * Action 'More?'.
 * 
 * @return the wire name
 */
public String hasMoreItems() {
    
    if (currentItemIndex == ITEMS.length) {
        // All items have been processed
        return "no";
    }

    // There are more items to process
    currentItemIndex++;
    
    return "yes";
}

The method end, as in the other robots, is an empty method once again, which represents only the last action of our robot.

1
2
3
4
5
6
/**
 * Action 'End'.
 */
public void end() {
    // Continue the process. At this step, the robot ends its execution
}

Finally, just like in the previous robot, we close Notepad to leave the resource in the same status as it was before the beginning of our robot execution. To do so, remember that we can use the method cleanUp, where we will use the method killAllProcesses of IWindows.

1
2
3
4
5
6
7
8
9
10
11
/**
 * @see com.novayre.jidoka.client.api.IRobot#cleanUp()
 */
@Override
public String[] cleanUp() throws Exception {
    
    // Close all Notepad instances
    windows.killAllProcesses("notepad.exe", 500);
    
    return new String[0];
}

Execution

Follow the same steps as Calculator Tutorial.


This version of the Appian RPA documentation was written for Appian 20.4, and does not represent the interfaces or functionality of other Appian versions.
Open in Github Built: Mon, Nov 15, 2021 (03:03:53 PM)

On This Page

FEEDBACK