Intercepting Trackwheel Events

In Chapter 11, the simple HelloBlackBerry program you created was extremely short — about 15 lines of code. Yet HelloBlackBerry managed to exhibit many of the standard features of a BlackBerry software program, including a title bar, a screen display, and automatic handling of the BlackBerry trackwheel. Adding these features required no effort on your part; they simply came free for the ride because your program by default included the features found in the base UiApplication and MainScreen classes that are provided as part of the BlackBerry SDK.

The method for telling the BlackBerry OS that your program should include the default behaviors of another class is to add the extends keyword to the code for your close, like so:

public class HelloBlackBerry extends UiApplication

This declaration tells the BlackBerry OS that HelloBlackBerry should assume behavior consistent with that of the built-in UiApplication class, unless it is told otherwise.

But what if you wanted your program to act slightly differently than the base UiApplication class? Would you have to abandon UiApplication entirely and add all of that default behavior yourself, just because you want to change one or two things? Absolutely not. One of the best things about working with objects and classes in Java is that you can decide which behaviors you want to keep and which behaviors you want to override. If you don't like a specific behavior provided by a base class, all you need to do to change it is replace that one behavior with your own code that does things the way that you want it to. When you do this, what you are telling the BlackBerry OS in effect is "Gee, thanks for offering this great function, but I think I'll handle it myself."

All BlackBerry programs that extend UiApplication get some free trackwheel handling as part of the deal. As you saw with HelloBlackBerry, a UiApplication-based program automatically knows how to handle some trackwheel events for you. This includes the display of a Close menu when you press and release the ESC button and the display of context-specific menus when user interface elements such as fields are present on the screen.

Your design for SketchBerry calls for the use of the trackwheel as the "control knob" for positioning and drawing on the screen. This is definitely not standard UiApplication behavior, so you need to override the default trackwheel methods and provide your own functionality that does what you want. In order to do this, you need to add custom handlers for the built-in methods trackwheelClick() and trackwheelRoll().

TrackwheelRoll Events and the TrackwheelListener trackwheelClick and trackwheelRoll are Java methods that are part of the BlackBerry-specific TrackwheelListener interface, found in net.rim.device.api.system.The TrackwheelListener interface allows you to create a class that "listens" for trackwheel events. The events that you are allowed to listen for are click, unclick, and roll. A click event is sent when the trackwheel is pressed in. An unclick event is sent when the trackwheel is released. A roll event is sent when the trackwheel is rolled (up or down).

By default, your application never sees these events, and the system takes care of them on your behalf. But by making your class TrackwheelListener, you get the opportunity to see these events inside your application and even perform your own custom actions when the events occur. So how do you make your class TrackwheelListener? It's actually easy. All you have to do is add the syntax implements TrackwheelListener to the class declaration line, like so:

public class SketchBerry extends UiApplication implements TrackwheelListener

This allows your class to add the special methods trackwheelClick, trackwheelUnclick, and trackwheelRoll. Note that you don't need to add all three methods. You can add one or two of them if that's all you need.

Most applications listen for trackwheel events so that they can create and display their custom menus at the appropriate time. In SketchBerry, you have a different purpose in mind, which is using the trackwheel to change the current drawing position on the screen. Take a look at some code that will process the trackwheelRoll event:

public boolean trackwheelRoll(int amount, int status, int time) {

if ((status & TrackwheelListener.STATUS_ALT) == 1) {

return false;

Once added to your code, the trackwheelRoll method will be called within your program each time the trackwheel is rolled up or down. If the trackwheel is rolled down, the amount parameter is positive, and if the trackwheel is rolled up, the amount parameter is negative.

What does the value of the amount parameter actually represent? Whatever you want it to represent. For an e-mail program that lists messages, it might make sense for this value to be the number of messages to scroll up or down in a list. In the MemoPad viewer it might be best to map this to the number of lines of text to scroll up or down. In SketchBerry you want to give the user a certain degree of precision with which to draw line segments, so you will interpret the amount parameter as the number of screen pixels to move the drawing cursor up or down. Different BlackBerry devices have varying screen dimensions, but my BlackBerry 8700 has a 320 x 320-pixel screen, so on my screen it would take 320 single rolls of the trackwheel to draw a vertical line from the top of the screen to the bottom of the screen.

Tracking the Current Drawing Position

The main reason you want to receive trackwheelRoll events is so that you can track the position of the SketchBerry drawing cursor as it moves around the screen. Ultimately, you will need to respond to these movements by drawing lines in the proper direction, but for now it will suffice to use a couple of program variables called _newVertPos and _newHorzPos to store the new x/y position of the drawing cursor on the screen. These variables are declared as private integers at the top of your main SketchBerry class:

private int _horzPos; private int _vertPos;

By adding the value of the amount parameter to _newVertPos, you are able to track the movement of the SketchBerry cursor up or down the screen.

As mentioned in the earlier SketchBerry design section, horizontal drawing is enabled by pressing and holding down the ALT key. You can tell whether the ALT key is pressed by using the following piece of code:

if ((status & TrackwheelListener.STATUS_ALT) == 1)

So if the ALT key is pressed, your code applies the amount value to the horizontal position variable _newHorzPos; otherwise it is applied to the vertical position variable _newVertPos.

Starting and Stopping Drawing Mode with TrackwheelClick

Because SketchBerry will be tracking the drawing position based on trackwheelRoll events, where should the drawing position start when SketchBerry launches as an application? You can put it anywhere, but you can start by trying the cursor out at the upper-left corner of the screen, at x/y position (0,0). This, however, causes a little bit of a problem in that all drawings made with SketchBerry would start in the upper-left corner and consist of a single continuous line that winds around the screen. That could be restrictive, so add the concept of a drawing mode to the program. The initial drawing mode would be off, which allows the user to position the cursor wherever he wants before drawing starts. Furthermore, the drawing mode could be toggled on or off at any point, which in effect lets the user "lift their pen up," move it to a different location, and then place the pen back down to start drawing again.

The drawing mode state can be tracked with a simple Boolean variable _drawing, and _drawing can be flipped to true or false by trapping the trackwheelClick event, like so:

public boolean trackwheelClick( int status, int time ) {

_drawing = !_drawing; return true;

Things are getting a little more interesting now that you can keep track of a drawing position as the user moves it horizontally and vertically around the screen with the trackwheel. But SketchBerry still doesn't really do anything useful yet. It's time to start drawing!

0 0

Post a comment

  • Receive news updates via email from this site