Assembling of Resources

Select and organize your resources automatically - it's easy to set up, but extremely powerful!

Example Resource Structure

Concepts

During the build process resources like images, sound files etc. are assembled autmatically for each device.

Place all your resources into the ${project.home}/resources folder (when no other directory has been specified in the <resources> element or with the resDir attribute of the <build> element in your build.xml script).

In case you have specific resource that only should be added for some devices, you can put these into correspondingly names subfolders of the resources directory.
You can have the resource bg.png in both the resources as well as the resources/ScreenSize.240+x320+ folders, for example. When you now build your application for a device with a screen size of at least 240 pixels wide and 320 pixels high, the resources from resources/ScreenSize.240+x320+ will be included in your application - they will overwrite generic resources with the same name that are placed in the resources directory.

Resources for devices of specific vendors can be placed into the "resources/[vendor-name]" folder, e.g. the "resources/Nokia" folder for Nokia devices. Resources for a specific device can be placed into the "resources/[vendor-name]/[device-name]" folder, e.g. the folder "resources/Nokia/N95" for Nokia/N95 devices.

You can refer to any device capability that has been defined in the device database for

All resources will be copied to the root of the application and more specific resources will overwrite the common resources: If you have a picture named "hello.png" in the "resources" folder as well as in the "resources/Nokia" and in the "resources/Nokia/N95 " folder, the version in the "resources" folder will be used for all non-Nokia devices, the version contained in the "resources/Nokia" folder will be used for all Nokia devices, but the image "resources/Nokia/N95 /hello.png" will be used for the application which is build for the Nokia/N95 phone.
In the application code you can load this image as any other resource from the root:

Image.createImage( "/hello.png" );

In case you want to include subfoldersin your application's JAR file, you need to use a root directory with enabled includeSubDirs attribute. Please see below for more details.

The adjustments of designs for different devices is described in the CSS-documentation.

Often Used Directories

Here are some examples for commonly used directory names:

GroupTypeDefault FolderExplanation
IconSize.16x16 Capability resources/IconSize.16x16 Folder for different icon sizes of the target devices, e.g. IconSize.16x16 or IconSize.56x56 and so on. You can use the IconSize.0x0 for storing icon resources for devices with an unknown IconSize capability.
ScreenSize.176x208 Screen resources/ScreenSize.176x208 Folder for different screen sizes of the target devices, e.g. ScreenSize.176x208 or ScreenSize.128x128 and so on.
ScreenSize.240+x320+ Screen resources/ScreenSize.240+x320+ Folder for devices with screens that are as large or larger than the specified screen size. In the example the screen needs to be at least 240 pixels wide and 320 pixel high so that resources from that folder are included.
CanvasSize.176x208 Canvas resources/CanvasSize.176x208 Folder for different canvas sizes of the target devices, e.g. CanvasSize.176x208 or CanvasSize.128x128 and so on.
CanvasSize.170+x200+ Canvas resources/CanvasSize.170+x200+ Folder for devices with canvassses that are as large or larger than the specified canvas size. In the example the canvas needs to be at least 170 pixels wide and 200 pixel high so that resources from that folder are included.
FullCanvasSize.176x208 FullCanvas resources/CFullanvasSize.176x208 Folder for different canvas sizes in fullscreen-mode of the target devices, e.g. FullCanvasSize.176x208 or FullCanvasSize.128x128 and so on.
FullCanvasSize.170+x200+ Canvas resources/FullCanvasSize.170+x200+ Folder for devices with canvassses that are as large or larger than the specified canvas size in fullscreen-mode. In the example the canvas needs to be at least 170 pixels wide and 200 pixel high in the fullscreen-mode so that resources from that folder are included.
mp3 audio resources/mp3 For devices which support the MP3 sound format.
amr audio resources/amr For devices which support the AMR sound format.
midi audio resources/midi For devices which support the MIDI sound format.
polish.audio.mp3 and not polish.audio.amr Preprocessing Term resources/polish.audio.mp3 and not polish.audio.amr You can use any preprocessing term as a directory name as well.
mpeg-4 video resources/mpeg-4 For devices which support the MPEG-4 video format.
3gpp video resources/3gpp For devices which support the 3GPP video format.

Structure Your Resources with Root Directories

While the default resource assembling mechanism is quite powerful, you might want to structure your resources a bit better or include subdirectories in your application as well. Your can easily achieve this by defining <root> elements in your build.xml script:

<resources
	dir="resources/base"
	defaultexcludes="yes"
	excludes="readme.txt"
>
	<root dir="resources/base/design" />
	<root dir="resources/base/sounds" />
	<root dir="resources/base/images" />
	<root dir="resources/base/images/largescreens" 
		if="polish.ScreenWidth &gt;= 240 and polish.ScreenHeight &gt;= 300" 
	/>
	<root dir="resources/base/images/i18n" 
		includeSubDirs="true" includeBaseDir="true" excludes="CVS, readme*" 
	/>
</resources>

Now you can put all sounds, images and the polish.css design into their own subfolder hierarchy. Each <root /> provides another starting point for the normal resource assembling mechanism described above.

Sometimes you will want to keep subfolders for your resources as well. You might want to add all localization dependent resources, for example, and allow your user to switch the localization dynamically. Image following resource structure with the language dependent flag.png resource:

resources/base/images/i18n/en/flag.png
resources/base/images/i18n/de/flag.png
resources/base/images/i18n/dk/flag.png
resources/base/images/i18n/fr/flag.png
resources/base/images/i18n/es/flag.png
resources/base/images/i18n/cn/flag.png

You can include the complete i18n directory with all its subfolders with this <root /> definition with activated includeSubDirs="true" setting:

<root dir="resources/base/images/i18n" 
	includeSubDirs="true" includeBaseDir="true" excludes="CVS, readme*" 
/>

You can now load the language dependent resource with this code:

Image flag = Image.createImage( "i18n/" + Locale.LANGUAGE + "/flag.png" );

Fine Tuning the Resource Assembling

Sometimes it is necessary to adjust the resource assembling.
The easiest way is to use conditional <root> settings:

<root dir="resources/base/images/largescreens" 
	if="polish.ScreenWidth &gt;= 240 and polish.ScreenHeight &gt;= 300" 
/>

In the above example you include resources from resources/base/images/largescreens only for target devices with a screen resolution of at least 240x300. And again you can use subdirectories within the largescreens folder for making differentations, e.g. by having an image in resources/base/images/largescreens/Sony-Ericsson/.
If you are building your application for a device with an unknown or a resolution less than 240x300, resources will be loaded from the other roots, typically from the resources folder.

Note that you have to escape any XML characters in your if condition, since you are defining them within the build.xml script.
Instead of writing if="polish.ScreenWidth &gt;= 240" you need to escape the > character into &gt;, for example. And instead of using && you should use and to combine conditions - alternatively you can also escape it into &amp;&amp;.

By the way - you can use <root> directories for customizing your application as well.

Excluding Resources

Sometimes it's much easier to exclude a resource for one or some devices than to include them for the rest of devices. The easiest way for doing this is to add a resource with the same name but with a size of 0 bytes into the appropriate subfolder:

${project.home}/resources/playback.wav
${project.home}/resources/Nokia/N95/playback.wav

If the playback.wav file in the ${project.home}/resources/Nokia/N95/ folder is 0 bytes in size, the build for Nokia/N95 device will not include this file.
On Unix based operating systems you can use the touch command line command for creating such a file:

$ mkdir resources/Nokia/N95/
$ touch resources/Nokia/N95/playback.wav

Alternatively you can use a nested <filter> element:

<filter excludes="*.mid" if="polish.audio.midi and polish.audio.amr" />

The above example will include all MIDI files if the target device supports both MIDI as well as AMR sound formats.

Tips & Tricks

Resources often use up a considerable if not the biggest amount of JAR size of your application. Here are some tips how you can limit the used space of your resources and how you can adapt them easily to your target devices.

Optimize the Size of Resources

You can often save a considerable amount by optimizing your resources.
Image sizes can be limited by reducing the number of colors and by removing unecessary headers. Sound files can be made leaner by reducing the sample rate and using an mobile optimized format like AMR.

There are also tools like pngout, Pngcrush or OptiPNG that help you to optimize PNG images - use them!

Download Resources Later

An effective way to trim down your JAR size is to exclude resources completely. You can then later onwards download these resources from within your application and store them into the Recordstore (RMS) of the device.

A drawback of this method is that you need to have a working network connection, which is not always a trivial task.

You also need to make some adjustments so that J2ME Polish UI components can still access images which are referenced by CSS styles. You have to provide a class or object that defines the public Image loadImage( String url ) throws IOException method and register this class by defining the preprocessing variable polish.classes.ImageLoader:

<variable name="polish.classes.ImageLoader" value="com.company.ResourceManager" />

Now you have to provide the method as well:

package com.company;
import javax.microedition.lcdui.Image;
import java.io.IOException;
import java.io.InputStream;

public class ResourceManager {
	public static Image loadImage( String url )
	throws IOException
	{
		InputStream in = getResourceAsStream( url );
		Image image = Image.createImage( in );
		in.close();
	}
	
	public static InputStream getResourceAsStream( url ) 
	throws IOException
	{
		//TODO retrieve resource from RMS
		return null;
	}
}

Download Translations Later

You can also externalize translations and download them at a later point in your application.

Adjust Resources during Build Time

It often quite difficult to provide device optimized resources for all your target devices. J2ME Polish can help you to scale resources using the svgconverter Resource Copier:

<resources 
 dir="resources" excludes="readme*, *.definition" > 
  <copier name="svgconverter" />
</resources>

The svgconverter resizes all icon*.svg and bg*.svg automatically to the icon and the screen size of the current target device and saves them as PNG files with the same name.

Adjust Resources during Run Time

Especially during the first iterations of a new project you don't want to provide images for all screen resolutions et cetera. You can use the
scaling-image background scaling-image background for adapting images automatically during runtime.

A Life without Resources

Adapting images for different devices is not only hard work, you sometimes even don't know the screen resolutions at build time, for example when you are targeting a generic device like Sony-Ericsson/JavaPlatform8.

J2ME Polish provides many design options that do not need images at all. Instead of using an image for realizing a gradient background, you can just use the vertical-gradient background, for example. Thanks for complex backgrounds like the combined background and the mask background you can also realize unusual formed backgrounds like having a gradient within a round-rect background.