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 >
|