J2ME Polish
J2ME Polish 2.4 Documentation
Enough Software

Touch Support

The J2ME Polish UI components support touch devices out of the box. This document describes additional features and explains how you can use gestures in your application.
This example demonstrates some features:

Touch Gestures

J2ME Polish supports various touch gestures that are demonstrated in the above movie:

Back Gesture

On screens that overlay a previous screen you can directly go back to the previous screen by clicking outside of the current screen's area.

Click Gesture

When tapping an item quickly, the default action for that item is triggered, on an Item that's typically the default command that you can specify with item.setDefaultCommand(Command).

Hold Gesture

The hold gesture is triggered when you tap an item and hold your finger on it.
You can specify that J2ME Polish handles the hold gesture by displaying all command actions that are associated with an item with following preprocessing variable:

<variable name="polish.Item.ShowCommandsOnHold" value="true" />

Add item commands by calling item.addCommand(Command) on the corresponding items.

Double-Tap Gesture

The double-tap gesture is triggered when you tap an item twice within a short duration.
Just specify a command that is triggered when an item is tapped twice by calling item.setDoubleTapCommand(Command). Note that you cannot use a default command and a double-tap command at the same time.

Alternatively you can also override the handleGestureDoubleTap(int x, int y) method on any Screen or Item subclass:

public boolean handleGestureDoubleTap(int x, int y)
{
	if (this.showInfo)
	{
		this.showInfo = false;
		this.infoTextField.setString("Double-tap happened");
		return true;
	}
	return false;
}

Swipe Right/Left Gesture

J2ME Polish also recognizes swipe left and swipe right touch gestures that you can use within your application easily. In the movie swipe right is used to to mark an article as read, and swipe left to mark it unread.

Reacting to Gestures

You can react to gestures in your application in different ways:

  • You can override Item.handleGesture( int gestureId, int x, int y ).
  • Alternatively implement and register an UiEventListener for specific items or screens.
  • Last but not least you can also create a global solution by implementing and registering an EventListener.

Override Item or Screen Methods

When you extend an J2ME Polish Item or Screen class, you can alternatively override one of the following methods:

  • protected boolean handleGesture(int gesture, int x, int y): is called for every recognized gesture.
  • protected boolean handleGestureHold(int x, int y): is subsequently called for the hold gesture
  • protected boolean handleGestureDoubleTap(int x, int y): is subsequently called for the double-tap gesture
  • protected boolean handleGestureSwipeLeft(int x, int y): is subsequently called for the swipe left gesture
  • protected boolean handleGestureSwipeRight(int x, int y): is subsequently called for the swipe right gesture

When you handle gestures in this way you should return true to mark that the event has been consumed as shown in the following code example:

import de.enough.polish.ui.StringItem;
...
public class MyStringItem extends StringItem {
	protected boolean handleGestureHold(int x, int y) {
		// do something fun here...
		BusinessLogic.handleGestureHold( this, x, y );
		// consume this event
		return true;
	}
}

UiEventListener

Another option to deal with gestures for a specific screen or item is to implement and register an UiEventListener. You will receive an UiEvent in the listener's callback method. Check if this is an GestureEvent and then proceed as wished. If you have handled the event please call GestureEvent.setHandled() to mark that the event has been consumed.

The following sample code demonstrates this option:

import de.enough.polish.event.UiEvent;
import de.enough.polish.event.UiEventListener;
import de.enough.polish.event.GestureEvent;
import de.enough.polish.ui.StringItem;
import de.enough.polish.ui.UiAccess;
...
//#style testButton
StringItem stringItem = new StringItem( null, Locale.get("gestures.test.button"));
UiAccess.setUiEventListener(stringItem,
	new UiEventListener() {
		public void handleUiEvent(UiEvent event, Object source) {
			if (event instanceof GestureEvent) {
				GestureEvent gesture = (GestureEvent)event;
				StringItem item = (StringItem)source;
				item.setText( gesture.getGestureName());
				// specify that we have consumed this event:
				gesture.setHandled();
			}
		}
	}
);

EventListener

If you want to handle gesture event globally, you should register a corresponding EventListener. Unless an event has been consumed by one of the above methods you will get notified in the handleEvent() method as shown in this example:

import de.enough.polish.ui.Item;
import de.enough.polish.event.EventManager;
import de.enough.polish.event.EventListener;
import de.enough.polish.event.GestureEvent;
...

public class GlobalEventHandler implements EventListener {
	private static GlobalEventHandler instance;
	private GlobalEventHandler() {
	}
	public static GlobalEventHandler getInstance() {
		if (instance == null) {
			instance = new GlobalEventHandler();
			EventManager.getInstance().addEventListener(GestureEvent.EVENT_GESTURE_SWIPE_LEFT, instance);
			EventManager.getInstance().addEventListener(GestureEvent.EVENT_GESTURE_SWIPE_RIGHT, instance);
		}
		return instance;
	}
	public void handleEvent(String name, Object source, Object evntData) {		
		// in this case we know that we only receive gesture events, so the source will be always an Item
		// and the data will always be a GestureEvent:
		Item item = (Item) source;
		GestureEvent event = (GestureEvent) evntData;
		if (event.getGestureId() == GestureEvent.GESTURE_SWIPE_LEFT) {
			// alternatively check: if (GestureEvent.EVENT_GESTURE_SWIPE_LEFT.equals(name)) 
			// handle gesture swipe left
		} else {
			// handle gesture swipe right
		}
		// specify that we have consumed this event:
		event.setHandled();
	}
}

Touch Support and Focus

By default, J2ME Polish clears the focus while dragging a scrollable area (e.g. a screen). When the up/down key is pressed on a touch device with directional keys / trackpad (e.g. the BlackBerry Torch) the focus is restored to the first visible item. To disable this feature you can set the following preprocessing variable:

<variable name="polish.Container.selectEntriesWhileTouchScrolling" value="true" />

With this preprocessing variable set to true, the focus remains on the last selected item when a scrollable area is dragged or scrolled.

:hover and :pressed on devices

If you are targeting touch enabled devices (or a dynamic device such as Generic/AnyPhone and run the app on a touch enabled device), then J2ME Polish will use the :hover style when no :pressed style is defined.
If you don't want this behavior and only use :pressed when it is actually used and want to apply :hover styles on touch enabled devices as well, then you set the preprocessing variable polish.Item.UseHoverStylesForTouchSystems to true:

	<variable name="polish.Item.UseHoverStylesForTouchSystems" value="true" />
	

Sample Application

Please have a look at the rssbrowser sample project.

JavaDoc

back to top