How do you switch screens in a BlackBerry application?

You’re writing a BlackBerry application with several screens. How do you change from one screen to another?

If you are in the event thread (the default thread your program runs on if it’s a UI application and you haven’t started any other threads), then opening up another screen can be done by calling the pushScreen() method of the UiApplication class.

Since, in a typical case, your application derives from UiApplication, you would take a reference to your application object and call pushScreen() on it with the parameter of your new screen:

myApp.pushScreen(new MyNewScreen());

If you’re running in a worker thread, or in any context where you either don’t have access to a UiApplication or pushing a screen would not be allowed (you’re only allowed to work with UI components on the original UI thread), then pushing a screen onto the screen stack is a bit different — you need to switch to the UI thread, and then push the new screen onto the screen stack:

Application.getApplication().invokeLater(
    new Runnable() {
        public void run() {
            Ui.getUiEngine().pushScreen(new MyNewScreen());
        }
    }
);

At Antair, we have a simple ScreenChanger class that’s part of a larger internal library that we use for all of our projects. Here’s a stripped-down version of the ScreenChanger class for you to use.

// -----------------------------------------------------------------------------
//
// Antair Library for BlackBerry Devices
// ScreenChanger.java
// Copyright (c) 2005 - 2011, Antair Corporation. All Rights Reserved.
//
// -----------------------------------------------------------------------------
 
 
package com.antair.blackberrylib.ui;
 
 
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.Ui;
 
 
interface ScreenChangerListener
{
    void onScreenChangeComplete(Screen openedScreen, Screen closedScreen);
}
 
 
final class ScreenChanger
{
    static void change ( Screen screenToOpen, ScreenChangerListener listener )
    {
        ScreenChanger.change(screenToOpen, null, listener);
    }
 
 
    static void change ( Screen screenToOpen, Screen screenToClose,
        ScreenChangerListener listener )
    {
        Application.getApplication().invokeLater(
            new EventThreadScreenChanger(screenToOpen, screenToClose, listener));
    }
 
 
    static void close ( Screen screenToClose, ScreenChangerListener listener )
    {
        Application.getApplication().invokeLater(
            new EventThreadScreenChanger(null, screenToClose, listener));
    }
}
 
 
final class EventThreadScreenChanger extends Thread
{
    Screen _screenToOpen;
    Screen _screenToClose;
    ScreenChangerListener _listener;
 
 
    EventThreadScreenChanger ( Screen screenToOpen, Screen screenToClose,
        ScreenChangerListener listener )
    {
        _screenToOpen = screenToOpen;
        _screenToClose = screenToClose;
        _listener = listener;
    }
 
 
    public void run()
    {
        if ( _screenToOpen != null )
        {
            try
            {
                Ui.getUiEngine().pushScreen(_screenToOpen);
            }
            catch ( Exception e )
            {
                // Your error handler
            }
        }
 
        if ( _screenToClose != null )
        {
            try
            {
                Ui.getUiEngine().popScreen(_screenToClose);
            }
            catch ( Exception e )
            {
                // Your error handler
            }
        }
 
        if ( _listener != null )
        {
            _listener.onScreenChangeComplete(_screenToOpen, _screenToClose);
        }
    }
}