Last week I wrote about developing a simple hello world app for your blackberry. Today I want to go one step further and show you how to make a real world application that actually does something. Of course since we are all learning to use this new API I want to keep it simple, bare bones and straightforward. We can add bells and whistles later.
For now I just wanted to get a handle on using the basic GUI components, and capturing events such as pressing a button. I don’t particularly care how the app will look. I also don’t care about fancy stuff such as detecting the orientation flip in Storm.
What kind of application would fit all these criteria? Simple? Straightforward? No frills? And yet somehow useful. I pondered this for a little while and came up with this: a dice rolling application. You know, something that emulates rolling one or more dice of a certain type. It’s basically a random number generator attached to a GUI front end. And it’s useful too. Well, for me at least. The ability to generate random numbers in your phone comes in handy when you are into pen & paper RPG games like me.
So I drew up a simple design in my mind. The app would essentially have two input fields. One field would accept the number of dice to be rolled, while the other field would accept the type of dice. For those of you who don’t know this: yes, there are many types of dice. The die you usually see in casinos is what we call a d6 – a six sided dice. We role players also use d4, d8, d10, d12 and d20. When needed we also simulate a d100 by rolling two d10’s (you pick one dice to signify the tens and the other the ones).
The user will type in the values into the two fields, press a button and get the results. Simple and easy to develop. The end result should look like this:
How do we do this? Let me show it to you. I apologize for the wall of text code segment but the app is just a single class and a fairly short one at that. It really doesn’t make much sense to break this code up. Note that this project uses a driver class just like the one I shown you in the Halo World example. I omitted it here because it is all uninteresting boilerplate code. To actually run this code however, you will need to create one yourself.
import java.util.Random;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.text.NumericTextFilter;
public class DiceScreen extends MainScreen
{
private EditField howmany, dice;
public DiceScreen()
{
super();
LabelField applicationTitle =
new LabelField("Luke's Dice Roller");
setTitle(applicationTitle);
howmany =
new EditField("How Many? ", "2", 10, Field.EDITABLE);
howmany.setFilter(new NumericTextFilter());
add(howmany);
dice = new
EditField("What kind of dice? ", "6", 10,
Field.EDITABLE);
dice.setFilter(new NumericTextFilter());
add(dice);
ButtonField roll = new ButtonField("Roll");
add(roll);
FieldChangeListener listener = new FieldChangeListener()
{
public void fieldChanged(Field field, int context)
{
int h = Integer.parseInt(howmany.getText());
int d = Integer.parseInt(dice.getText());
String result = randomize(h, d);
Dialog.alert("Results: " + result);
}
};
roll.setChangeListener(listener);
}
private String randomize(int howmany, int dice)
{
String out = "";
Random generator = new Random();
for(int i=0; i
Very straightforward stuff. The EditField component is basically a combination of a label and input box. Instead of using two components you just do one, and it accepts a string argument that will display some text to the left of the input box. It also accepts the initial value, maximum length and style indicator (in that order).
Each EditField (or rather each Field) defines a setFilter method that lets you pass in a filter object that will prohibit imputing certain values. I'm passing in a NumericTextFilter object which is why the Blackberry Storm displays the numeric keyboard when that field is active.
Finally, I create a listener for my button by defining FieldChangeListener instance as an inner class. I then attach it to my button just like I would do it a Swing application.
I don't think I need to explain the random number generation procedure, since that's something you should already know how to do. If you don't, I recommend cracking open any Java book, or online tutorial. Random number stuff will probably be like on page 3 or something.
To keep things simple, I made the results appear in a modal dialog:
It works! Happy dance!
Of course this app has some serious problems. For one, it is ugly as hell. At least compared to most native Storm applications. It is also infuriatingly hard to navigate using the touch screen. You can't really see this in the emulator, but once you load this ting onto your phone, changing fields becomes frustrating. Because they are so close, a downward finger swipe will almost always skip the second field and highlight the button. And upward swipe on he other hand will highlight the first field. Getting to the second field is then a matter of careful finger placement.
This is an usability issue that needs to be resolved before this little simplistic app can be considered worth while. So this is what I want to talk about in the next post in this series. Adding bells and whistles. I want to make this app look pretty, and somehow space the fields out so that they can be easily navigated.
I'd also like to do something fancy - for example remove the button and attach the dice rolling action to the orientation switch event. This way you could actually roll the dice with a flick of your wrist. How awesome would that be? Of course it would require some testing to see how sensitive the device really is, and whether or not the roll would be accidentally t triggered during normal use.
Am bookmarking your site on my Curve 8310 under “Useful RIM API Info” as I am a new RIM developer and very new Java developer. And because RIM API documentation is worse than awful.
Any chance you could write a how-to post on event handling with the RIM API that is newbie-friendly?