Handling gesture events

To handle gesture events for a UI element set to receive them, the MIDlet must implement the GestureListener class. You can define multiple GestureListeners for a MIDlet.

To handle gesture events:

  1. Create a listener class that implements GestureListener.

    The following code snippet creates the framework for the MyGestureListener custom class.

    // Import the necessary classes
    import com.nokia.mid.ui.gestures.GestureEvent;
    import com.nokia.mid.ui.gestures.GestureInteractiveZone;
    import com.nokia.mid.ui.gestures.GestureListener;
    
    public class MyGestureListener implements GestureListener {
    
        // Implement gestureAction
        // (see step 2 of this example)
    
    }
  2. Define the gestureAction method for the class. This method is called every time a gesture event occurs for a UI element that uses MyGestureListener. The method is called with all the information related to the gesture event.

    The following code snippet creates the framework for a gestureAction implementation.

    public void gestureAction(Object container,
                              GestureInteractiveZone gestureInteractiveZone,
                              GestureEvent gestureEvent) {
    
        // Handle received gesture events
        // (see step 3 of this example)
    
    }

    The gestureAction method is called with the following parameters detailing the gesture event:

    Table: gestureAction parameters

    Parameter

    Description

    Type

    container

    The UI element for which the gesture event occurred. This is either a Canvas or CustomItem instance.

    Object

    gestureInteractiveZone

    The GestureInteractiveZone instance in which the gesture event occurred. This is one of the interactive zones registered for the UI element specified in container.

    GestureInteractiveZone

    gestureEvent

    The gesture event that occurred for container in gestureInteractiveZone.

    The GestureEvent object provides a number of methods for retrieving data about the gesture event. Each type of gesture event supports a specific subset of methods. To retrieve the type of the current gesture event, use the getType method:

    int gestureEventType = gestureEvent.getType();

    The method returns one of the gesture event constants defined in the GestureInteractiveZone class.

    For more information about the methods supported for each type, see the following table.

    GestureEvent

  3. Handle the gesture events returned by the gestureAction method. Use the GestureEvent.getType method to determine the gesture event type and then call the appropriate methods to retrieve the event details (see the following table). You can handle the gesture events either directly in the gestureAction method, or you can use the gestureAction method to call separately defined handlers. For information about optimizing the gestureAction method for performance, see Using the gestureAction method correctly.

    Table: Supported GestureEvent methods per gesture event type

    Gesture event type

    Supported methods

    Description

    GESTURE_TAP

    GESTURE_DOUBLE_TAP

    GESTURE_LONG_PRESS

    GESTURE_LONG_PRESS_REPEATED

    getType

    getStartX

    getStartY

    The getStartX and getStartY methods return the coordinates (x pixels, y pixels) where the gesture occurred. The coordinates are relative to the top left corner (0,0) of the UI element.

    GESTURE_DRAG

    GESTURE_DROP

    getType

    getStartX

    getStartY

    getDragDistanceX

    getDragDistanceY

    The getStartX and getStartY methods return the coordinates (x pixels, y pixels) where the associated drag gesture started, that is, where the initial touch down event occurred. Therefore, the GESTURE_DRAG events registered for a given drag gesture always return the same coordinates. The coordinates are relative to the top left corner (0,0) of the UI element.

    For a GESTURE_DRAG event, the getDragDistanceX and getDragDistanceY methods return the number of pixels moved horizontally (x-axis) and vertically (y-axis) since the previous GESTURE_DRAG event or, if the event is the first GESTURE_DRAG event for the gesture, since the initial touch down event that started the gesture.

    For a GESTURE_DROP event, the getDragDistanceX and getDragDistanceY methods always return 0.

    GESTURE_FLICK

    getType

    getStartX

    getStartY

    getFlickDirection

    getFlickSpeed

    getFlickSpeedX

    getFlickSpeedY

    The getStartX and getStartY methods return the coordinates (x pixels, y pixels) where the flick gesture started. The coordinates are relative to the top left corner (0,0) of the UI element.

    The getFlickDirection method returns the direction of the flick gesture in radians. The value can range from -p radians to p radians. 0 indicates a direction to the right along the x-axis, while -p and p indicate a direction to the left along the x-axis.

    The getFlickSpeed method returns the flick speed in pixels per second in the flick direction. The getFlickSpeedX and getFlickSpeedY methods return the horizontal (x-axis) and vertical (y-axis) flick speeds in pixels per second, respectively.

    GESTURE_PINCH

    getType

    getStartX

    getStartY

    getPinchCenterX

    getPinchCenterY

    getPinchCenterChangeX

    getPinchCenterChangeY

    getPinchDistanceStarting

    getPinchDistanceCurrent

    getPinchDistanceChange

    The getStartX and getStartY methods return the coordinates (x pixels, y pixels) where the second finger originally touched the screen. The coordinates are relative to the top left corner (0,0) of the UI element.

    The getPinchCenterX and getPinchCenterY methods return the coordinates (x pixels, y pixels) of the current center point between the two fingers involved in the pinch gesture. For example, if one finger is located at (10,10) and the other at (100,100), the current center point is at (55,55), meaning getPinchCenterX and getPinchCenterY both return 55.

    The getPinchCenterChangeX and getPinchCenterChangeY methods return the relative number of pixels the center point has moved horizontally (x-axis) and vertically (y-axis) since the previous GESTURE_PINCH event. For example, if the previous center point was at (55,55) and the current one is at (60,60), the center point has moved 5 pixels positive both horizontally and vertically, meaning getPinchCenterChangeX and getPinchCenterChangeY both return 5. If the current center point was instead at (50,50), both methods would return –5, since the center point would have moved 5 pixels negative.

    The getPinchDistanceStarting method returns the distance in pixels between the fingers at the start of the pinch gesture.

    The getPinchDistanceCurrent method returns the current distance in pixels between the fingers.

    The getPinchDistanceChange method returns the relative change in pixels in the distance between the fingers since the previous GESTURE_PINCH event. For example, if the previous distance was 50 pixels, and the current distance is 60 pixels, the distance has changed by 10 pixels positive, meaning getPinchDistanceChange returns 10.

    Tip: To implement continuous zooming with a pinch gesture, you need to know when and where the pinch gesture ends. Use the GESTURE_RECOGNITION_END event to retrieve the end coordinates per finger of the pinch gesture. A pinch gesture always ends in two consecutive GESTURE_RECOGNITION_END events, one per finger. To avoid false end events, create a GestureInteractiveZone that only receives GESTURE_PINCH and GESTURE_RECOGNITION_END events.

    GESTURE_RECOGNITION_START

    GESTURE_RECOGNITION_END

    getType

    getStartX

    getStartY

    For a GESTURE_RECOGNITION_START event, the getStartX and getStartY methods return the coordinates (x pixels, y pixels) where the gesture started, that is, where touch down occurred.

    For a GESTURE_RECOGNITION_END event, the getStartX and getStartY methods return the coordinates (x pixels, y pixels) where the gesture ended, that is, where touch release occurred.

    Both events are generated once for each finger involved in the gesture. For example, for a tap gesture, both events are generated once, since tapping involves only one finger, while for a pinch gestures, both events are generated twice, once for each finger involved in the pinch gesture.

    Note: GESTURE_DOUBLE_TAP is supported only in Nokia Asha software platform 1.0.

    The following code snippet handles received gesture events by first determining their type and then calling the corresponding getter methods to store the event details in local variables. In this example, the GestureInteractiveZone only receives taps and long taps, so GESTURE_TAP and GESTURE_LONG_PRESS are the only gesture events that need handling.

    // Retrieve the tap or long tap details and store them
    switch (gestureEvent.getType()) {
        case GestureInteractiveZone.GESTURE_TAP:
        case GestureInteractiveZone.GESTURE_LONG_PRESS:
            try {
                int startLocationX = gestureEvent.getStartX();
                int startLocationY = gestureEvent.getStartY();
            } catch (IllegalStateException e) {
                ;
            }
            break;
    }

Using the gestureAction method correctly

The gestureAction method is called from the MIDlet UI thread. This single thread is shared by all UI notifications, key and pointer events, command actions, and other UI operations. To maximize performance, handle any time-consuming or resource-intensive gesture operations in a separate thread. If you program the MIDlet to perform lengthy operations directly in the gestureAction method, and thus in the MIDlet UI thread, these operations can block other UI events and operations and cause the user interface to become unresponsive.

During a drag gesture, the platform can generate a large number of drag event notifications and thus a large number of calls to the gestureAction method. To prevent the Java memory heap from filling up and fragmenting with multiple GestureEvent instances, the platform recycles the same GestureEvent instance for each call. The GestureEvent values are therefore valid only during the current gestureAction call, since each call overwrites the single GestureEvent instance with its own values. If you access a copy of the GestureEvent instance from outside the gestureAction method, and thus outside the MIDlet UI thread, the returned values are those from the latest gestureAction call. The values are not from the call during which the copy was originally created. If you need to use the GestureEvent values for a specific gesture event outside the gestureAction method, copy the values from GestureEvent instance before returning from the gestureAction method.