Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Highlighted
New Developer
Posts: 17
Registered: ‎02-09-2010
My Device: Blackberry 9000
My Carrier: None

Classes to help switch from one screen to the next...

Greetings,

               I have created some classes that extend Screen  with a ListField and Dialog which permits easy navigation from a screen to the next. When creating a dialog box you can set the next screen that will be presented to the user when the dialog has a result of Dialog.OK. Furthermore BasicSelectionScreen has a parameter in its contains for each list item an associated screen. If present, when that item is selected, the associated screen in the screens array is called. Of course, I am a new developer to the Blackberry , so i'm no expert and this might be unduly complicated. But i wanted to share my code with you, and fi you have comments or suggestions to improve it, be my guest.

 

p.s: Currently, even though the parameters permit it, the ListField does not display any graphics, i still need to implement it.

 

 

/** Implements a basic dialog box. This dialog box
 *  inherits from the Dialog class, and also implements
 *  a way to indicate the next screen that should appear
 *  after this screen if the selection of the dialog
 *  box is OK. The next screen parameter can be set
 *  to null if there is no next screen associated
 *  with this dialog.
 *  
 * @author Carl Eric Codere
 *
 */
public class BasicDialog extends Dialog
{
  /** The next screen to display after this dialog
   *  box is successfully executed.
   */
  private Screen nextScreen;

  /**
   *
   * @param next Indicates the next screen after this dialog box
   *   has been executed without canceling it. The value can
   *   be null in the case when the current screen should
   *   be kept.
   * @param message   Text message to display in the dialog
   * @param choices Objects selectable by the user. Each object is displayed using Object.toString().
   * @param values If this parameter is specified, instead of returning the index selected, doModal() returns
   *   the value associated with this index (useful for adding CANCEL).
   * @param defaultChoice Initial choice selected when the Dialog is displayed. If you
   *   provide a non-null values parameter, the default choice must be present in the
   *   values array. If the values parameter is null, the default choice is the index
   *   of the initially selected item.
   * @param bitmap - Image to display in the left side of the dialog.
   * @param style - Screen or Manager style.
   */
  public BasicDialog(Screen next, String message, Object[] choices, int[] values, int defaultChoice, Bitmap bitmap, long style)
  {
     super(message, choices, values, defaultChoice, bitmap, style);
     nextScreen = next;
  }
 
 
 /** This returns the next screen that should be displayed to the user
  *  when the user successfully executed the dialog box. The return
  *  value can be null if there is no next screen to display.
  *   
  * @return
  */
 public Screen getNextScreen()
 {
   return nextScreen;
 }
}

 


/** This class implements a basic selection screen that permits
 *  the selection of one item from a choice of selections. It automatically
 *  handles adding a banner and a title to the correct areas of the string.
 *  
 *  Furthermore, the actual items of the selection can also be displayed using a
 *  bitmap object which must be of the same height as the default text.
 *   
 *  It also handles pushing and popping directly to the next screen using arrays,
 *  and also handles back functionality if setPreviousScreen() is called.
 *  
 * @author Carl Eric Codère
 *
 */
public class BasicSelectionScreen extends MainScreen implements MFSApplicationResource
{
  /** Contains the actual items in the list */
  private Vector stringList;
  /** Contains the actual images in the list */
  private Vector imageList;
  /** Contains the actual screens associated with these items when the
   *  user selects that item.
   */
  private Screen[] screens;
  private ResourceBundle _resources;
  private UiApplication application;
  /** Points to the previous screen that created this screen, this is
   *  used for back functionality.
   */
  private Screen previousScreen;
 

  /** This is the actual callback used to manage the list items
   *  as well as display those list items on the screen.
   *   
   * @author Carl Eric Codère
   *
   */
  private class ListCallBack implements ListFieldCallback
  {

      private ListField _view;
      
      
      public ListCallBack(ListField view)
      {
          super();
          stringList = new Vector();
          imageList = new Vector();
          _view = view;
          _view.setCallback(this);
          // set the default row height
          _view.setRowHeight(32);
      }

      public void drawListRow(ListField listField, Graphics graphics,
              int index, int y, int width) {
          graphics.drawText((String)stringList.elementAt(index), 0, y, 0, width);
          //graphics.drawText(String.valueOf(index * 111), 0, y, DrawStyle.RIGHT, width);         
      }

      public Object get(ListField listField, int index) {
          // TODO Auto-generated method stub
          return (String)stringList.elementAt(index);
      }

      public int getPreferredWidth(ListField listField) {
          // Normally we should use the display width, but since
          // it is a restricted API, used this API instead.
          return  getMainManager().getWidth();         
      }

      public int indexOfList(ListField listField, String prefix, int start)
      {
          // TODO Auto-generated method stub
          return stringList.indexOf(prefix, start);
      }
      
      public void add(Object obj, Object img)
      {
          stringList.addElement(obj);
          imageList.addElement(img);
          // This should give the correct index into the value
          _view.insert(stringList.size() - 1);
      }
      
  }

  protected ListCallBack listCallback;
  /** Contains the actual visual menu select item */
  protected ListField menuList;
 
  // This is used to make sure that the ENTER key actually selects the
  // correct handler.
  protected boolean keyChar(char c, int status, int time)
  {
      int row;
      if (c == Characters.ENTER)
      {
          row = menuList.getSelectedIndex();
          // We only act if we actually have a menu selection item.
          if (row != -1)
          {
              // Call the method that actually execute the command.
              itemSelection(row);
              return true;
          }
      }
      if (c == Characters.ESCAPE)
      {
          // Call the back method
          back();
          return true;
      }
      // Handle all other keys as usual
      return super.keyChar(c, status, time);
  }
 
  // This is correct for the trackwheel and touch pad, but the enter
  // key contrary to the documentation does not select the current item!!
  // so we need to override keychar also!
  protected  boolean navigationClick(int status, int time)  
  {
      int row = menuList.getSelectedIndex();
      // We only act if we actually have a menu selection item.
      if (row != -1)
      {
          itemSelection(row);
          return true;
      }
      return super.navigationClick(status, time);
  }
 
  /** This method is called when the item is selected. The actual
   *  item selected is indicated by the row parameter. It should
   *  create and push the appropriate screens depending on the
   *  row value which is the value of the indexes of the items
   *  using a 1:1 mapping. The screen push is taken from the
   *  screens array which was passed at the constructor.
   *  
   */
  protected void itemSelection(int row)
  {
     Screen nextScreen = null;
     // If there is no next screen to display, do nothing.
     if (screens[row] == null)
     {
       
     }
     else
     {
        // Special handling for Dialog Boxes, we see if after
        // execution we must execute another screen or not.
        if (screens[row] instanceof BasicDialog)
        {
           BasicDialog dlg = (BasicDialog)screens[row];
           if (dlg.doModal() == Dialog.OK)
           {
             nextScreen = dlg.getNextScreen();
           }
        } else
        {
          nextScreen = screens[row];
        }
        if (nextScreen != null)
        {
           application.popScreen(this);
           application.pushScreen(nextScreen);
          
        }
         
     }
  }
 
  /** This is the constructor that builds the actual FieldList. It has
   *  several parameters which are important for the functionality of
   *  the list.
   *
   *  @param application Contains the instance of the application that
   *    created this screen. This is important for pushing and popping
   *    the different data.
   *  @param items Contains the items that will be displayed, each index
   *    of this array shall correspond to an optional elements in the images
   *    array and correspond to the next screen in the screens array.
   *  @param images Contains optionally the images that are associated
   *    with the items of the list.
   *  @param screens Contains the screens that will be executed when
   *    an item has been selected by the user. Normally, none of the
   *    items in this array should be null.
   *  @param title The actual title of this screen
   *  @param resources Resources associated with this screen (currently unused)
   */

  public BasicSelectionScreen(UiApplication application, String[] items, Bitmap[] images,
       Screen[] screens, String title, ResourceBundle resources)
  {
      int i;
      VerticalFieldManager vFieldManager;
      Bitmap bannerImage;
      _resources = resources;
      this.screens = screens;
      this.application = application;
      // Set the displayed title of the screen.       
      setTitle(title);
      vFieldManager = new VerticalFieldManager();
      bannerImage = Bitmap.getBitmapResource("img/banner.png");
      vFieldManager.add(new BitmapField(bannerImage,Field.FIELD_LEFT));
      vFieldManager.add(new SeparatorField(SeparatorField.LINE_HORIZONTAL));
      setBanner(vFieldManager);


      // Create the user interface element
      menuList = new ListField(0,0);
      // Create the callback of the user interface element
      listCallback = new ListCallBack(menuList);
      for (i = 0; i < items.length; i++)
      {
        listCallback.add(items[i],images[i]);
      }
      add(menuList);
  }

  /** Sets the previous screen that will be shown to the user when the
   *  users presses the ESCAPE button. This value is by default null
   *  which indicates that on the ESCAPE key, the application shall be closed.
   *   
   *  @param screen that is considered the previous screen
   */
  public void setPreviousScreen(Screen screen)
  {
    previousScreen = screen;
  }
 
  /** This method is called when the user clicks the ESCAPE button,
   *  the default behavior is to actually back up one screen unless
   *  this is the first screen of the application, in which cases
   *  it closes the application.
   *  
   */
  protected void back()
  {
    // If no previous screen close the application
    if (previousScreen == null)
    {
      close();
      return;
    }
    application.popScreen(this);
    application.pushScreen(previousScreen);
  }

  /**
   * Display a dialog box to the user with "Goodbye!" when the application
   * is closed.
   *
   * @see net.rim.device.api.ui.Screen#close()
   */
  public void close()
  {
      // Display a farewell message before closing application.
      Dialog.alert("Goodbye!");     
      super.close();
  }   

}

 

Here is some sample from the main constructor:

 

        // Push the main screen instance onto the UI stack for rendering.
      String[] choices = {"OK"};
      int[] values = {Dialog.OK};
      
      // This is a dialog box which will be displayed when String 1 of the
      // second listField is selected.
      BasicDialog dlg = new BasicDialog(null,"Hello dialog",choices,values,Dialog.OK,Bitmap.getPredefinedBitmap(Bitmap.INFORMATION),Dialog.GLOBAL_STATUS);
      
      
      String s[] = {"String 1", "String 2" };
      Bitmap  b[] = {null, null};
      // First selection pops up a dialog bo, otherwise, nothing done.
      Screen  scr[] = {dlg,null};
      BasicSelectionScreen secondList = new BasicSelectionScreen(this,s,b,scr,"My selection 1",_resources);;
      
      String s1[] = {"List item 1","List item 2" };
      Bitmap  b1[] = {null, null};
      Screen  scr1[] = {secondList,null};
      
      BasicSelectionScreen welcomeScreen = new BasicSelectionScreen(this,s1,b1,scr1,"My selection 1",_resources);;
      
      // For back operation, set the previous screen of this screen
      secondList.setPreviousScreen(welcomeScreen);
      pushScreen(welcomeScreen);      

Enjoy!!

-- Carl Eric Codère
New Developer
Posts: 17
Registered: ‎02-09-2010
My Device: Blackberry 9000
My Carrier: None

Re: Classes to help switch from one screen to the next...

Sorry forgot to indicate to comment out MFSApplicationResource in the class declarations to make it compile. But I am also wondering if it was the best way to handle next and previous screens?

 

Would it not be more intelligent to use a method getNextScreen() that each screen must implement in derived classes with a parameter indicating the next screen to display instead?

 

Any suggestion on how to easily switch from one screen to the next would be appreciated!

Carl Eric Codere

 

 

 

-- Carl Eric Codère
Developer
Posts: 17,019
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport
My Carrier: O2 Germany

Re: Classes to help switch from one screen to the next...

I didn't read your code, a bit too much. did you use the code tag?

 

For complex navigation i mostly use tabs, which means an unmutable bar at the top with buttons or text links. below is a manager area that changes. A vector can take care of some kind of history to go back to a past manager.

 

for simple navigation i just push a new screen.

 

in between i have some concepts with services, for example a method showScreenX that displays this screen.

 

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter