Chapter 3: Bananas Widgets

This chapter describes the four widgets contained in the Bananas User Interface Toolkit


The BButton widget provides focus management and event handling for a button. The BButton widget consists of these elements:

This class provides a view with highlights; typically you will also add text to it using either BText or setResource(). The Bananas sample code shows creating different types of buttons (

Figure 3-1. Bananas sample buttons

There are four versions of the setBarAndArrows() method for this class. The simplest version allows you to specify the action to associate with the left and right whispering arrows. When the user presses the LEFT ARROW or RIGHT ARROW key, the corresponding action is fired:

void setBarAndArrow(Object action_left,
                    Object action_right) 

If the parameter is NULL, the whispering arrow is omitted.

The sample code uses the most complex version:

void setBarAndArrows(int bar_left,  
                     int bar_right,  
                     java.lang.Object action_left, 
                     java.lang.Object action_right, 
                     java.lang.Object action_up, 
                     java.lang.Object action_down,  
                     boolean inside) 

The bar_left parameter specifies the indentation for the left side of the button, as follows:

Similarly, the bar_right parameter specifies the alignment for the right side of the button.

The action_left, action_right, action_up and action_down parameters refer to the four possible arrows you can associate with a BButton. (If the parameter is NULL, the arrow is omitted.) Each arrow can be associated with an action object defined by you, or it can specify a pre-defined action, such as:

See “Custom Sounds” in Chapter 2 for an example of overriding the default behavior of actions.

The Boolean value for the inside parameter specifies whether to put the left and right whispering arrows inside (TRUE) or outside (FALSE) the button. The up and down whispering arrows are always outside the button and are not affected by this parameter.

Here is the sample code to create the first button, which has highlights outside the button and a text resource that says “A Standard Button.”

boolean highlights_inside = false; 
BButton stdrdButton = new BButton(getNormal(), 
                                  (getWidth()/2)-150, top, 
                                  300, 30); 
stdrdButton.setBarAndArrows(BAR_DEFAULT, BAR_DEFAULT, "pop", 
                            null, null, H_DOWN, 
                        Color.white, "A Standard Button")); 


The BText widget provides an easy way for you to specify colors, styles, alignment, and shadows for a text object. This widget is a BView that displays a text resource. The value of the BText widget is the text string. The Bananas sample illustrates setting different text attributes (

Figure 3-2. Sample Bananas text attributes

As this figure shows, the BText widget contains methods for specifying:

This widget also uses resource flags to set these attributes:

The following resource flags, defined in IHmeProtocol, are set with the BText.setFlags() method:

For example, here is the sample code to create the centered italic text:

BText italicText = new BText(getNormal(), border_left, top, 
                             text_width, 30); 
italicText.setValue("Italic text"); 

Here is the sample code to create text with a custom shadow (custom color and offset by 5 pixels):

BText shadowSample2 = new BText(getNormal(), border_left, top, 
                                text_width, 50); 
shadowSample2.setFlags(IHmeProtocol.RSRC_HALIGN_LEFT | 
shadowSample2.setShadow(new Color(255, 200, 200), 5); 
shadowSample2.setValue("Text with a custom shadow"); 


The BList widget provides built-in event handling for the UP, DOWN, CHANNEL UP, and CHANNEL DOWN keys. It also provides focus management and scrolling behavior (if the list does not fit on one screen). The BList widget consists of several elements:

Although the bar and arrows are “built-in” to this widget, you do need to call setBarAndArrows() in the BList constructor to set certain parameters for the highlights.

Creating a List

BList is an abstract class, so you always need to create your own subclass. (The BList class does not handle drawing of the list items.) In the constructor for your subclass, call setBarAndArrows() to specify the highlights. Then, override the createRow() method, which adds a row to the list, and the setFocus() method, which sets the focus on the desired view. You can add a single object, an array of objects, or a vector of objects (see “Performance Tip,” below).

Performance Tip

If you know the full set of row objects ahead of time, add the objects as an array or vector rather than adding them one at a time. This technique is especially important with large lists because the default behavior turns painting off and on for each call to list.add(object). The following code illustrates the preferred method for adding rows to a list:

BList list = new BList(...); 
Vector objVec = getObjectVector(); 

The following technique should be used only when the elements are not known at list creation time. It requires considerable processing overhead:

//NOT recommended, especially for large lists 
BList list = new BList(...); 
ArrayList objList = getObjectArray(); 
Iterator it = objList.iterator(); 
while (it.hasNext()) 
   Object obj =; 

Sample Code

The Bananas Toolkit sample code ( illustrates how to override BList to create three different list styles:

Figure 3-3. Bananas sample lists

Example 1: Standard List

The first list is a standard list that has an icon (a star) at the beginning of each row. It includes a call to setBarAndArrows() in its constructor:

static class StandardList extends BList  
// Constructor 
   public StandardList(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); 

The setBarAndArrows() method has the following syntax:

void  setBarAndArrows(int bar_left,  
                      int bar_right,  
                      java.lang.Object action_left, 
                      java.lang.Object action_right)  

The bar_left parameter specifies the indentation for the left side of the scroll bar, as follows:

Similarly, the bar_right parameter specifies the indentation for the right side of the scroll bar, as follows:

The last two parameters in this method (action_left and action_right) are strings that indicate the actions associated with the left and right highlight arrows. Specifying NULL for one of these parameters omits the highlight arrow. As shown in these examples, possible values are:

When List 1 has focus, pressing LEFT ARROW pops the screen; pressing RIGHT ARROW moves the focus to the right.

The createRow() method for this list creates a row with two views: an icon view and a text view:

protected void createRow(BView parent, int index) 
   BView icon = new BView(parent, 20, 0, 34, 
   BText text = new BText(parent, 60, 0, 
   // Set the value of the row to be the text that 
   // was passed in through add() 

The text in each row is left-aligned (RSRC_HALIGN_LEFT) and has a shadow.

Example 2: List with Icon Showing Focus

The second list overrides the handleFocus() method to add an icon to the focused row. It changes the location of iconView (the musical note) depending on the focus. Whenever the focused row changes, the handleFocus() method is called twice, once for the row that loses focus (to remove the icon) and once for the row that gains the focus (to add the icon). This list is longer than one screen and illustrates the built-in BList scrolling mechanism. Call BHighlights.setPageHint() to add the Page Up/Page Down icons to scrolling lists.

Here is the handleFocus() method for List 2:

public boolean handleFocus(boolean isGained, BView gained, 
                           BView lost)  
// We really only care when we gain focus and when we do, we 
// set the icon to be on the row that just gained focus. 
// If we gain focus and the previous focus was not this list, 
// then we jump the icon directly to the new focused item. 
// Otherwise, we animate it at the same speed as the bar so 
// that it looks like it is part of the bar. 
   if (isGained && gained.getParent() == this) { 
      if (lost.getParent() == this) { 
         iconView.setLocation(30, gained.getY()+3, 
      } else { 
      // gaining focus from another widget 
      iconView.setLocation(30, gained.getY()+3); 
   return super.handleFocus(isGained, gained, lost); 

Example 3: Right-Aligned List

The third list overrides createRow() to make the rows right-aligned. Note that it has only a left highlight arrow, so it handles only the LEFT ARROW key press.


The BKeyboard widget provides an onscreen keyboard that allows the user to spell out words on the television using the TiVo remote control. Your application can monitor the keyboard and respond to changes as the user enters characters in the text entry box above the keyboard. This widget thus provides basic keyboard functionality for your application without requiring additional hardware in the user’s living room.

Types of Standard Keyboards

There are two standard types of Bananas keyboards: the plain keyboard (Figure 3-4) and the e-mail keyboard (Figure 3-5). The e-mail keyboard has special characters used to enter e-mail addresses, such as the @ character, the suffixes .com, .org, and .net, and several punctuation marks (underscore and period).

Figure 3-4. Plain version of standard keyboard

Both the plain and e-mail keyboards have three versions: lowercase, uppercase, and symbol. The standard keyboards are named as follows:


Figure 3-4 shows the lowercase version of the plain keyboard. Figure 3-5 shows the uppercase version of the e-mail keyboard. Figure 3-6 shows the symbol version of the plain keyboard.

Figure 3-5. e-mail version of standard keyboard

Figure 3-6. Symbol version of standard keyboard

Standard Keyboard Behaviors and Options

As the user selects characters on the keyboard widget, they appear in the text entry box above the keyboard. After the user has entered one or more characters, the CLR button is visible. If the user presses CLR, that button toggles to UNDO (so that the user can retrieve the deleted text if desired).

Also built in to the standard keyboards is an optional tips area, which provides hints to the user on standard behavior for buttons on the remote. Both Figure 3-4 and Figure 3-5 include the Tips, which prompt the user to

The number keys and the CLEAR key on the remote can be used in place of the corresponding keyboard keys to enter and clear characters.

The width of the text entry box is customizable. The keyboard itself and Tips area are of fixed size and layout.

Sample Code

The following section discusses how the Bananas sample code ( creates three different keyboard widgets.

Creating a Keyboard Widget

The Bananas Toolkit sample creates three keyboards (see Figure 3-7):

Figure 3-7. Menu choices for BKeyboard sample

The BKeyboard class has three constructors. Typically, you will use one of the first two constructors listed here. Use the following simple constructor to create a plain standard lowercase keyboard, with the Tips area visible:

public BKeyboard(BView parent,   //parent view			
                 int x,			 //x position relative to parent
                 int y, //y position relative to parent
                 int width,      			//width of widget
                 int height)     //height of widget 

This second constructor allows you to specify which standard keyboard to use (either PLAIN_KEYBOARD or EMAIL_KEYBOARD) and to choose whether to display the Tips area or not:

public BKeyboard(BView parent,
                 int x,
                 int y,
                 int width,
                 int height,
                 int KeyboardType, //one of two types
                 boolean tips)    //include Tips area? 

The third constructor allows you to specify any keyboard object, to choose whether to display the Tips area, to specify a custom width for the text entry box, and to choose whether to display the keyboard itself.

public BKeyboard(BView parent,
                 int x,
                 int y,
                 int width,
                 int height,
                 Keyboard keyboard,
                 boolean tips,
                 int textEntryWidth,
                 boolean visible) 

Plain Keyboard

The first keyboard in the BKeyboard sample code (Figure 3-4) uses the simplest constructor to create a default keyboard. (This constructor creates the plain standard lowercase keyboard, includes the Tips area, and creates a text entry box of standard width.) Before you construct the keyboard, you need to call the helper function getKeyboardSize() to obtain the size of the keyboard, which is passed in to the constructor’s width and height parameters.

This code shows how the plain keyboard is created:

Point p = BKeyboard.getKeyboardSize(null, 
kb = new BKeyboard(getNormal(), 100, 140, p.x, p.y); 

e-Mail Keyboard

The second keyboard in the BKeyboard sample code uses the constructor that allows you to pass in a keyboard type and to specify whether Tips are visible. This example creates a keyboard of type EMAIL_KEYBOARD. As described above, you first need to call the helper function getKeyboardSize() to obtain the size of the keyboard, which is passed in to the constructor’s width and height parameters.

This code shows how the e-mail keyboard is created:

Point p = BKeyboard.getKeyboardSize(
kb = new BKeyboard(getNormal(), 100, 140, p.x, p.y,
                   BKeyboard.EMAIL_KEYBOARD, true); 

Plain Keyboard with Scrolling Text Area

The third keyboard in the BKeyboard sample code uses the most detailed constructor, which allows you to pass in any keyboard object, to specify the width of the text entry box, and to specify whether Tips are visible. (See Figure 3-8).

Figure 3-8. Keyboard with scrolling text area

This constructor requires use of this form of the getKeyboardSize() function:

static public Point getKeyboardSize(Keyboard keyboard,  
                            boolean tips, int textEntryWidth) 

This code shows how the third keyboard is created:

Point p = 
kb = new BKeyboard(getNormal(), 100, 150, p.x, p.y,

Handling Events

In the Bananas Toolkit sample, the third keyboard monitors and responds to keyboard events. The handleEvent() method in the sample monitors the characters typed into the text entry box and updates the scrolling word list at the right accordingly:

//handle a change in the value of the BKeyboard by 
//updating the related text field 
public boolean handleEvent(HmeEvent event) { 
   if (event instanceof KeyboardEvent) { 
   return super.handleEvent(event); 

In this example, the getValue() method returns a string that is the current value displayed in the text entry box of the BKeyboard widget.