FileDocCategorySizeDatePackage
Alert.javaAPI DocJ2ME MIDP 2.035506Thu Nov 07 12:02:28 GMT 2002javax.microedition.lcdui

Alert

public class Alert extends Screen
An alert is a screen that shows data to the user and waits for a certain period of time before proceeding to the next Displayable. An alert can contain a text string and an image. The intended use of Alert is to inform the user about errors and other exceptional conditions.

The application can set the alert time to be infinity with setTimeout(Alert.FOREVER) in which case the Alert is considered to be modal and the implementation provide a feature that allows the user to "dismiss" the alert, whereupon the next Displayable is displayed as if the timeout had expired immediately.

If an application specifies an alert to be of a timed variety and gives it too much content such that it must scroll, then it automatically becomes a modal alert.

An alert may have an AlertType associated with it to provide an indication of the nature of the alert. The implementation may use this type to play an appropriate sound when the Alert is presented to the user. See {@link AlertType#playSound(javax.microedition.lcdui.Display) AlertType.playSound()}.

An alert may contain an optional Image. The Image may be mutable or immutable. If the Image is mutable, the effect is as if a snapshot of its contents is taken at the time the Alert is constructed with this Image and when setImage is called with an Image. This snapshot is used whenever the contents of the Alert are to be displayed. Even if the application subsequently draws into the Image, the snapshot is not modified until the next call to setImage. The snapshot is not updated when the Alert becomes current or becomes visible on the display. (This is because the application does not have control over exactly when Displayables appear and disappear from the display.)

Activity Indicators

An alert may contain an optional {@link Gauge} object that is used as an activity or progress indicator. By default, an Alert has no activity indicator; one may be set with the {@link #setIndicator} method. The Gauge object used for the activity indicator must conform to all of the following restrictions:

  • it must be non-interactive;
  • it must not be owned by another container (Alert or Form);
  • it must not have any Commands;
  • it must not have an ItemCommandListener;
  • it must not have a label (that is, its label must be null;
  • its preferred width and height must both be unlocked; and
  • its layout value must be LAYOUT_DEFAULT.

It is an error for the application to attempt to use a Gauge object that violates any of these restrictions. In addition, when the Gauge object is being used as the indicator within an Alert, the application is prevented from modifying any of these pieces of the Gauge's state.

Commands and Listeners

Like the other Displayable classes, an Alert can accept Commands, which can be delivered to a CommandListener set by the application. The Alert class adds some special behavior for Commands and listeners.

When it is created, an Alert implicitly has the special Command {@link #DISMISS_COMMAND} present on it. If the application adds any other Commands to the Alert, DISMISS_COMMAND is implicitly removed. If the application removes all other Commands, DISMISS_COMMAND is implicitly restored. Attempts to add or remove DISMISS_COMMAND explicitly are ignored. Thus, there is always at least one Command present on an Alert.

If there are two or more Commands present on the Alert, it is automatically turned into a modal Alert, and the timeout value is always {@link #FOREVER}. The Alert remains on the display until a Command is invoked. If the Alert has one Command (whether it is DISMISS_COMMAND or it is one provided by the application), the Alert may have the timed behavior as described above. When a timeout occurs, the effect is the same as if the user had invoked the Command explicitly.

When it is created, an Alert implicitly has a CommandListener called the default listener associated with it. This listener may be replaced by an application-provided listener through use of the {@link #setCommandListener} method. If the application removes its listener by passing null to the setCommandListener method, the default listener is implicitly restored.

The {@link Display#setCurrent(Alert, Displayable)} method and the {@link Display#setCurrent(Displayable)} method (when called with an Alert) define special behavior for automatically advancing to another Displayable after the Alert is dismissed. This special behavior occurs only when the default listener is present on the Alert at the time it is dismissed or when a command is invoked. If the user invokes a Command and the default listener is present, the default listener ignores the Command and implements the automatic-advance behavior.

If the application has set its own CommandListener, the automatic-advance behavior is disabled. The listener code is responsible for advancing to another Displayable. When the application has provided a listener, Commands are invoked normally by passing them to the listener's commandAction method. The Command passed will be one of the Commands present on the Alert: either DISMISS_COMMAND or one of the application-provided Commands.

The application can restore the default listener by passing null to the setCommandListener method.

Note: An application may set a {@link Ticker Ticker} with {@link Displayable#setTicker Displayable.setTicker} on an Alert, however it may not be displayed due to implementation restrictions.

see
AlertType
since
MIDP 1.0

Fields Summary
public static final int
FOREVER
FOREVER indicates that an Alert is kept visible until the user dismisses it. It is used as a value for the parameter to {@link #setTimeout(int) setTimeout()} to indicate that the alert is modal. Instead of waiting for a specified period of time, a modal Alert will wait for the user to take some explicit action, such as pressing a button, before proceeding to the next Displayable.

Value -2 is assigned to FOREVER.

public static final Command
DISMISS_COMMAND
A Command delivered to a listener to indicate that the Alert has been dismissed. This Command is implicitly present an on Alert whenever there are no other Commands present. The field values of DISMISS_COMMAND are as follows:
  • label = "" (an empty string)
  • type = Command.OK
  • priority = 0

The label value visible to the application must be as specified above. However, the implementation may display DISMISS_COMMAND to the user using an implementation-specific label.

Attempting to add or remove DISMISS_COMMAND from an Alert has no effect. However, DISMISS_COMMAND is treated as an ordinary Command if it is used with other Displayable types.

CommandListener
implicitListener
Special CommandListener instance to handle execution of the default "OK" Command
private static final Command
OK
Static default Command for "OK"
private static final int
CELL_SPACING
Default spacing between elements of this Alert
private static final int
SCROLL_AMOUNT
Number of pixels to scroll when using up/down keys
private static final int
DEFAULT_TIMEOUT
The default timeout of all alerts
private AlertType
type
The type of this alert
private String
text
The layout object for the alert text string
private Image
image
The image of this alert
private Image
mutableImage
A reference to the original, mutable Image passed to setImage(). This is only so getImage() can return the correct Image Object.
private Gauge
indicator
The activity indicator for this alert
private int
time
The timeout value of this alert
private int
height
The overall height of this alert
private static Timer
timeoutTimer
A Timer which serves all Alert objects to schedule their timout tasks
private TimerTask
timerTask
A TimerTask which will be set to expire this Alert after its timeout period has elapsed.
private Displayable
returnScreen
The screen which the display will return to when this Alert is completed
private CommandListener
userCommandListener
The application's command listener
Constructors Summary
public Alert(String title)
Constructs a new, empty Alert object with the given title. If null is passed, the Alert will have no title. Calling this constructor is equivalent to calling
Alert(title, null, null, null)

param
title the title string, or null
see
#Alert(String, String, Image, AlertType)


// *****************************************************
//  Constructor(s)
// *****************************************************

                                                          
       
        this(title, null, null, null);
    
public Alert(String title, String alertText, Image alertImage, AlertType alertType)
Constructs a new Alert object with the given title, content string and image, and alert type. The layout of the contents is implementation dependent. The timeout value of this new alert is the same value that is returned by getDefaultTimeout(). The Image provided may either be mutable or immutable. The handling and behavior of specific AlertTypes is described in {@link AlertType}. null is allowed as the value of the alertType parameter and indicates that the Alert is not to have a specific alert type. DISMISS_COMMAND is the only Command present on the new Alert. The CommandListener associated with the new Alert is the default listener. Its behavior is described in more detail in the section Commands and Listeners.

param
title the title string, or null if there is no title
param
alertText the string contents, or null if there is no string
param
alertImage the image contents, or null if there is no image
param
alertType the type of the Alert, or null if the Alert has no specific type


        super(title);

        synchronized (Display.LCDUILock) {
            this.time = DEFAULT_TIMEOUT;
            this.text = alertText;
            this.type = alertType;

            setImageImpl(alertImage);
        }
        layout();
    
Methods Summary
public voidaddCommand(Command cmd)
Similar to {@link Displayable#addCommand}, however when the application first adds a command to an Alert, {@link #DISMISS_COMMAND} is implicitly removed. Calling this method with DISMISS_COMMAND as the parameter has no effect.

param
cmd the command to be added
throws
NullPointerException if cmd is null

        if (cmd == null) {
            throw new NullPointerException();
        }

        if (cmd == DISMISS_COMMAND) {
            return;
        }

        synchronized (Display.LCDUILock) {
            super.addCommandImpl(cmd);
        }
    
voidcallHideNotify(Display d)
Notify this Alert that it will no longer be displayed on the given Display

param
d The Display showing this Alert

        super.callHideNotify(d);
        super.removeCommandImpl(OK);
        super.setCommandListener(null);
        if (timerTask != null) {
            try {
                timerTask.cancel();
                timerTask = null;
            } catch (Throwable t) { }
        }
    
voidcallKeyPressed(int keyCode)
Handle a key press

param
keyCode the key which was pressed

        int gameAction = Display.getGameAction(keyCode);
        switch (gameAction) {
            case Canvas.UP:
            case Canvas.DOWN:
                if (scrollViewport(gameAction)) {
                    repaintContents();
                }
                break;
            default:
                break;
        }
    
voidcallKeyRepeated(int keyCode)
Handle a key repeat

param
keyCode the key which was repeated

        callKeyPressed(keyCode);
    
voidcallPaint(Graphics g, java.lang.Object target)
Paint the contents of this Alert given the graphics context.

param
g The Graphics object to paint this Alert to
param
target the target Object of this repaint

        super.callPaint(g, target);

        // Vertically center alert content if the alert height
        // is less than the view port height.
        int yOffset = (viewport[HEIGHT] - height) / 2;
        if (yOffset < 0) {
            yOffset = 0;
        }
        int xOffset;

        // Translate into screen coordinates
        yOffset += viewport[Y] - view[Y];
        xOffset  = viewport[X] - view[X];

        // center and paint the image
        if (image != null) {
            int tX = (viewport[WIDTH] - image.getWidth()) / 2;
            if (tX < 0) {
                tX = 0;
            }
            tX += xOffset;

            g.translate(tX, yOffset);

            g.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);

            g.translate(-tX, -yOffset);

            // amount of space between Image and next component
            yOffset += image.getHeight() + CELL_SPACING;
        }

        // Paint the activity indicator
        if (indicator != null) {
            // We do not need to center the activity indicator.
            // That has already been done in the layout() method.
            int tX = indicator.bounds[X] + xOffset;

            g.translate(tX, yOffset);

            indicator.callPaint(g, viewport[WIDTH], viewport[HEIGHT]);

            g.translate(-tX, -yOffset);

            // amount of space between indicator and next component
            yOffset += indicator.bounds[HEIGHT] + CELL_SPACING;
        }

        // paint the text
        if (text != null) {
            g.translate(xOffset, yOffset);

            Text.paint(text, Screen.CONTENT_FONT, g, viewport[WIDTH] - xOffset,
                       (viewport[HEIGHT] + viewport[Y]) - yOffset, 0, 
                       Text.NORMAL, null);

            g.translate(-xOffset, -yOffset);
        }

        setVerticalScroll();
    
voidcallShowNotify(Display d)
Notify this Alert that is being displayed on the given Display and wether it needs to initialize its highlight

param
d The Display this Alert will be shown on


                                      
       
        super.callShowNotify(d);

        if (type != null) {
            d.playAlertSound(type);
        }

        layout();

        int timeout = getTimeout();
        if (timeout == FOREVER) {
            if (getCommandCount() == 0) {
                // Add implicit command
                super.addCommandImpl(OK);
            }
        } else {
            if (timeoutTimer == null) {
                timeoutTimer = new Timer();
            }
            timerTask = new timeoutTask(this);
            timeoutTimer.schedule(timerTask, timeout);
        }
        super.setCommandListener(implicitListener);
    
public intgetDefaultTimeout()
Gets the default time for showing an Alert. This is either a positive value, which indicates a time in milliseconds, or the special value {@link #FOREVER FOREVER}, which indicates that Alerts are modal by default. The value returned will vary across implementations and is presumably tailored to be suitable for each.

return
default timeout in milliseconds, or FOREVER

        synchronized (Display.LCDUILock) {
            return DEFAULT_TIMEOUT;
        }
    
public ImagegetImage()
Gets the Image used in the Alert.

return
the Alert's image, or null if there is no image
see
#setImage

        synchronized (Display.LCDUILock) {
            if (mutableImage != null) {
                return mutableImage;
            } else {
                return image;
            }
        }
    
public GaugegetIndicator()
Gets the activity indicator for this Alert.

return
a reference to this Alert's activity indicator, or null if there is none
see
#setIndicator
since
MIDP 2.0

        // SYNC NOTE: no locking necessary
        return indicator;
    
DisplayablegetReturnScreen()
Get the screen the display should return to when this Alert is dismissed.

return
The Displayable to display when this Alert is completed

        return returnScreen;
    
public java.lang.StringgetString()
Gets the text string used in the Alert.

return
the Alert's text string, or null if there is no text
see
#setString

        // SYNC NOTE: no locking necessary
        return text;
    
public intgetTimeout()
Gets the time this Alert will be shown. This is either a positive value, which indicates a time in milliseconds, or the special value FOREVER, which indicates that this Alert is modal. This value is not necessarily the same value that might have been set by the application in a call to {@link #setTimeout}. In particular, if the Alert is made modal because its contents is large enough to scroll, the value returned by getTimeout will be FOREVER.

return
timeout in milliseconds, or FOREVER
see
#setTimeout

        synchronized (Display.LCDUILock) {
            if ((height > viewport[HEIGHT]) || (getCommandCount() > 1)) {
                return FOREVER;
            } else {
                return time;
            }
        }
    
public AlertTypegetType()
Gets the type of the Alert.

return
a reference to an instance of AlertType, or null if the Alert has no specific type
see
#setType

        // SYNC NOTE: return of atomic value, no locking necessary
        return type;
    
booleanisConformantIndicator(Gauge ind)
Verify the activity indicator is conformant with the spec requirements for addition to an Alert.

param
ind The indicator to be verified
return
boolean True if the gauge is conformant; false otherwise

        return ((ind.isInteractive() == false) &&
                (ind.getOwner() == null) &&
                (ind.getCommandCount() == 0) &&
                (ind.getItemCommandListener() == null) &&
                (ind.getLabel() == null) &&
                (ind.getLayout() == Item.LAYOUT_DEFAULT) &&
                (ind.lockedWidth == -1) &&
                (ind.lockedHeight == -1));
    
voidlayout()
Layout the content of this Alert given the width and height parameters

        super.layout();

        // height of image, if any
        height = (image != null) ? image.getHeight() + CELL_SPACING : 0;

        // height of activity indicator, if any
        if (indicator != null) {
            if (indicator.bounds == null) {
                indicator.bounds = new int[4];
            }

            int pW      = indicator.callPreferredWidth(-1);
            int pH      = indicator.callPreferredHeight(-1);

            // Center indicator horizontally
            int xOffset = (viewport[WIDTH] - pW) / 2;
            if (xOffset < 0) {
                xOffset = 0;
            }

            // We assign the item a bounds which is its pixel location,
            // width, and height in coordinates which represent offsets
            // of the viewport origin (that is, are in the viewport
            // coordinate space)
            indicator.bounds[X]      = xOffset;
            indicator.bounds[Y]      = height;
            indicator.bounds[WIDTH]  = pW;
            indicator.bounds[HEIGHT] = pH;

            height += pH + CELL_SPACING;
        }

        // height of alert text, if any
        height += Text.getHeightForWidth(text, Screen.CONTENT_FONT, 
                                         viewport[WIDTH], 0);

        // Adjust indicator if the Alert is shorter than the screen
        if ((indicator != null) && (height < viewport[HEIGHT])) {
            // Shift bounds to vertically center indicator on the screen
            indicator.bounds[Y] += (viewport[HEIGHT] - height) / 2;
        }

        view[HEIGHT] = height;
    
public voidremoveCommand(Command cmd)
Similar to {@link Displayable#removeCommand}, however when the application removes the last command from an Alert, {@link #DISMISS_COMMAND} is implicitly added. Calling this method with DISMISS_COMMAND as the parameter has no effect.

param
cmd the command to be removed

        if (cmd == DISMISS_COMMAND) {
            return;
        }

        synchronized (Display.LCDUILock) {
            super.removeCommandImpl(cmd);
        }
    
booleanscrollViewport(int dir)
Scroll the viewport in the specified direction.

param
dir direction to scroll the viewport.
return
boolean True if the viewport was scrolled

        if ((dir == Canvas.DOWN) && 
            (view[Y] + viewport[HEIGHT] < height)) {
                view[Y] += SCROLL_AMOUNT;
                return true;
        } else if ((dir == Canvas.UP) && 
                   (view[Y] > 0)) {
                view[Y] -= SCROLL_AMOUNT;
                return true;
        }

        return false;
    
public voidsetCommandListener(CommandListener l)
The same as {@link Displayable#setCommandListener} but with the following additional semantics. If the listener parameter is null, the default listener is restored. See Commands and Listeners for the definition of the behavior of the default listener.

param
l the new listener, or null

        synchronized (Display.LCDUILock) {
            userCommandListener = l;
        }
    
public voidsetImage(Image img)
Sets the Image used in the Alert. The Image may be mutable or immutable. If img is null, specifies that this Alert has no image. If img is mutable, the effect is as if a snapshot is taken of img's contents immediately prior to the call to setImage. This snapshot is used whenever the contents of the Alert are to be displayed. If img is already the Image of this Alert, the effect is as if a new snapshot of img's contents is taken. Thus, after painting into a mutable image contained by an Alert, the application can call

alert.setImage(alert.getImage()); 

to refresh the Alert's snapshot of its Image.

If the Alert is visible on the display when its contents are updated through a call to setImage, the display will be updated with the new snapshot as soon as it is feasible for the implementation to do so.

param
img the Alert's image, or null if there is no image
see
#getImage

        synchronized (Display.LCDUILock) {
            setImageImpl(img);
            layout();
            if (isShown()) {
                repaintContents();
            }
        }
    
voidsetImageImpl(Image img)
Set the Image for this Alert.

param
img The img to use for this Alert

        if (img != null && img.isMutable()) {
            this.image = Image.createImage(img);   // use immutable copy of img
            this.mutableImage = img;
        } else { 
            this.image = img;
            this.mutableImage = null;        // Make sure to clear mutableImage
        }
    
public voidsetIndicator(Gauge indicator)
Sets an activity indicator on this Alert. The activity indicator is a {@link Gauge} object. It must be in a restricted state in order for it to be used as the activity indicator for an Alert. The restrictions are listed above. If the Gauge object violates any of these restrictions, IllegalArgumentException is thrown.

If indicator is null, this removes any activity indicator present on this Alert.

param
indicator the activity indicator for this Alert, or null if there is to be none
throws
IllegalArgumentException if indicator does not meet the restrictions for its use in an Alert
see
#getIndicator
since
MIDP 2.0

        synchronized (Display.LCDUILock) {
            if (indicator == null) {
                if (this.indicator != null) {
                    // The Alert no longer owns this Gauge
                    this.indicator.setOwner(null);
                }
            } else {
                if (!isConformantIndicator(indicator)) {
                    throw new IllegalArgumentException("Gauge in wrong state");
                }
                indicator.setOwner(this);
            }

            if (this.indicator != null) {
                this.indicator.setOwner(null);
            }

            this.indicator = indicator;
            layout();
            if (isShown()) {
                repaintContents();
            }
        }
    
voidsetReturnScreen(Displayable d)
Set the screen that the display should return to when this Alert is dismissed.

param
d The Displayable to display when this Alert is completed

        if (d != null) {
            this.returnScreen = d;
        } else {
            this.returnScreen = new Form("");
        }
    
public voidsetString(java.lang.String str)
Sets the text string used in the Alert.

If the Alert is visible on the display when its contents are updated through a call to setString, the display will be updated with the new contents as soon as it is feasible for the implementation to do so.

param
str the Alert's text string, or null if there is no text
see
#getString

        synchronized (Display.LCDUILock) {
            text = str;
            layout();
            if (isShown()) {
                repaintContents();
            }
        }
    
public voidsetTimeout(int time)
Set the time for which the Alert is to be shown. This must either be a positive time value in milliseconds, or the special value FOREVER.

param
time timeout in milliseconds, or FOREVER
throws
IllegalArgumentException if time is not positive and is not FOREVER
see
#getTimeout

        if (time <= 0 && time != FOREVER) {
            throw new IllegalArgumentException();
        }

        synchronized (Display.LCDUILock) {
            this.time = time;
        }
    
public voidsetType(AlertType type)
Sets the type of the Alert. The handling and behavior of specific AlertTypes is described in {@link AlertType}.

param
type an AlertType, or null if the Alert has no specific type
see
#getType

        synchronized (Display.LCDUILock) {
            this.type = type;
        }