bitrazor.com ...THE source for mediocre content                                      

Day 3: Real TiVo Test; Adding Menu Items             

<< Back to Tutorial Home< Back to Day 2 - Forward To Day 4 >

Now it's time to try the app on our real TiVo box, just to be sure everything's OK.  Then, we'll add some more stuff to the app to make it do something useful.

Checklist of Steps

  • Run the app and check your TiVo. details
  • Add a couple menu items. details
  • Test it out. details
  • Replace the text items with actual screens. details
  • Test it in the Simulator. details
  • If you're having problems... details

Run the app and check your TiVo.

Do 'Run - Run', then find the TrafficCam run configuration we created yesterday, then click Run.  The application should run, just like yesterday, and you'll see similar output in the console window in Eclipse. 

  • Go over to your TiVo box, go to the TiVo menu, and select 'Music, Photos, & More'.  (Yours might say 'Music, Photos, Products, & More.) 
  • You should see something in the list that says 'TrafficCam Viewer' with a little banana-bunch icon next to it.  Select it, and you should see the same screen as you did on the simulator.  Yay!
  • Hit the TiVo button to exit the application.
  • To kill the application in Eclipse, click the red square to the right of the Console tab:

OK, now you're set up to test your app at any time, either on the simulator, or on your real TiVo.  Now, let's add some meat to our initial screen.

Add a couple menu items.

For our initial screen, we're going to add just two items: 'View Cameras' and 'Setup'.  If you've looked at the Bananas sample code, you'll see that this is pretty easy (see MainMenuScreen.java in the Bananas source).

First, let's add a helper class called 'TextItemList' we can call to create the items for us. Click on the com.bitrazor.tivo.trafficcam package, then click the New Class button on the toolbar (it looks like this: ).  Name the class 'TextItemList', then click 'Finish'.

Add the following contents to TextItemList.java:     (download source of TextItemList.java)

package com.bitrazor.tivo.trafficcam;

import com.tivo.hme.bananas.BList;
import com.tivo.hme.bananas.BText;
import com.tivo.hme.bananas.BView;

// Highly leveraged from Bananas sample source
public class TextItemList extends BList {

    public TextItemList(BView parent, int x, int y, 
            int width, int height, int rowHeight) {
        super(parent, x, y, width, height, rowHeight);
        setBarAndArrows(BAR_HANG, BAR_DEFAULT, "pop", H_RIGHT);
        getHighlights().setWhisperingArrow(H_UP, A_CENTER, A_TOP, H_UP);
    }

    protected void createRow(BView parent, int index) {
        BText text = new BText(parent, 20, 0, parent.getWidth()-40, parent.getHeight());
        text.setFlags(RSRC_HALIGN_LEFT);
        text.setValue(get(index));
    }
}

Now bring up InitialScreen.java and add the following lines just below super(app); :

TextItemList list = new TextItemList(getNormal(), SAFE_TITLE_H, 225, 250, 200, 40);
list.add("View Traffic Cameras");
list.add("Setup");
setFocusDefault(list);

Your InitialScreen.java should look something like this: 

Test it out.

Notice that the Run button in the toolbar remembers the last few run configurations you used:

In my example above, 'TrafficCam - Simulator' is listed first (since it was the last one I used), so I could just click the Run button to run my app in the Simulator.  Or, I could drop down the menu shown above and pick it from the list.  Run your app, and you should see something like this in the Simulator:

Replace the text items with actual screens.

Well, that's nifty & all, but we really want to have new screens come up when we select those items.  Let's go ahead and create two new classes now:

  • Select the com.bitrazor.tivo.trafficcam package.
  • Click the New Class button ().
  • Enter 'ViewScreen' for the class name and click Finish.
  • Click the New Class button ().
  • Enter 'SetupScreen' for the class name and click Finish.

Fill in the Classes

For now, we'll put two TextItemList items on the setup screen, and one text string on the view screen.  To do this, add the following contents to your classes:

SetupScreen.java     (download source of SetupScreen.java)

package com.bitrazor.tivo.trafficcam;

import com.tivo.hme.bananas.BApplication;

public class SetupScreen extends ScreenTemplate {
    public SetupScreen(BApplication app) {
        super(app);

        TextItemList list = new TextItemList(getNormal(), SAFE_TITLE_H,
            225, 400, 200, 40);
        list.add("Choose Region");
        list.add("Change Camera Rotation Time");
        setFocusDefault(list);
    }

    public String toString() {
        return "TrafficCam Setup";
    }
}

ViewScreen.Java     (download source of ViewScreen.java)

package com.bitrazor.tivo.trafficcam;

import com.tivo.hme.bananas.BApplication;

public class ViewScreen extends ScreenTemplate {
    public ViewScreen(BApplication app) {
        super(app);
    }

    public String toString() {
        return "View Traffic Cameras";
    }
}

Change InitialScreen to Call These New Screens

Create the ScreenList Helper Class

One last change we have to make: instead of displaying a TextItemList, we really want the items that show up on our initial screen to call those two new screen we just created.  To do this, we're first going to create a helper class called ScreenList.  Same instructions as before: select the package, click the new class button, type in the name 'ScreenList', click Finish.  Add the following contents:

ScreenList.java     (download source of ScreenList.java)

package com.bitrazor.tivo.trafficcam;

import com.tivo.hme.bananas.BEvent;
import com.tivo.hme.bananas.BList;
import com.tivo.hme.bananas.BText;
import com.tivo.hme.bananas.BView;

// Heavily leveraged from the Bananas sample source
class ScreenList extends BList {

    public ScreenList(BView parent, int x, int y, int width,
            int height, int rowHeight) {
        super(parent, x, y, width, height, rowHeight);
        setBarAndArrows(BAR_HANG, BAR_DEFAULT, null, "push");
    }


    protected void createRow(BView parent, int index) { 
        BText text = new BText(parent, 10, 4, parent.getWidth()-40,
            parent.getHeight() - 4);
        text.setShadow(true);
        text.setFlags(RSRC_HALIGN_LEFT);
        text.setValue(get(index).toString());
    }

    public boolean handleKeyPress(int code, long rawcode) {
        switch (code) {
            case KEY_SELECT:
                postEvent(new BEvent.Action(this, "push"));
                return true;
        }
        return super.handleKeyPress(code, rawcode);
    }
}

Update ScreenTemplate to Allow Return to Parent Screen

While we're in here, let's make a couple improvements to ScreenTemplate.  We'll move the setting of the title to its own method for cleanliness, and we'll add a keypress handler so that if the left key on the remote is pressed, the screen will return to its parent (the screen that called it originally).

ScreenTemplate.java     (download source of ScreenTemplate.java)

package com.bitrazor.tivo.trafficcam;
import java.awt.Color;

import com.tivo.hme.bananas.BApplication;
import com.tivo.hme.bananas.BScreen;
import com.tivo.hme.bananas.BText;

public class ScreenTemplate extends BScreen { 

    public ScreenTemplate(BApplication app) {
        super(app);

        // Set background and title
        getBelow().setResource("blue.jpg"); 
        setTitle(this.toString());

    }

    // Set the title of the window in a safe area of the screen.
    private void setTitle(String t) {
        BText title = new BText(getNormal(), SAFE_TITLE_H+100, SAFE_TITLE_V, 
            (getWidth()-(SAFE_TITLE_H*2))-100, 54);
        title.setValue(t);
        title.setColor(Color.yellow);
        title.setShadow(Color.black, 3);
        title.setFlags(RSRC_VALIGN_TOP);
        title.setFont("default-48.font");
    }

    // If the left key is pressed, return to the calling screen.
    public boolean handleKeyPress(int code, long rawcode) {
        switch (code) {
            case KEY_LEFT:
                getBApp().pop();
                return true;
        }

        return super.handleKeyPress(code, rawcode);
    }

}

Changing InitialScreen To Use It

Modify InitialScreen.java so it looks like this now:

InitialScreen.java     (download source of InitialScreen.java)

package com.bitrazor.tivo.trafficcam;

import com.tivo.hme.bananas.BApplication;
import com.tivo.hme.bananas.BScreen;
import com.tivo.hme.bananas.BView;

public class InitialScreen extends ScreenTemplate {
    ScreenList list;
    public InitialScreen(BApplication app) {
        super(app);

        list = new ScreenList(getNormal(), SAFE_TITLE_H + 10,
                (getHeight() - SAFE_TITLE_V) - 290, 300, 280, 35);
        list.add(new ViewScreen(getBApp()));
        list.add(new SetupScreen(getBApp()));
        setFocusDefault(list);
    }

    public boolean handleAction(BView view, Object action) {
        if (action.equals("push")) {
            BScreen screen = (BScreen) (list.get(list.getFocus()));
            getBApp().push(screen, TRANSITION_LEFT);
            return true;
        }
        return super.handleAction(view, action);
    }

    public boolean handleKeyPress(int code, long rawcode) {
        switch (code) {
        case KEY_LEFT:
            getBApp().setActive(false);
            return true;
        }

        return super.handleKeyPress(code, rawcode);
    }

    public String toString() {
        return "Traffic Cam Viewer";
    }
}

Test it in the Simulator.

Hit the Run button, and your app should run.  Notice that you can now navigate back and forth between the screens using the left and right buttons on your remote (or the left and right arrow keys on your keyboard if you're using the Simulator).

If you're having problems...

If you're having problems and you just want to grab a full copy of my project, here is the zip file.  It contains the entire contents of my Eclipse workspace, so you can sync back up.  Your best bet is to extract just the Java source files out of it, and put them over top of your versions of the files.  Make a backup copy of your files someplace first.

<< Back to Tutorial Home< Back to Day 2 - Forward To Day 4 >

                                                         Last updated: August 25, 2006