FileDocCategorySizeDatePackage
DisplayableLFImpl.javaAPI DocphoneME MR2 API (J2ME)36310Wed May 02 18:00:22 BST 2007javax.microedition.lcdui

DisplayableLFImpl

public abstract class DisplayableLFImpl extends Object implements DisplayableLF
The look and feel implementation of Displayable based on platform widget.

Fields Summary
Display
currentDisplay
The current Display object.
int
width
Width and height available to the Displayable.
int
height
boolean
defferedSizeChange
True, indicates that before being painted, this Displayable should be notified that its size has changed via uCallSizeChanged().
Displayable
owner
The owner of this view.
int
nativeId
The MidpDisplayable* of this Displayable while visible. INVALID_NATIVE_ID if no native resource has been created.
int
modelVersion
Version number of this LF's data model. Should be updated when public data model has changed and be passed to native peer if visible. Native peer tags all its native events with this version to prevent user actions on obsolete copy of the data in native.
boolean
sawPointerPress
True, if a pointer press is in progress.
boolean
sawKeyPress
True, if a key press is in progress.
int
state
current state of DisplayableLF (HIDDEN, SHOWN, or FROZEN)
private int
stickyKeyMask
Stores key code of the current key pressed at least once.
private int
currentKeyMask
Stores key code of the current key is currently down.
boolean
pendingInvalidate
Used to indicate the invalidate is needed
static final int
X
Used as an index into the viewport[], for the x origin.
static final int
Y
Used as an index into the viewport[], for the y origin.
static final int
WIDTH
Used as an index into the viewport[], for the width.
static final int
HEIGHT
Used as an index into the viewport[], for the height.
static final int
INVALID_NATIVE_ID
Uninitialized native resource id value.
static final int
HIDDEN
hidden state of DisplayableLF
static final int
SHOWN
shown state of DisplayableLF
static final int
FROZEN
frozen state of DisplayableLF
Constructors Summary
DisplayableLFImpl(Displayable d)
Creates DisplayableLF for the passed in Displayable.

param
d the Displayable object associated with this look & feel.

        initialize0();
    
        owner = d;
        width  = Display.WIDTH;
        height = Display.HEIGHT;
    
Methods Summary
abstract voidcreateNativeResource()
Create native resource. Instance variable {@link #nativeId nativeId} must be set to the id of the new resource.

voiddeleteNativeResource()
Delete native resource. Instance variable {@link #nativeId nativeId} is reset to {@link #INVALID_NATIVE_ID INVALID_NATIVE_ID}.

        if (nativeId != INVALID_NATIVE_ID) {
            deleteNativeResource0(nativeId);
            nativeId = INVALID_NATIVE_ID;
        }
    
private native voiddeleteNativeResource0(int nativeId)
Free the native resource of this Displayable and hide it from display.

param
nativeId native resource id
exception
OutOfMemoryException - if out of native resource

private native voidfinalize()
Native finalizer to delete native resources.

public intgetVerticalScrollPosition()
Get the current vertical scroll position.

return
int The vertical scroll position on a scale of 0-100

        // SYNC NOTE: return of atomic value
        return 0;
    
public intgetVerticalScrollProportion()
Get the current vertical scroll proportion.

return
ing The vertical scroll proportion on a scale of 0-100

        // SYNC NOTE: return of atomic value
        return 100;
    
private static native voidinitialize0()
Native class initializer.

public voidlAddCommand(Command cmd, int i)
Notifies look & feel object of a command addition to the Displayable. SYNC NOTE: The caller of this method handles synchronization.

param
cmd the command that was added
param
i the index of the added command in Displayable.commands[] array

        updateCommandSet();
    
voidlCallHide()
Remove this Displayable from physical screen. The Displayable should unload any resource that was allocated. It is not required to clean the physical screen before this function returns.

        if (state == SHOWN) {
            updateNativeTicker(owner.ticker, null);
        }

        // Delete native resources
        deleteNativeResource();
        
    
voidlCallShow()
Prepare to show this LF on physical screen. This is the internal version of showNotify() function as defined in MIDP spec. It is called immediately prior to this LF being made visible on the display. The LF should load any resource that is needed, layout. App's paint() should NOT be called in this function. Instead, it should be in the uCallPaint() that will be called on this LF shortly after. This function sets this DisplayableLF to SHOWN state.


        // This will suppress drags, repeats and ups until a
        // corresponding down is seen.
        sawPointerPress = sawKeyPress = false;
        
        if (state != SHOWN) {
            // Create native resource first
            // since the title and ticker may depend on it
            createNativeResource();
        }

        // Start to paint the ticker
        updateNativeTicker(null, owner.ticker);

        // set mapping between GameCanvas and DisplayAccess
        // set Game key event flag based on value passed in
        // GameCanvas constructor.
        if (owner instanceof GameCanvas) {
            GameMap.registerDisplayAccess(owner, currentDisplay.accessor);
            stickyKeyMask = currentKeyMask = 0;
        } else {
            // set the keymask to -1 when
            // the displayable is not a GameCanvas.
            stickyKeyMask = currentKeyMask = -1;
        }

        state = SHOWN;
    
public voidlCommitPendingInteraction()
Called to commit any pending user interaction for the current item.

 
public DisplaylGetCurrentDisplay()
Return the Display instance in which the LF is currently shown.

return
the Display instance in which the LF is shown. Null if not shown.

        return currentDisplay;
    
public DisplayablelGetDisplayable()
Return the associated Displayable object. SYNC NOTE: Since the Displayable and DisplayableLFImpl has 1-to-1 mapping, this function can be called from in or outside of LCDUILock.

return
the public model object this LF is associated with.

        return owner;
    
public intlGetHeight()
Get the height in pixels this Displayable is using.

return
height of the area available to the application

        return height;
    
public intlGetWidth()
Get the width in pixels this Displayable is using.

return
width of the area available to the application

        return width;
    
public booleanlIsShown()
Implement public API isShown().

return
true if current DisplayableLF is interactive with user.

        return (currentDisplay != null) && currentDisplay.isShown(this);
    
public voidlRemoveCommand(Command cmd, int i)
Notifies look &s; feel object of a command removal from the Displayable. SYNC NOTE: The caller of this method handles synchronization.

param
cmd the command that was removed
param
i the index of the removed command in Displayable.commands[] array

        updateCommandSet();
    
voidlRequestInvalidate()
Called to schedule an "invalidate" for this Displayable. Invalidation is caused by things like size changes, content changes, or spontaneous traversal within the Item. SYNC NOTE: Caller must hold LCDUILock around this call.

        pendingInvalidate = true;
        if (state == SHOWN && currentDisplay != null) {
            currentDisplay.invalidate();
        }
    
voidlRequestPaint(int x, int y, int width, int height, java.lang.Object target)
Repaint this Displayable.

param
x The x coordinate of the region to repaint
param
y The y coordinate of the region to repaint
param
width The width of the region to repaint
param
height The height of the region to repaint
param
target an optional paint target to receive the paint request when it returns via uCallPaint()

        if (lIsShown()) {
            // Note: Display will not let anyone but the current
            // Displayable schedule repaints
            currentDisplay.repaintImpl(this, 
                                       x, y, width, height,
                                       target);
        }
    
voidlRequestPaint()
Repaints this Displayable. This is the same as calling repaint(0, 0, width, height, null)

        lRequestPaint(0, 0, width, height, null);
    
voidlRequestPaintContents()
Repaint the whole Displayable.

        lRequestPaint(0, 0, width, height, null);
    
public voidlSetDisplay(Display d)
Set the display instance the Displayable is associated with. Caller should hold LCDUILock around this call.

param
d Display instance in which this DisplayableLF is visible. null if this DisplayableLF is no longer visible.

        // ASSERT(d == null || currentDisplay == null)
        currentDisplay = d;
    
public voidlSetTicker(Ticker oldTicker, Ticker newTicker)
Notifies Displayable's look & feel object of a ticker change. SYNC NOTE: The caller of this method handles synchronization.

param
oldTicker the old ticker, or null for no ticker
param
newTicker the new ticker, or null for no ticker


        // This method will not be called if oldTicker and 
        // newTicker are the same (that includes both being null)

        if (owner.ticker != null) {
            owner.ticker.tickerLF.lSetOwner(this);
        }

        updateNativeTicker(oldTicker, newTicker);
    
public voidlSetTitle(java.lang.String oldTitle, java.lang.String newTitle)
Notifies Displayable's look & feel object of a title change. SYNC NOTE: The caller of this method handles synchronization.

param
oldTitle the old title, or null for no title
param
newTitle the new title, or null for no title

        // No updates are necessary if we are in a full screen mode
        if (owner.isInFullScreenMode) {
            return;
        }
        // No update needed if title string is the same object
        if (oldTitle == newTitle) {
            return;
        }
        // No update needed if title strings have same content
        if (oldTitle != null && 
            newTitle != null && 
            oldTitle.equals(newTitle)) {
            return;
        }
        // Update only if we have native resource created
        if (nativeId != INVALID_NATIVE_ID) {
            setTitle0(nativeId, newTitle);
        }
    
private voidreleaseKeyMask(int keyCode)
Called to release key mask of all the keys that were release.

param
keyCode The key code to release the key mask.

        /*
        // Leave this case to dsHide and dsFreeze()
        if (paintSuspended || !hasForeground) {
            currentKeyMask = 0;
            return;
        }
        */

        // set the mask of keys pressed 
        switch (KeyConverter.getGameAction(keyCode)) {
        case Canvas.UP:
            currentKeyMask = currentKeyMask & ~ GameCanvas.UP_PRESSED;
            break;
        case Canvas.DOWN:
            currentKeyMask = currentKeyMask & ~ GameCanvas.DOWN_PRESSED;
            break;
        case Canvas.LEFT:
            currentKeyMask = currentKeyMask & ~ GameCanvas.LEFT_PRESSED;
            break;
        case Canvas.RIGHT:
            currentKeyMask = currentKeyMask & ~ GameCanvas.RIGHT_PRESSED;
            break;
        case Canvas.FIRE:
            currentKeyMask = currentKeyMask & ~ GameCanvas.FIRE_PRESSED;
            break;
        case Canvas.GAME_A:
            currentKeyMask = currentKeyMask & ~ GameCanvas.GAME_A_PRESSED;
            break;
        case Canvas.GAME_B:
            currentKeyMask = currentKeyMask & ~ GameCanvas.GAME_B_PRESSED;
            break;
        case Canvas.GAME_C:
            currentKeyMask = currentKeyMask & ~ GameCanvas.GAME_C_PRESSED;
            break;
        case Canvas.GAME_D:
            currentKeyMask = currentKeyMask & ~ GameCanvas.GAME_D_PRESSED;
        }
    
private voidsetKeyMask(int keyCode)
Called to set key mask of all the keys that were pressed.

param
keyCode The key code to set the key mask.

        /*
        // Shouldn't run into this case.
        if (paintSuspended || !hasForeground) {
            return;
        }
        */

        // set the mask of keys pressed 
        switch (KeyConverter.getGameAction(keyCode)) {
        case Canvas.UP:
            stickyKeyMask = stickyKeyMask | GameCanvas.UP_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.UP_PRESSED;
            break;
        case Canvas.DOWN:
            stickyKeyMask = stickyKeyMask | GameCanvas.DOWN_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.DOWN_PRESSED;
            break;
        case Canvas.LEFT:
            stickyKeyMask = stickyKeyMask | GameCanvas.LEFT_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.LEFT_PRESSED;
            break;
        case Canvas.RIGHT:
            stickyKeyMask = stickyKeyMask | GameCanvas.RIGHT_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.RIGHT_PRESSED;
            break;
        case Canvas.FIRE:
            stickyKeyMask = stickyKeyMask | GameCanvas.FIRE_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.FIRE_PRESSED;
            break;
        case Canvas.GAME_A:
            stickyKeyMask = stickyKeyMask | GameCanvas.GAME_A_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.GAME_A_PRESSED;
            break;
        case Canvas.GAME_B:
            stickyKeyMask = stickyKeyMask | GameCanvas.GAME_B_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.GAME_B_PRESSED;
            break;
        case Canvas.GAME_C:
            stickyKeyMask = stickyKeyMask | GameCanvas.GAME_C_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.GAME_C_PRESSED;
            break;
        case Canvas.GAME_D:
            stickyKeyMask = stickyKeyMask | GameCanvas.GAME_D_PRESSED;
            currentKeyMask = currentKeyMask | GameCanvas.GAME_D_PRESSED;
        }
    
private voidsetTicker(Ticker t)
Set the ticker.

param
t the new ticker to be set


        if (nativeId != INVALID_NATIVE_ID) {
            setTicker0(nativeId, (t == null) ? null : t.displayedMessage);
        }
    
private static native voidsetTicker0(int nativeId, java.lang.String text)
Set text of the native ticker.

param
nativeId native resource id.
param
text text used. Null if the ticker should stop.

private static native voidsetTitle0(int nativeId, java.lang.String title)
Change the title of native resource.

param
nativeId native resource id (MidpDisplayable *)
param
title New title string. Can be null.

voidtickerTextChanged(Ticker t)
Notification that the ticker has changed. This method is called from TickerLFImpl.

param
t the ticker associated with the TickerLFImpl

        if (owner.ticker != t) {
            return;
        }
        setTicker(t);
    
public voiduCallFreeze()
Some "system modal dialog" takes over physical screen buffer and user input now or foreground is lost. This function calls lCallHide after holding LCDUILock and sets this DisplayableLF to FROZEN state.

        synchronized (Display.LCDUILock) {
            // Delete native resources and update ticker
            lCallHide();
            // set state
            state = FROZEN;
        }
    
public voiduCallHide()
Remove this Displayable from physical screen. This function calls lCallHide after holding LCDUILock and sets this DisplayableLF to HIDDEN state.

        synchronized (Display.LCDUILock) {
            // Delete native resources and update ticker
            lCallHide();
            // set state
            state = HIDDEN;
        }
    
public voiduCallInvalidate()
Called by the event handler to perform an invalidation of this Displayable. Subclass should override to perform re-layout. Default implementation does nothing.

        synchronized (Display.LCDUILock) {
            pendingInvalidate = false;
        }
    
public voiduCallKeyEvent(int type, int keyCode)
Handle a raw key event from Display.

param
type type of event, defined in EventConstants
param
keyCode code of the key event

        int eventType = -1;

        synchronized (Display.LCDUILock) {

            switch (type) {
                case EventConstants.PRESSED:
                    sawKeyPress = true;
                    eventType = 0;
                    break;
                case EventConstants.RELEASED:
                    if (sawKeyPress) {
                        eventType = 1;
                    }
                    break;
                case EventConstants.REPEATED:
                    if (sawKeyPress) {
                        eventType = 2;
                    }
                    break;
            }
            // used later by getKeyMask()
            if (currentKeyMask > -1 && eventType != -1) {
                if (eventType == 1) {
                    releaseKeyMask(keyCode);
                } else {
                    // set the mask on key press, repeat or type.
                    // don't set the mask when a key was released.
                    setKeyMask(keyCode);
                }
            }
        } // synchronized

        // SYNC NOTE: Since we may call into application code,
        // we do so outside of LCDUILock
        switch (eventType) {
        case -1:
            return;
        case 0:
            uCallKeyPressed(keyCode);
            break;
        case 1:
            uCallKeyReleased(keyCode);
            break;
        case 2:
            uCallKeyRepeated(keyCode);
            break;
        default:
            /*
             * TBD:
             *
             * Originally severity level was "ERROR". 
             * But it was reduced to INFO because 
             * a). it do not harm to the system
             * b). some cases, 
             *     Displayable processes KEY_PRESS events
             *     (when in system menu) & cleans all related status flag, 
             *     while following KEY_REPEAT & KEY_RELEASE event pairs
             *     are not processed in the same way and therefore
             *     this eror messae was printed or them.
             *
             * As a temporary solution it was decided to disable messages 
             * insead of additional event filtering.
             */
            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
                Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI,
                               "DisplayableLFImpl: uCallKeyEvent," +
                               "type=" +type+ " keyCode=" +keyCode);
            }
            break;
        }
    
voiduCallKeyPressed(int keyCode)
Handle a key press.

param
keyCode The key that was pressed

 
voiduCallKeyReleased(int keyCode)
Handle a key release.

param
keyCode The key that was released

 
voiduCallKeyRepeated(int keyCode)
Handle a repeated key press.

param
keyCode The key that was pressed

 
public voiduCallPaint(Graphics g, java.lang.Object target)
Display calls this method on it's current Displayable. Displayable uses this opportunity to do necessary stuff on the graphics context, this includes, paint Ticker, paint Title and translate as necessary.

The target Object of this repaint may be some Object initially set by this Displayable when the repaint was requested - allowing this Displayable to know exactly which Object it needs to call to service this repaint, rather than potentially querying all of its Objects to determine the one(s) which need painting. SYNC NOTE: The caller of this method handles synchronization.

param
g the graphics context to paint into.
param
target the target Object of this repaint

        // Made obsolete by dsShow, where native title is shown already
    
voiduCallPointerDragged(int x, int y)
Handle a pointer drag event.

param
x The x coordinate of the drag
param
y The y coordinate of the drag

 
public voiduCallPointerEvent(int type, int x, int y)
Called from the event delivery loop when a pointer event is seen.

param
type kind of pointer event
param
x x-coordinate of pointer event
param
y y-coordinate of pointer event

        int eventType = -1;

        synchronized (Display.LCDUILock) {
            switch (type) {
                case EventConstants.PRESSED:
                    sawPointerPress = true;
                    eventType = 0;
                    break;
                case EventConstants.RELEASED:
                    if (sawPointerPress) {
                        eventType = 1;
                    }
                    break;
                case EventConstants.DRAGGED:
                    if (sawPointerPress) {
                        eventType = 2;
                     }
                    break;
            }
        } // synchronized

        // SYNC NOTE: Since we may call into application code,
        // we do so outside of LCDUILock
        switch (eventType) {
        case -1:
            return;
        case 0:
            uCallPointerPressed(x, y);
            break;
        case 1:
            uCallPointerReleased(x, y);
            break;
        case 2:
            uCallPointerDragged(x, y);
            break;
        default:
            // this is an error
            break;
        }
    
voiduCallPointerPressed(int x, int y)
Handle a pointer press event.

param
x The x coordinate of the press
param
y The y coordinate of the press

 
voiduCallPointerReleased(int x, int y)
Handle a pointer release event.

param
x The x coordinate of the release
param
y The y coordinate of the release

 
public voiduCallScrollContent(int scrollType, int thumbPosition)
This method notify displayable to scroll its content

param
scrollType scrollType
param
thumbPosition

        // by default nothing to do 
    
public voiduCallShow()
Prepare to show this LF on physical screen. This function will set correct screen mode screen mode then call lCallShow.


        boolean copyDefferedSizeChange;

        synchronized (Display.LCDUILock) {
            // Assure correct screen mode
            currentDisplay.lSetFullScreen(owner.isInFullScreenMode);
            // display dimentions may change as the resulr of lSetFullScreen
            width = Display.WIDTH;
            height = Display.HEIGHT;
            if (owner.isInFullScreenMode) {
                setTicker(null);
            } else if (owner.ticker != null) {
                setTicker(owner.ticker);
            }
            copyDefferedSizeChange = defferedSizeChange;
            defferedSizeChange = false;
        }

        if (copyDefferedSizeChange) {
            synchronized (Display.calloutLock) { 
                try { 
                    owner.sizeChanged(width, height); 
                } catch (Throwable t) {
                    Display.handleThrowable(t); 
                } 
             }
        }

        synchronized (Display.LCDUILock) {
            // Do the internal show preparation
            lCallShow();
            if (pendingInvalidate || copyDefferedSizeChange) {
                lRequestInvalidate();
            }
        }
    
public voiduCallSizeChanged(int w, int h)
Package private equivalent of sizeChanged().

param
w the new width
param
h the new height


        boolean copyDefferedSizeChange;

        synchronized (Display.LCDUILock) {
            if (owner instanceof GameCanvas) {
                GameCanvasLFImpl gameCanvasLF =
                    GameMap.getGameCanvasImpl((GameCanvas)owner);
                if (gameCanvasLF != null) {
                    gameCanvasLF.lCallSizeChanged(w, h);
                }
            }

            // If there is no Display, or if this Displayable is not
            // currently visible, we simply record the fact that the
            // size has changed
            defferedSizeChange = (state != SHOWN);
            copyDefferedSizeChange = defferedSizeChange;
            /*
             * sizeChangeOccurred is a boolean which (when true) indicates
             * that sizeChanged() will be called at a later time. So, if it
             * is false after calling super(), we go ahead and notify the
             * Canvas now, rather than later
             */

            width = w;
            height = h;
            if (!defferedSizeChange) {
                lRequestInvalidate();
            }

        }
        if (!copyDefferedSizeChange) {
            synchronized (Display.calloutLock) {
                try {
                    owner.sizeChanged(w, h);
                } catch (Throwable t) {
                    Display.handleThrowable(t);
                }
            }
        }
    
public intuGetKeyMask()
Called to get the key mask of all the keys that were pressed. Implement an interface function for CanvasLF only.

return
keyMask The key mask of all the keys that were pressed.

        synchronized (Display.LCDUILock) {
            // don't release currently pressed keys
            int savedMaskCopy = stickyKeyMask | currentKeyMask;
            stickyKeyMask = 0;
            return savedMaskCopy;
        }
    
public booleanuIsScrollNative()
This method is used in repaint, in order to determine the translation of the draw coordinates.

return
true, if the scroll responsibility is on the native platform. false, if the scroll is done at Java level.

        // only native form overrides this and returns true
        return false;
    
voiduRequestPaint()
Request to paint all of this Displayable (without holding a lock).

        synchronized (Display.LCDUILock) {
            lRequestPaint();
        }
    
public voiduSetFullScreenMode(boolean mode)
Notifies look & feel object of a full screen mode change.

param
mode true, if canvas should be displayed without title, ticker, etc.; false otherwise


        boolean requestRepaint = false;

        synchronized (Display.LCDUILock) {

            if (lIsShown()) {
                // currentDisplay is not null when lIsShown is true
                currentDisplay.lSetFullScreen(mode);
                if (mode) {
                    setTicker(null);
                } else if (owner.ticker != null) {
                    setTicker(owner.ticker);
                }
                updateCommandSet();
                requestRepaint = true;
            }
        }
        // This may call into app code, so do it outside LCDUILock
        uCallSizeChanged(Display.WIDTH, Display.HEIGHT);

        // app's sizeChanged has to be called before repaint
        synchronized (Display.LCDUILock) {
            if (requestRepaint) {
                lRequestPaint();
            }
        }
    
public booleanuSetRotatedStatus(boolean newStatus)
Set status of screen rotation

param
newStatus
return

        synchronized (Display.LCDUILock) {
            if (newStatus == owner.isRotated) {
                return false;
            } else {
                owner.isRotated = newStatus;
                return true;
            }
        }
    
public voidupdateCommandSet()
Updates command set if this Displayable is visible. SYNC NOTE: Caller must hold LCDUILock around this call.

        if (state == SHOWN && currentDisplay != null) {
            currentDisplay.updateCommandSet();
        }
    
private voidupdateNativeTicker(Ticker oldTicker, Ticker newTicker)
Updates the ticker.

param
oldTicker the old ticker, or null for no ticker
param
newTicker the new ticker, or null for no ticker


        // CASES:
        // 1. Had an invisible non-null ticker, setting a null ticker
        //    - We need to set the new ticker. There's no need to re-layout
        //      or start the new ticker
        // 2. Had an invisible non-null ticker, setting a non-null ticker
        //    - We need to set the new ticker. There's no need to re-layout
        //      or start the new ticker
        // 3. Had a visible non-null ticker, setting a null ticker
        //    - We need to set the new ticker and re-layout. There's no
        //      need to start the new ticker.
        // 4. Had a null ticker, setting a visible non-null ticker
        //    - We need to set the new ticker, re-layout, and
        //      start up the new ticker
        // 5. Had a visible non-null ticker, setting a non-null ticker
        //    - We need to set the new ticker. There's no need to re-layout

        if ((owner.isInFullScreenMode) || 
            ((oldTicker == null) && (newTicker == null))) {
            return;
        } else {
            setTicker(newTicker);
        }