/*
*
*
* Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package javax.microedition.lcdui;
import java.util.TimerTask;
import java.util.Timer;
/**
* An object that has the capability of being placed on the display. A
* <code>Displayable</code> object may have a title, a ticker,
* zero or more commands and a listener associated with it. The
* contents displayed and their interaction with the user are defined by
* subclasses.
*
* <p>The title string may contain
* <A HREF="Form.html#linebreak">line breaks</a>.
* The display of the title string must break accordingly.
* For example, if only a single line is available for a
* title and the string contains a line break then only the characters
* up to the line break are displayed.</p>
*
* <p>Unless otherwise specified by a subclass, the default state of newly
* created <code>Displayable</code> objects is as follows:</p>
*
* <ul>
* <li>it is not visible on the <code>Display</code>;</li>
* <li>there is no <code>Ticker</code> associated with this
* <code>Displayable</code>;</li>
* <li>the title is <code>null</code>;</li>
* <li>there are no <code>Commands</code> present; and</li>
* <li>there is no <code>CommandListener</code> present.</li>
* </ul>
*
* @since MIDP 1.0
*/
public abstract class Displayable {
// ************************************************************
// public member variables
// ************************************************************
// ************************************************************
// protected member variables
// ************************************************************
/**
* Create a new Displayable
*/
Displayable() {
}
/**
* Create a new Displayable with a passed in title
*
* @param title the Displayable's title, or null for no title
*/
Displayable(String title) {
synchronized (Display.LCDUILock) {
this.title = title;
}
}
// ************************************************************
// public methods
// ************************************************************
/**
* Gets the title of the <code>Displayable</code>. Returns
* <code>null</code> if there is no title.
* @return the title of the instance, or <code>null</code> if no title
* @see #setTitle
*/
public String getTitle() {
synchronized (Display.LCDUILock) {
return title;
}
}
/**
* Sets the title of the <code>Displayable</code>. If
* <code>null</code> is given,
* removes the title.
*
* <P>If the <code>Displayable</code> is actually visible on
* the display,
* the implementation should update
* the display as soon as it is feasible to do so.</P>
*
* <P>The existence of a title may affect the size
* of the area available for <code>Displayable</code> content.
* Addition, removal, or the setting of the title text at runtime
* may dynamically change the size of the content area.
* This is most important to be aware of when using the
* <code>Canvas</code> class.
* If the available area does change, the application will be notified
* via a call to {@link #sizeChanged(int, int) sizeChanged()}. </p>
*
* @param s the new title, or <code>null</code> for no title
* @see #getTitle
*/
public void setTitle(String s) {
synchronized (Display.LCDUILock) {
if (title == s || (title != null && title.equals(s))) {
return;
}
String oldTitle = title;
this.title = s;
displayableLF.lSetTitle(oldTitle, title);
}
}
/**
* Gets the ticker used by this <code>Displayable</code>.
* @return ticker object used, or <code>null</code> if no
* ticker is present
* @see #setTicker
*/
public Ticker getTicker() {
synchronized (Display.LCDUILock) {
return ticker;
}
}
/**
* Sets a ticker for use with this <code>Displayable</code>,
* replacing any
* previous ticker.
* If <code>null</code>, removes the ticker object
* from this <code>Displayable</code>. The same ticker may be shared by
* several <code>Displayable</code>
* objects within an application. This is done by calling
* <code>setTicker()</code>
* with the same <code>Ticker</code> object on several
* different <code>Displayable</code> objects.
* If the <code>Displayable</code> is actually visible on the display,
* the implementation should update
* the display as soon as it is feasible to do so.
*
* <p>The existence of a ticker may affect the size
* of the area available for <code>Displayable's</code> contents.
* Addition, removal, or the setting of the ticker at runtime
* may dynamically change the size of the content area.
* This is most important to be aware of when using the
* <code>Canvas</code> class.
* If the available area does change, the application will be notified
* via a call to {@link #sizeChanged(int, int) sizeChanged()}. </p>
*
* @param ticker the ticker object used on this screen
* @see #getTicker
*/
public void setTicker(Ticker ticker) {
synchronized (Display.LCDUILock) {
// Return early if there's nothing to do :
// ticker is the same or (old and new tickers are null)
if (this.ticker == ticker) {
return;
}
Ticker oldTicker = this.ticker;
this.ticker = ticker;
displayableLF.lSetTicker(oldTicker, ticker);
}
}
/**
* Checks if the <code>Displayable</code> is actually visible
* on the display. In order
* for a <code>Displayable</code> to be visible, all of the
* following must be true:
* the <code>Display's</code> <code>MIDlet</code> must be
* running in the foreground, the <code>Displayable</code>
* must be the <code>Display's</code> current screen, and the
* <code>Displayable</code> must not be
* obscured by a <a href="Display.html#systemscreens">
* system screen</a>.
*
* @return <code>true</code> if the
* <code>Displayable</code> is currently visible
*/
public boolean isShown() {
synchronized (Display.LCDUILock) {
return displayableLF.lIsShown();
}
}
/**
* Adds a command to the <code>Displayable</code>. The
* implementation may choose,
* for example,
* to add the command to any of the available soft buttons or place it
* in a menu.
* If the added command is already in the screen (tested by comparing the
* object references), the method has no effect.
* If the <code>Displayable</code> is actually visible on the
* display, and this call
* affects the set of visible commands, the implementation should update
* the display as soon as it is feasible to do so.
*
* @param cmd the command to be added
*
* @throws NullPointerException if <code>cmd</code> is
* <code>null</code>
*/
public void addCommand(Command cmd) {
if (cmd == null) {
throw new NullPointerException();
}
synchronized (Display.LCDUILock) {
addCommandImpl(cmd);
displayableLF.lAddCommand(cmd, numCommands-1);
}
}
/**
* Removes a command from the <code>Displayable</code>.
* If the command is not in the <code>Displayable</code>
* (tested by comparing the
* object references), the method has no effect.
* If the <code>Displayable</code> is actually visible on the
* display, and this call
* affects the set of visible commands, the implementation should update
* the display as soon as it is feasible to do so.
* If <code>cmd</code> is <code>null</code>, this method
* does nothing.
*
* @param cmd the command to be removed
*/
public void removeCommand(Command cmd) {
synchronized (Display.LCDUILock) {
int i = removeCommandImpl(cmd);
if (i != -1) {
displayableLF.lRemoveCommand(cmd, i);
}
}
}
/**
* Sets a listener for {@link Command Commands} to this
* <code>Displayable</code>,
* replacing any previous <code>CommandListener</code>. A
* <code>null</code> reference is
* allowed and has the effect of removing any existing listener.
*
* @param l the new listener, or <code>null</code>.
*/
public void setCommandListener(CommandListener l) {
synchronized (Display.LCDUILock) {
listener = l;
}
displayableLF.updateCommandSet();
}
/**
* Gets the width in pixels of the displayable area available to the
* application. The value returned is appropriate for the particular
* <code>Displayable</code> subclass. This value may depend
* on how the device uses the
* display and may be affected by the presence of a title, a ticker, or
* commands.
* This method returns the proper result at all times, even if the
* <code>Displayable</code> object has not yet been shown.
*
* @return width of the area available to the application
*/
public int getWidth() {
synchronized (Display.LCDUILock) {
return displayableLF.lGetWidth();
}
}
/**
* Gets the height in pixels of the displayable area available to the
* application. The value returned is appropriate for the particular
* <code>Displayable</code> subclass. This value may depend
* on how the device uses the
* display and may be affected by the presence of a title, a ticker, or
* commands.
* This method returns the proper result at all times, even if the
* <code>Displayable</code> object has not yet been shown.
*
* @return height of the area available to the application
*/
public int getHeight() {
synchronized (Display.LCDUILock) {
return displayableLF.lGetHeight();
}
}
// ************************************************************
// protected methods
// ************************************************************
/**
* The implementation calls this method when the available area of the
* <code>Displayable</code> has been changed.
* The "available area" is the area of the display that
* may be occupied by
* the application's contents, such as <code>Items</code> in a
* <code>Form</code> or graphics within
* a <code>Canvas</code>. It does not include space occupied
* by a title, a ticker,
* command labels, scroll bars, system status area, etc. A size change
* can occur as a result of the addition, removal, or changed contents of
* any of these display features.
*
* <p> This method is called at least once before the
* <code>Displayable</code> is shown for the first time.
* If the size of a <code>Displayable</code> changes while
* it is visible,
* <CODE>sizeChanged</CODE> will be called. If the size of a
* <code>Displayable</code>
* changes while it is <em>not</em> visible, calls to
* <CODE>sizeChanged</CODE> may be deferred. If the size had changed
* while the <code>Displayable</code> was not visible,
* <CODE>sizeChanged</CODE> will be
* called at least once at the time the
* <code>Displayable</code> becomes visible once
* again.</p>
*
* <p>The default implementation of this method in <code>Displayable</code>
* and its
* subclasses defined in this specification must be empty.
* This method is intended solely for being overridden by the
* application. This method is defined on <code>Displayable</code>
* even though applications are prohibited from creating
* direct subclasses of <code>Displayable</code>.
* It is defined here so that applications can override it in
* subclasses of <code>Canvas</code> and <code>Form</code>.
* This is useful for <code>Canvas</code> subclasses to tailor
* their graphics and for <code>Forms</code> to modify
* <code>Item</code> sizes and layout
* directives in order to fit their contents within the the available
* display area.</p>
*
* @param w the new width in pixels of the available area
* @param h the new height in pixels of the available area
*/
protected void sizeChanged(int w, int h) {
// this method is intended to be overridden by the application
}
// ************************************************************
// package private methods
// ************************************************************
/**
* Gets look&feel for this Displayable object
* This method is implemented in the subclasses.
* @return - DisplayableLF for this Displayable object
*/
DisplayableLF getLF() {
return displayableLF;
}
/**
* Called to schedule a call to itemStateChanged() due to
* a change in the given Item.
*
* @param src the Item which has changed
*/
void itemStateChanged(Item src) {
/*
* This call could happen on a Displayable that is not currently
* visible (either not current, or the Display instance is not
* foreground).
*/
Display.itemStateChanged(src);
}
/**
* Called by the event handler to notify any ItemStateListener
* of a change in the given Item.
* The default implementation of this function does nothing.
*
* @param src The Item which has changed
*/
void uCallItemStateChanged(Item src) { }
/**
* Add a Command to this Displayable
*
* @param cmd The Command to add to this Displayable
* @return command index
*/
int addCommandImpl(Command cmd) {
for (int i = 0; i < numCommands; ++i) {
if (commands[i] == cmd) {
return -1;
}
}
if ((commands == null) || (numCommands == commands.length)) {
Command[] newCommands = new Command[numCommands + 4];
if (commands != null) {
System.arraycopy(commands, 0, newCommands, 0, numCommands);
}
commands = newCommands;
}
commands[numCommands] = cmd;
++numCommands;
return numCommands-1;
}
/**
* Remove a Command from this Displayable
*
* @param cmd The Command to remove from this Displayable
* @return command index
*/
int removeCommandImpl(Command cmd) {
for (int i = 0; i < numCommands; ++i) {
if (commands[i] == cmd) {
commands[i] = commands[--numCommands];
commands[numCommands] = null;
return i;
}
}
return -1;
}
// ************************************************************
// private methods
// ************************************************************
// ************************************************************
// package private member variables
// ************************************************************
/** An array of Commands added to this Displayable */
Command commands[];
/** The number of Commands added to this Displayable */
int numCommands;
/** The CommandListener for Commands added to this Displayable */
CommandListener listener;
/** True, if this Displayable is in full screen mode */
boolean isInFullScreenMode; // = false
/** True, if this Displayable is rotated */
boolean isRotated; // = false
/** The title for this Displayable */
String title;
/** The ticker that may be set for this Displayable */
Ticker ticker;
/** The Look &s; Feel object associated with this Displayable */
DisplayableLF displayableLF;
// ************************************************************
// private member variables
// ************************************************************
// ************************************************************
// Static initializer, constructor
// ************************************************************
} // Displayable
|