Main Menu
- Home
- Projects
- Forums
- People
- Java User Groups
- JCP
This is a photo management demo, where the content to be shown is decided at run time. When an "album" is chosen, thumbnails of the photos in the album are shown. When a thumbnail is chosen, the bigger image is shown. A "camera capture" screen is also available, which simulates taking a picture with phone camera.
In the "Album" screen, click anywhere on it to give it focus. Then use the up or down arrow keys for navigation and the "enter" key for selection. In the "thumbnail" screen, use the arrow keys for navigation and "enter" key for selection. You can click on the "camera" icon in the lower left to go to the "photo capture" screen, where you can click on the "camera" icon in the bottom center to take a picture or the "left arrow" icon to go back to the thumbnail screen. In the thumbnail screen, if you select a thumbnail, you will go to the "image viewing" screen, where you can click on the "left arrow" icon in the lower left to go back to the thumbnail screen. |
Note: The midlet code in the DemoBox directory shows a different video in the Camera Capture screen. In the same screen, when a photo is snapped, the midlet code shows the correct image in the lower right corner, whereas here the same image is shown all the time. |
The createImage
method of the javax.microedition.m2g.SVGImage
class is used to
load the svg file. Some of the image resources are loaded from a jar file, using an
ExternalResourceHandler
. The ExternalResourceHandler
interface is
implemented when the loading of an external resource, referenced in an SVG document, needs
to be customized. The correct URIs of the images to be loaded are not known ahead of time. The image
elements in the svg file, have an "xlink:href" attribute defined,
with a place holder URI. The correct image name is determined at run time and the
ExternalResourceHandler
computes the rigth URI and uses ScalableImage
's
requestCompleted
method to load the images.
Animations are defined in the svg file, but are activated programmatically,
using the beginElementAt()
method of the
org.w3c.dom.svg.SVGAnimationElement
class. For example as you
navigate the "select album" screen, items gain and lose focus. For items gaining
focus, animations are declaratively defined that increase font size, scale up images
and surrounding rectangles, to give the item more prominence. For items losing focus,
the reverse animations are defined, i.e. font sizes decreased, images and rectangles
scaled down. Knowing their id, these animations are accessed using
org.w3c.dom.Document
's getElementById
method and then
activated.
Many intercative screens are presented, most using elements from the same svg file.
Most of the elements in the svg file, have the display
attribute
set to none
, and hence are not rendered. Most screen objects like,
ImageViewScreen
and ThumbnailsScreen
, have methods
transitionIn
and transitionOut
. In the transitionIn
,
method many svg elements are accessed using org.w3c.dom.Document
's
getElementById
method. Some of these elements from the previous screen, have
their "display" attribute set to "none", thus causing them to disappear. Some new elements
have their "display" attribute set to "inline", causing them to appear. All this is achieved
using the setTrait("display", "none")
or setTrait("display", "inline")
method of the org.w3c.dom.svg.SVGElement
class. Similarly in the transitionOut
method, some elements are made to disappear and some screen ending animations are started.
<!-- image element with place holder href attribute --> <image id="imageViewImage" xlink:class="www.sun.com/images/imageView.png" display="none"/> ...... <!-- focusIn animation, "select album" screen, item: San Francisco ->- <!-- increase font size ->- <animate id="focusInAnim_menuItem_sanFrancisco" xlink:class="#menuItem_sanFrancisco_text" attributeName="font-size" values="20;25" begin="2s" dur="0.25s" fill="freeze" /> <!-- magnify image ->- <animateTransform xlink:class="#sanFranciscoImage" attributeName="transform" type="scale" values="1;1.3" begin="focusInAnim_menuItem_sanFrancisco.begin" dur="0.25s" fill="freeze" /> <!-- move border rectangle outward ->- <animateTransform xlink:class="#albumPrompt" attributeName="transform" type="translate" values="20,80;20,80" begin="focusInAnim_menuItem_sanFrancisco.begin" dur="0.25s" fill="freeze" /> <!-- focusOut animation, "select album" screen, item: San Francisco ->- <!-- decrease font size ->- <animate id="focusOutAnim_menuItem_sanFrancisco" xlink:class="#menuItem_sanFrancisco_text" attributeName="font-size" values="25;20" begin="indefinite" dur="0.25s" fill="freeze" /> <!-- minify image ->- <animateTransform xlink:class="#sanFranciscoImage" attributeName="transform" type="scale" values="1.3;1" begin="focusOutAnim_menuItem_sanFrancisco.begin" dur="0.25s" fill="freeze" /> ........... <!-- display set to none. Turned on programmatically --> <g id="thumbHighlight" transform="translate(600, 73.75)" display="none"> ......
// ========================================================================= // ExternalResourceHandler implementation (from MobileAerith.java) // ========================================================================= /** * In this implementation of requestResource, we assume that all resources * are embedded into the jar file, so we simply do a getResourceAsStream. * * @param scalableImage the image referencing the requested resource. * @param uri the uri for the requested resource. */ public void requestResource(final ScalableImage scalableImage, final String uri) { .... // Compute correct URI String trimmedURItmp = uri; String prefix = "www.sun.com/"; if (uri != null && uri.startsWith(prefix)) { trimmedURItmp = uri.substring(prefix.length()); } final String trimmedURI = trimmedURItmp; .... // Inputstream obtained from modified URI and matched with original URI // The stream is consumed asynchronously scalableImage.requestCompleted(uri, MobileAerith.class.getResourceAsStream ("/" + trimmedURI)); .... } .... // Snippets from ThumbnailsScreen.java /** * Called to transition the screen out of the scene. * * @return the time, in seconds, which the out transition takes. */ public float transitionOut() { // Animation accessed knowing id SVGAnimationElement transitionOut = (SVGAnimationElement) getElementById(THUMBS_VIEW_ID_ANIM_END); // animation started transitionOut.beginElementAt(0); return 0.5f; } /** * Called to transition the screen into the scene. * * @param delay before the transition should start. */ public void transitionIn(final float delay) { // Animation accessed knowing id SVGAnimationElement transitionIn = (SVGAnimationElement) getElementById(THUMBS_VIEW_ID_ANIM_BEGIN); // animation started transitionIn.beginElementAt(delay); } ........ // Snippets from ImageViewScreen.java /** * Called to transition the screen into the scene. * * @param delay before the transition should start. */ public void transitionIn(float delay) { ... // Access elements of interest from document, using their id SVGAnimationElement transition = (SVGAnimationElement) getElementById(IMAGE_VIEW_ID_ANIM_BEGIN); SVGElement titleText = getElementById(IMAGE_VIEW_ID_TITLE); SVGElement image = getElementById(IMAGE_VIEW_ID_IMAGE); SVGAnimationElement loadingAnim = (SVGAnimationElement) getElementById(IMAGE_VIEW_ID_LOADING_ANIM); SVGElement loading = getElementById(IMAGE_VIEW_ID_LOADING_GRAPHICS); SVGElement uploading = getElementById(IMAGE_VIEW_ID_UPLOADING); SVGElement networkingStatus = getElementById(IMAGE_VIEW_ID_NETWORKING_STATUS); SVGElement rightIcon = getElementById(IMAGE_VIEW_ID_RIGHT_ICON); SVGElement leftIcon = getElementById(IMAGE_VIEW_ID_LEFT_ICON); // Do not render rightIcon rightIcon.setTrait("display", "none"); // but render left icon leftIcon.setTrait("display", "inline"); // set title text titleText.setTrait("#text", title); // set image attributes width = image.getFloatTrait("width"); height = image.getFloatTrait("height"); x = image.getFloatTrait("x"); y = image.getFloatTrait("y"); // do not display image now image.setTrait("display", "none"); // start loading animation loadingAnim.beginElementAt(0); // render loading icon loading.setTrait("display", "inline"); // but, do not render uploading icon uploading.setTrait("display", "none"); // but render network status icon networkingStatus.setTrait("display", "inline"); // delayed beginning of transition animation transition.beginElementAt(delay); ... // get image and render it getImage(); ... } /** * Called to transition the screen out of the scene. * * @return the time, in seconds, which the out transition takes. */ public float transitionOut() { // Access screen ending animation element SVGAnimationElement transition = (SVGAnimationElement) getElementById(IMAGE_VIEW_ID_ANIM_END); // Trigger animation transition.beginElementAt(0); // Restore image attributes SVGElement image = getElementById(IMAGE_VIEW_ID_IMAGE); image.setFloatTrait("width", width); image.setFloatTrait("height", height); image.setFloatTrait("x", x); image.setFloatTrait("y", y); return 0f; } ...............
Note: When running the MobileAerith midlet in WTK or Netbeans, set the Java Heap to be atleast 4M, in order to avoid OutOfMemory exceptions. Here are instructions on how to set this in Netbeans or WTK.