Back Home

How To Write the Back End

After the Learning Tool tutorial, the user should be able to create mock-ups: graphical user interfaces that look functional but aren't able to do anything. The next step is implementing a back end so the GUI will be functional.

Adjusting ELVIS Code for a Back-End

The first thing to do is adjust the ELVIS code to accomodate for a back end. For each element that can do something, there is an attribute associated with that action (or ActionListener for the Java inclined). ELVIS is able to handle elements that are clickable (derive from Clickable in the Widget Hierarchy) and elements that are selectable (TreeNode elements). These are two different types of actions, which is why they are treated differently. The values of these attributes are the method names that will be called when the action is fired.

While specifying the action as an attribute is simple enough, there needs to be one more change to the ELVIS code. There is a controller header above the other ELVIS code that actually builds the back-end interface. The syntax for the controller block is:

%controller {
    Action actionMethod1, actionMethod2; // all the methods called with onClick attribute.
    Tree nodeSelectionMethod1, nodeSelectionMethod2; // all methods called with onSelected attribute.
}

The Controller

For ELVIS code with a controller block, there will now be two files that are created when the code is translated into Java. There will still be the actual Java code, but now there will be a Controller interface as well. From the above controller block, the generated Controller interface will look like:

//import statements

public interface Controller {
    public void actionMethod1(Component widget, ActionEvent event);
    public void actionMethod2(Component widget, ActionEvent event);
    public void nodeSelectionMethod1(Component widget, TreeSelectionEvent event);
    public void nodeSelectionMethod2(Component widget, TreeSelectionEvent event);
}

Note that the Action parameters are different than the Tree parameters; this is why we have different names for listeners. Each method takes the Widget that fires the action and the event. This allows the back-end user to use almost any aspect of the element or the event.

The back-end programmer is reponsible for impolementing this interface and writing all the methods. The accessor and mutator methods for the widgets are helpful here.

Example: Button on a Window

The following example builds on the example in the Learning Tool Tutorial. It implements a back end for the button on a window so the title changes when you click the button.

Step 1: Change the ELVIS code and Re-Compile

Change the ELVIS code so it now looks like:

mockup: false;

%controller {
    Action changeTitle;
}

Window myWindow {
    title: "Window Title"; 
    Button myButton { 
        label: "Change the Title!"; 
        onClick: changeTitle;
    }
} 

Compile the code.

Step 2: Look at the Controller Interface

After compiling the code from the Learning Tool, go to the directory where the Java files were generated and look at Controller.java. It should look like the following:

import java.awt.Component;
import java.awt.event.ActionEvent;

public interface Controller {
    public void changeTitle(Component widget, ActionEvent event);
}

This means that there is one method that the back-end user must write: the changeTitle method.

Step 3: Write the Back-End

Now we are finally ready to write the back end. Create a new java file that implements the Controller interface. If the you had saved the original file as "WindowAndButton.gui," an example could be:

import java.awt.Component;
import java.awt.event.ActionEvent;

public class TitleChanger implements Controller {
    public static WindowAndButton wb;

    // main method
    public static void main(String[] args) {
        new TitleChanger();
    }

    // Constructor that instantiates the GUI.
    public TitleChanger() {
        wb = new WindowAndButton(this);
    }

    // Method to change the title name
    public void changeTitle(Component widget, ActionEvent event) {
        String currentText = wb.getWindowTitle(wb.myWindow);

        if (currentText.equals("Window Title"))
            wb.setWindowTitle(wb.myWindow,"CHANGED Window Title");
        else
            wb.setWindowTitle(wb.myWindow,"Window Title");
    }
}

Step 4: Run the Back-End Code

Now, by running the TitleChanger class (note that it has a main method), the button will be functional. So, by clicking the button on:

Window and Button Shot

You will see:

Changed Window and Button Shot