The Paint MIDlet integrates multipoint touch functionality for Series 40 full touch devices while maintaining backwards compatibility with older devices. Multipoint touch functionality is implemented using the Multipoint Touch API.
Note: The Multipoint Touch API is supported on Series 40 devices with Java Runtime 2.0.0 for Series 40 or newer.
Supporting multipoint touch involves handling the different touch points separately. This is achieved by using touch point IDs. To draw multiple lines at the same time, the MIDlet needs a separate buffer for each line. The MIDlet is implemented to scale for two or more touch points. The MIDlet also works on devices that do not support multipoint touch ("single touch point"). This backwards compatibility is achieved by isolating the multipoint touch functionality from the rest of the MIDlet, that is, by wrapping it so that it can be accessed only when it is supported by the device. For more information about this approach, see article How to use an optional API in Java ME in the Nokia Developer Wiki.
Figure: Multipoint touch interface
Use the MultipointTouchListener
interface to implement
a listener for multipoint touch events. While the MultipointTouchListener
callback methods differ somewhat from the pointer methods available
in the Canvas
class, they can be easily mapped to
the pointer methods. To support both pointer events and multipoint
touch events, the event handling needs to be transferred to a new pointerDragged
method that supports touch points. On devices
that do not support multipoint touch, the new method is called from
the standard pointerDragged
method. Devices that
support multipoint touch call the new pointerDragged
method directly.
public void pointerDragged(int x, int y) { if (TOUCH_POINTS == 1) { pointerDragged(x, y, 0); } } // ... public void pointerDragged(int x, int y, int id) { if (!drawingAllowed && colorpicker.isVisible()) { colorpicker.dragged(x, y); } else if (y > Toolbar.HEIGHT) { buffers[id].addElement(new DrawableLine(previousX[id], previousY[id], x, y)); previousX[id] = x; previousY[id] = y; } }
The buffers and previous coordinates are stored in arrays, which
are indexed using the touch point IDs. The following code snippet
shows the implementation of the pointerChanged
method,
which is called by the isolated Multipoint Touch API.
public void pointersChanged(int[] ids) { for (int i = 0; i < ids.length; i++) { int id = ids[i]; int x = MultipointTouch.getX(id); int y = MultipointTouch.getY(id); switch (MultipointTouch.getState(id)) { case MultipointTouch.POINTER_PRESSED: touchListener.pointerPressed(x, y, id); break; case MultipointTouch.POINTER_DRAGGED: touchListener.pointerDragged(x, y, id); break; case MultipointTouch.POINTER_RELEASED: touchListener.pointerReleased(x, y, id); break; } } }
Line rendering also needs to be updated to support multiple buffers,
but this simply involves one additional for
loop
for going through all the touch points.