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.

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" />

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 differnent 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 Methods

When you extend J2ME Polish Items you can alternatively override on 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 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

The least invasive way 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.ui.UiAccess;
import de.enough.polish.event.UiEvent;
import de.enough.polish.event.UiEventListener;
import de.enough.polish.event.GestureEvent;
import javax.microedition.lcdui.StringItem;
...
//#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();
	}
}

Virtual keyboard

When using TextFields in your Screens you can also use an virtual keyboard to enter text. This allows you to edit text inline instead of opening up a native editor which might require more clicks or which might confuse the user. Please have a look at the virtual keyboard documentation.

Sample Application

Please have a look at the rssbrowser/News Cup sample application for a real world example. You can also download this demo app on m.j2mepolish.org under the name 'News Cup'.

JavaDoc