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

Screen.java

/*
 * @(#)Screen.java	1.157 02/09/11 @(#)
 *
 * Copyright (c) 1999-2002 Sun Microsystems, Inc.  All rights reserved.
 * PROPRIETARY/CONFIDENTIAL
 * Use is subject to license terms.
 */

package javax.microedition.lcdui;

import java.util.TimerTask;
import java.util.Timer;

/**
 * The common superclass of all high-level user interface classes. The 
 * contents displayed and their interaction with the user are defined by 
 * subclasses.
 *
 * <P>Using subclass-defined methods, the application may change the contents
 * of a <code>Screen</code> object while it is shown to the user.  If
 * this occurs, and the
 * <code>Screen</code> object is visible, the display will be updated
 * automatically.  That
 * is, the implementation will refresh the display in a timely fashion without
 * waiting for any further action by the application.  For example, suppose a
 * <code>List</code> object is currently displayed, and every element
 * of the <code>List</code> is
 * visible.  If the application inserts a new element at the beginning of the
 * <code>List</code>, it is displayed immediately, and the other
 * elements will be
 * rearranged appropriately.  There is no need for the application to call
 * another method to refresh the display.</P>
 *
 * <P>It is recommended that applications change the contents of a
 * <code>Screen</code> only
 * while it is not visible (that is, while another
 * <code>Displayable</code> is current).
 * Changing the contents of a <code>Screen</code> while it is visible
 * may result in
 * performance problems on some devices, and it may also be confusing if the
 * <code>Screen's</code> contents changes while the user is
 * interacting with it.</P>
 *
 * <P>In MIDP 2.0 the four <code>Screen</code> methods that defined
 * read/write ticker and
 * title properties were moved to <code>Displayable</code>,
 * <code>Screen's</code> superclass.  The
 * semantics of these methods have not changed.</P>
 * 
 * @since MIDP 1.0
 */

public abstract class Screen extends Displayable  {

// ************************************************************
//  public member variables
// ************************************************************

// ************************************************************
//  protected member variables
// ************************************************************

// ************************************************************
//  package private member variables
// ************************************************************

    /** Special content font, shared amongst the LCDUI package */
    final static Font CONTENT_FONT  = Font.getDefaultFont();

    /** Special content height, shared amongst the LCDUI package */
    final static int CONTENT_HEIGHT = CONTENT_FONT.getHeight();

    /**
     * When paintBorder is not BORDER_NONE, there is a pixel border 
     * painted around content and viewPort is reduced by 4 pixels. 
     * This is used by subclasses such as TextBox which need a pixel 
     * border around them.
     */
    int paintBorder;             // = BORDER_NONE;
 
    /** this is for no border */
    final static int BORDER_NONE  = 0;
    /** this is for a solid border */
    final static int BORDER_SOLID = 1;
    /** this is for a dotted light grey border */
    final static int BORDER_GRAY  = 2;


// MARK                        

    /**
     * A boolean declaring whether the viewport is capable of
     * scrolling horizontally. FALSE by default
     */
    final static boolean SCROLLS_HORIZONTAL = false;

    /**
     * A boolean declaring whether the viewport is capable of
     * scrolling vertically. TRUE by default
     */
    final static boolean SCROLLS_VERTICAL = true;

    /**
     * An array which holds the scroll location and 
     * the overall dimensions of the view being
     * shown in the parent Displayable's viewport
     * Note that the following is always true.
     * 0 <= view[X] <= view[WIDTH] - viewport[WIDTH]
     * 0 <= view[Y] <= view[HEIGHT] - viewport[HEIGHT]
     */
    int view[];

    /**
     * Screens should automatically reset to the top of the when
     * they are shown, except in cases where it is interrupted by
     * a system menu or an off-screen editor - in which case it
     * should be reshown exactly as it was.
     */
    boolean resetToTop = true;

// ************************************************************
//  private member variables
// ************************************************************

// ************************************************************
//  Static initializer, constructor
// ************************************************************

    /**
     * Creates a new Screen object with no title and no ticker.
     */
    Screen() {
        this(null);
    }

    /**
     * Creates a new Screen object with the given title and with no ticker.
     *
     * @param title the Screen's title, or null for no title
     */
    Screen(String title) {
        view = new int[4];
        view[X] = 0;
        view[Y] = 0;
        view[WIDTH] = 0;
        view[HEIGHT] = 0;

        super.setTitleImpl(title);
    }

// ************************************************************
//  public methods
// ************************************************************

// ************************************************************
//  protected methods
// ************************************************************

// ************************************************************
//  package private methods
// ************************************************************

    /**
     * Layout the contents of this screen. Calls super.layout()
     * and then translateViewport();
     */
    void layout() {
        super.layout();
        translateViewport();
    }

    /**
     * Paint an Item contained in this Screen. The Item requests a paint
     * in its own coordinate space. Screen translates those coordinates
     * into the overall coordinate space and schedules the repaint
     *
     * @param item the Item requesting the repaint
     * @param x the x-coordinate of the origin of the dirty region
     * @param y the y-coordinate of the origin of the dirty region
     * @param w the width of the dirty region
     * @param h the height of the dirty region
     */
    void repaintItem(Item item, int x, int y, int w, int h) {

        callRepaint(item.bounds[X] + viewport[X] - view[X] + x,
                    item.bounds[Y] + viewport[Y] - view[Y] + y,
                    w,
                    h,
                    item);
    }

    /**
     * Translate the viewport[] array so that subclasses only render
     * within the viewport
     */
    private void translateViewport() {
        if (paintBorder != BORDER_NONE) {
            // translate the viewport for subclasses layout()
            // to utilize
            viewport[X] += 4;
            viewport[Y] += 4;
            viewport[WIDTH] -= 8;
            viewport[HEIGHT] -= 8;
        }
    }

    /**
     * Paint the contents of this Screen
     *
     * @param g the Graphics to paint to
     * @param target the target Object of this repaint
     */
    void callPaint(Graphics g, Object target) {
        super.callPaint(g, target);

        /*
        System.err.println("Screen:Clip: " +
            g.getClipX() + "," + g.getClipY() + "," +
            g.getClipWidth() + "," + g.getClipHeight());
        */

        synchronized (Display.LCDUILock) {
            if ((paintBorder != BORDER_NONE) && (g.getClipX() < viewport[X])) {
                // erase the border and its surrounding rectangles
                g.setColor(Display.ERASE_COLOR);
                g.drawRect(viewport[X] - 4, viewport[Y] - 4,
                           viewport[WIDTH] + 7, viewport[HEIGHT] + 7);
                g.drawRect(viewport[X] - 3, viewport[Y] - 3,
                           viewport[WIDTH] + 5, viewport[HEIGHT] + 5);
                g.drawRect(viewport[X] - 2, viewport[Y] - 2,
                           viewport[WIDTH] + 3, viewport[HEIGHT] + 3);
                g.drawRect(viewport[X] - 1, viewport[Y] - 1,
                           viewport[WIDTH] + 1, viewport[HEIGHT] + 1);

                // Draw the border
                if (paintBorder == BORDER_SOLID) {
                    // solid border
                    g.setColor(Display.FG_COLOR);
                } else {
                    // light gray dotted border
                    g.setColor(Display.BORDER_COLOR);
                    g.setStrokeStyle(Graphics.DOTTED);
                }
                g.drawRect(viewport[X] - 3, viewport[Y] - 3,
                           viewport[WIDTH] + 5, viewport[HEIGHT] + 5);

                // restore the line style
                g.setStrokeStyle(Graphics.SOLID);
            }

            // Clip off the ticker/title area to keep subclasses from
            // painting on it
            g.clipRect(viewport[X], viewport[Y],
                    viewport[WIDTH],
                    viewport[HEIGHT]);

            if (target == null || (
                    target instanceof Item && ((Item)target).owner == this)) {

                g.setColor(Display.ERASE_COLOR);
                g.fillRect(g.getClipX(), g.getClipY(),
                           g.getClipWidth(), g.getClipHeight());
                g.setColor(Display.FG_COLOR);
            }
        } // synchronized
    }

    /**
     * Set the vertical scroll indicators for this Screen
     */
    void setVerticalScroll() {

        // Previously, Screen was always resetting the left/right
        // scroll indicators to 0 when it set the up/down indicators,
        // now it sets the up/down indicators as appropriate, but
        // maintains the left/right indicators as they were, and it
        // is the component's responsibility (ie Gauge) to update
        // the right/left scroll indicators if necessary
        if (view[HEIGHT] <= viewport[HEIGHT]) {
            super.setVerticalScroll(0, 100);
        } else {
            super.setVerticalScroll(
                (view[Y] * 100 / (view[HEIGHT] - viewport[HEIGHT])),
                (viewport[HEIGHT] * 100 / view[HEIGHT]));
        }
    }

}