More on Items,
Images, & Fonts

Peter Komisar ©  Conestoga College  version  1.2  /  2009

reference: Learning Wireless Java, Qusay H. Mahmoud,
O'Reilly, User’s Guide Sun JavaTM Wireless Toolkit for
CLDC Version 2.5.2, Sun MicroSystems, 'Java 2ME and
MIDP Development', John Muchow,
The Mobile Information
Device Profile and MIDlets, Part 2, Kim Topley, onjava.com



The Item Class

Below we recap the Item class hierarchy. Recall
that the Item class serves as the abstract parent
for elements that can be added to a form.


Item Class Hierarchy

Item
  |__ChoiceGroup
  |__CustomItem
  |__DateField
  |__Gauge
  |__ImageItem
  |__Spacer
  |__StringItem
  |__TextField


From last week as well, we finished
with the following
code, which used
two of the Item sub-classes, TextField
and StringItem.


Sample Using Form's Simple Constructor

import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class SimpleForm extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);

   Form form= new Form("SIMPLE FORM");
   StringItem instruction=new StringItem
("Name & Registration Number", "Please enter your first and last name, and your product registration number." );
 form.append(instruction);

   TextField firstField = new TextField("First Name",null,24,TextField.ANY);
   form.append(firstField);
  
   TextField lastField=new TextField("Last Name","",24,TextField.ANY);
   form.append(lastField);
 
   TextField regField = new TextField
("Registration Number",null,24,TextField.ANY);
   form.append(regField);
  
   display.setCurrent(form);
   }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}


As mentioned in last class, we can create an set
of objects and add them to the form as an array.
Alternatively we can use the append method.

The append method is overridden to take any of
the Item types and additionally a plain String or
Image object.


Overridden append( ) Methods

The int value represents an assigned index value
that is assigned for the element.


A General Note on Working with Images
// more to come later in the note


Note we had to use the static createImage( )
method to create an image based on a JPG.
The MicroEdition also supports images in
PNG format.

Put images in 'res' folder

Another key trick is that the image needs to be
placed in the res folder under the application
directory.


The forward Slash


A last point, the forward slash in front of the
image name is required to locate the image file.


Example

Image image = Image.createImage("/robin.jpg");

We will add details regarding handling images
later in the note.

The following code shows these items in use.



Appending Strings, Items and Images

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class MoreItems extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);

   Form form= new Form("BIRDS");
   form.append("\n     \n");

try{
   Image image = Image.createImage("/robin.jpg");
   form.append(image);
   }
catch(IOException ioe){form.append("Couldn't find image.\n");} 

   String string="\nV^V^V^V^V^V^V^V^V^V^V^V^V^V^V^V^V\n";
   form.append(string);
 
   StringItem str_item = new StringItem
("The Robin",
"The Robin is common in Southern Ontario. "   +
"This predator eats worms and other Robins "  +
"and has been known to attack in packs and "  +
"kill elk and deer. It's beak bite is very "  +
"poisonous and would be at home in Australia."
);
   form.append(str_item);
 
   display.setCurrent(form);
   }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}


Deleting Items

The int value that is returned by the append( )
method can be used to delete an item.

Example

form.delete(2);

You can add this line to the earlier code to
see it's effect.


The get ( ) and size( ) Methods

The get( ) method returns the object name
and address based on the index it is passed.

The size method returns the size of the Item
array.

Following we reuse the above code, printing to
console the representation of the size and objects.
The console output for the method calls is shown
below.

Notice that the string passed into the constructor,
isn't counted as part of the array that is created
with the append statements.

Notice as well, the System.out.println statement
that captures the index of the first append statement.
Comment it in and it yields the value '0' to console.


Example with get( ) and size( ) Methods

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class MoreItems extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);

   Form form= new Form("BIRDS");
// item 1
   int one = form.append("\n     \n");               // item 2
//  System.out.println( "one has the index: " + one);

 
try{
   Image image = Image.createImage("/robin.jpg");
   form.append(image);                
// item 3
   }
catch(IOException ioe){form.append("Couldn't find image.\n");} 

   String string="\nV^V^V^V^V^V^V^V^V^V^V^V^V^V^V^V^V\n";
   form.append(string);                   
// item 4
 
   StringItem str_item = new StringItem
("The Robin",
"The Robin is common in Southern Ontario. "   +
"This predator eats worms and other robins "    +
"and has been known to attack in packs. "      +
"
It's beak bite is very poisonous. "
);
   form.append(str_item);                 
// item 5
//   form.delete(2);

 
System.out.println(form.size( ));

System.out.println(form.get(0));
System.out.println(form.get(1));
System.out.println(form.get(2));
System.out.println(form.get(3));


   display.setCurrent(form);
   }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}

OUTPUT

___________________

4
javax.microedition.lcdui.StringItem@1cb37664
javax.microedition.lcdui.ImageItem@f828ed68
javax.microedition.lcdui.StringItem@ea0ef881
javax.microedition.lcdui.StringItem@84aee8b


Trying to access an element at index ' 4 '
will throw an IndexOutOfBoundsException.

There is more information provided for the
Image class below.


Nesting a ChoiceGroup in a Form


ChoiceGroup is similar to List in that it implements
the Choice interface. It also demonstrates a similar
construction pattern to the Form class. 


ChoiceGroup Constructors

ChoiceGroup(String label, int choiceType)
// creates a new, empty ChoiceGroup with title and type

ChoiceGroup(String label, int choiceType,
String[] stringElements, Image[] imageElements)
// creates a ChoiceGroup with title, type and an
// array of Strings and Images to be used as contents.


Another similarity, it has an append method. If you
don't want to use an image, you can null it out.

In the following code sample a Choice Group is
created and then nested inside a Form object.


Nesting a ChoiceGroup in a Form

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class Groups extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);
    Form form = new Form("Quiz");
    form.append("Choose which of the following you would " +
    "be comfortable in, flying to Hawaii? \n");
   

   ChoiceGroup gp = new ChoiceGroup("Planes",Choice.EXCLUSIVE);
    gp.append("Ultra-Light",null);
    gp.append("Cesna",null);
    gp.append("DC-8",null);
    gp.append("707 Jumbo",null);
    gp.append("Hot Air Balloon",null);
    form.append(gp);
    display.setCurrent(form);
   }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}



DateField

The DateField component is a fancy element visually
as it offers a calendar view of the current month. It
may be configured to a time zone using a TimeZone
object supplied to the constructor.


DateField Constructors

DateField(String label, int mode)
        // Creates a DateField object with the specified label and mode.
DateField(String label, int mode, TimeZone timeZone)
       // Creates a DateField object with calendar calculations based
       // on a specific TimeZone object and the default calendaring
       // system for the current locale.



TimeZone

The TimeZone object
represents a time zone offset, and
also figures out daylight savings.  TimeZone is a knock-off
of the java.util.TimeZone class first found in JDK 1.3.

getDefault( )

The getDefault( ) method gets the current time zone.

The following Date, Time constants allow you to select
Time, Date or both.


DateField Constants

Example


DateField.DATE


The following code shows DateField in action. This
component is pretty elaborate. It offers Date or time
if the Data_Time constant is used. The time is shown
digitally on the face or as an emulation of an analog
clock. The calendar allows going forward and
backwards in time.


DateField Example

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class DateCalendar extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);
    Form form = new Form("Calendar Dates ");
    DateField df =new DateField("My Calendar",DateField.DATE_TIME);
    form.append(df);
    display.setCurrent(form);
   }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}

Date and Time can be initialized with the setDate( )
method.

Example

datefield.setDate(new Date());

// there is a getTimeZone(String ID) method for which
// the only zone ID that has required support is "GMT"


Gauge

Another elaborate sub-class of Item is the Gauge
class. The Gauge class provides a Bar Graph
view. It has the the following single constructor.


Guage Class Constructor

Gauge(String label, boolean interactive,
                             int maxValue, int initialValue)

 // The Guage object is created with a given label, in either active
// or interactive modes and and given maximum and initial values.

Initial Values are given as constants. The values they
evaluate to are included below.


Gauge Initial Value Constants

Example

Gauge.CONTINUOUS_IDLE


Interactive mode allows the user to effect changes
to the gauge. The isInteractive( ) method returns a
boolean to say whether the gauge is interactive or
not. An interactive guage is useful for such things
as volume controls.

Following are the methods that Gauge supports,
shown without arguments or return types.


Gauge Methods

In the following sample different Gauge types are
shown. Notice we will need to add action processing
to do acheive some interactivity. 

Notice in the last gauge, interactivity is set to
false so it takes the form of a straight progress
bar.

Gauge Example

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class SoundGauge extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);
    Form form = new Form("Volume Control");
    Gauge volume =new Gauge("Volume",true,90,Gauge.INDEFINITE);
    form.append(volume);
    Gauge treble =new Gauge("Treble",true,70,Gauge.INCREMENTAL_IDLE);
    form.append(treble);
    Gauge mid =new Gauge("Mid",true,50,Gauge.CONTINUOUS_IDLE);
    form.append(mid);
    Gauge bass =new Gauge("Bass",true,30,Gauge.CONTINUOUS_RUNNING);
    form.append(bass);
    Gauge subs =new Gauge("Subs",true,10,Gauge.INCREMENTAL_UPDATING);
    form.append(subs);
    Gauge downloads =new

Gauge("Downloads",false,90,Gauge.INCREMENTAL_UPDATING);
    form.append(downloads); 

    display.setCurrent(form);

 }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}


Image and ImageItem


First let us add a little more detail regarding the Image
class.

Two sorts of images are described. 'Immutable' images
are normally loaded from somewhere, over the net or
from file. Images used by 'Alert', 'Form' or 'ImageItem'
have to use a 'hard' image, if we may call it that.

Mutable images, is created off-screen in memory
via a static call to a createImage( ) method call.

Following are the Image class createImage( ) methods.
They allow getting a handle on a image via arrays,
streams or sources.

Image Class createImage( ) Methods
// with arguments, all return an Image object

The easy one is the one we used where we opened on
a jpg file name, passed in as a String object.


Example

Image image = Image.createImage("/robin.jpg");


This is where we can remind you the forward slash is
for path resolution and the image is stored in the res
( for resource ) directory.


PNG vs JPG

Another interesting point, early APIs are only required
to support PNG formats. Our jpg file seems to work fine.
But this might not be the case with your target market.


JTWI Compliance
// the 'next' generation


You must be aware of what specification you are trying
to satisfy. JPEG or JFIF must be supported to be JTWI
compliant. PNG must be supported to be MIDP 2.0
compliant.

JTWI is thought to be the 'next generation' wireless
standard. Following is the link for the homepage of
JTWI.

To be safe, if you want to appeal to a general, lowest
common denominator audience, you should put your
images into PNG format.


JTWI Homepage

http://java.sun.com/products/jtwi/

Following are other methods of the Image class.
The first call shows that images can be used that
take advantage transparency.


Other Methods of the Image Class
        

ImageItem

The ImageItem class provides some controls over
the layout of images when they are added to forms
or alerts.

ImageItem has the following constructors.

ImageItem Constructors

ImageItem
(String label, Image img, int layout, String altText)

// creates an ImageItem with the given label, image,
// layout directive, and alternate text string.


ImageItem
(String label, Image image, int layout,
             String altText, int appearanceMode)

// creates a new ImageItem object with the given label, image,
layout directive, alternate text string, and appearance mode.


The Layout directives are represented by a set
of constants in the ImageItem class.


Layout Constants of the ImageItem class
// really should now be thought of as in the Item class


Example


Item.LAYOUT_CENTER

// for the explanation why Item rather than ImageItem
// is used in the example read on!



A Word on Newline Before and Newline After

Effectively 'New Line After' acts to put elements
before and after the image on their own line.
Using 'New line Before' keeps everything before
and after the image as close to being on the same
line as the screen allows.

The size of the emulator screen also impacts
how elements are layed out.


More Migration


Image Item has the layout directives that were originally
defined in MIDP 1.0. Some of these layout directives have
been  moved to the Item class. From this location they can
be applied to all items.

The declarations are left in the ImageItem class for
backwards compatibility. That is why, though listed in
the ImageItem documentation it is more appropriate
to reference the constants off of the Item class.

Item Layouts

In addition to the layouts that ImageItem declares,
the class also inherits the following layout directives
from Item class.

Item Class Layouts

Rules for Combining Layouts


The layouts can be combined with certain restrictions.

For instance

The following example shows one way to combine
the layouts so a newline is started after a centered
image. The general way in which constants are mixed
is to OR their values with the ' | ' operator.


Example

 ImageItem voltItem =new ImageItem("The Volt", volt,
 (Item.LAYOUT_CENTER | Item.LAYOUT_NEWLINE_AFTER),
  "Chev Volt");  


The following code shows the key advantage of ImageItem
in allowing some control over the placement of the Image
on the screen.


ImageItem Code Sample

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class ImageItem_EX extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);

   Form form= new Form("Electric Cars");
 
try{
   Image volt = Image.createImage("/volt.jpg");
   ImageItem voltItem =new ImageItem("The Volt", volt,
         Item.LAYOUT_CENTER, "Chev Volt");  

  form.append(voltItem);
   }
   catch(IOException ioe){form.append("Couldn't find image.\n");}
 
   display.setCurrent(form);
   }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}


Fonts and the Font Class

In the Java Standard Edition Fonts are part of the
discussion of Graphics, and a lot of controls are
provided for customizing the Font appearances.

In the MicroEdition, what you can do with fonts is
somewhat limited. According we treat Fonts as
a short standalone topic here in the note.

Essentially, you have controls for three attributes,
Face, Size and Style for which fixed values are
provided for each. These are as follows.

Descriptively, they may summarized as follows.


Font Attributes and Values

The real values are found in the Font Class
and are as follows.


Font Class Attributes


Example


Font.STYLE_BOLD

Font Faces vs Fonts

Notice the above show faces and fonts.
Faces are used with size and style attributes.
Fonts are complete in themselves.

The getFont( )  Methods

There are two getFont( ) methods, one for
use with fontspecifiers and one that takes
a face, style and size.


The Font getFont( ) Methods


'Asking' the System for a Font


It is not so obvious how you get a font. The documentation
indicates you 'ask' the system for a font that you can then
manipulated. When terms like 'ask' or 'suggests' are used
it means that the API has recommended to the Vendor
what they think should be provided however they leave it
to the Vendor to supply what they think is an appropriate
font.  Font's are traditionally an area where there is a lot of
platform specific  implementation.


The following code shows one way to mutate the fonts
on a StringItem.


Font Example

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class FontShow extends MIDlet{

public void startApp() {
   Display display = Display.getDisplay(this);

   Form form= new Form("Fonts");
 
    StringItem mono_underlined = new StringItem
("Face: Proportional Style: Underlined, \n Size Medium",
"A is for Ant");

// here is the formula used to here to get a Font
// with given styles

mono_underlined.setFont(
      Font.getFont( Font.FACE_PROPORTIONAL,      
      Font.STYLE_UNDERLINED,Font.SIZE_MEDIUM )
       );
  form.append(mono_underlined);
   display.setCurrent(form);
   }
public void destroyApp(boolean unconditional){}
public void pauseApp(){}
}




Assignment


Create a MIDlet that has at the top an image
of a fancy font or something to do with fonts.
You should be able to find something on the net.
This could be a picture of the old Gutenberg
printing press. Another option would be a nice
image would show up if you searched hand
writing and caligraphy. You can also create a
logo in a graphics program like 'Gimp'.

Add text that shows and examples each of the
Font class attributes reiterated below.

Font Class Attributes


You might which to use a StingItem object as
the title can be used to describe with attribute
you are demonstrating.

Practically, you may wish to make combinations
of the attributes on each example as is appropriate.
For instance, we only need to see one size for
each style.

// please report anomalies, for instance some
// fonts may not permit certain changes to be made


The StringItem class has a setFont( ) method
that might be used on each String Item.

You may have to keep your text short to get
all the types on screen.

Screenshot the emulator output and submit with
your MIDlet code.