(For more resources on BlackBerry, see here.)
So, without any further words, let's get to work!
Remember that the first step is to choose the SDK version to use. For this project we want to choose the lowest possible SDK version, which is 4.2.1. This is because this application is so simple that it will not need to use any of the newer features of more recent versions of the SDK.
By choosing a lower version, more models of handheld can be used to run this application. Conversely, choosing a higher SDK version means that fewer models of handhelds can run the application. Therefore, you should choose the lowest version of the SDK that still supports the features you require in order to support as many devices as possible. We will go through the steps of actually applying this later on, but for now, the choice is made and we are ready to move on.
You need to create a new project for your new application. The IDE makes it very simple to get started, but because you are creating a BlackBerry project you have to be careful. Let's get started and see what I mean.
These three steps are all that is needed to create a BlackBerry project in Eclipse.
You were told earlier that choosing New | Java Project was not the right thing to do. This is because the wizard that you get from choosing this menu item is the Swiss Army Knife wizard that will set up any kind of project for Eclipse. It is powerful, complicated, and not for beginners. Because of this, we just won't use it at all. The BlackBerry Project option is much easier to use, you just have to remember to use the New | Project... option instead of the New | Java Project option.
Once you have chosen the right menu item, the New Project dialog is shown. Apparently, it is possible to have so many project types available that finding the one you want can be a challenge. The text field at the top of the dialog will filter the tree below to include only projects whose name matches the filter test. In our case though, the BlackBerry project is right near the top and easily accessible so there really isn't a need for the search feature.
The last step of the wizard prompts you to enter the name of your new application. Project names are used as a directory name but are not used in code so they can have some special characters, such as a space, which would otherwise be invalid for code. If you try to provide a name that is invalid the wizard will show a warning about the name to indicate the name is not valid.
Below the Project name text box is a checkbox indicating to use the default workspace location. By leaving the box checked the new project will be placed in a directory named after the project name under the directory set as the workspace. You can change the location where the new project files are stored by unchecking the Default location checkbox and then entering a new location in the edit field provided.
Next, you will create a new package for the application to use. A Java package is a container for the objects in your application and is used to prevent conflicts if the classes you create happen to have the same name as another class in the same project or even the system classes. Packages are equivalent to namespaces in C# and Visual Basic .NET (VB.NET).
Adding a package to the project in this way is a minor housekeeping task, but is also an overall good technique because it forces you to choose your package name up front before creating any code. In Java, the naming convention for a package is to use your Internet domain name in reverse—almost like you were creating a new server. In this case, we will use the package name com.rimdev.demo.tipcalc. The package name can be any valid Java name and doesn't have to follow these conventions.
At this point you have an empty project that is ready to start being used. You've taken the BlackBerry application project that you had before and added a package to the src directory in preparation for creating the actual source files (which will come next).
The project tree is expanded slightly to include the package you just created under the src directory—the directory whose icon looks like a little mail parcel. Creating a package in your project doesn't result in any actual source files being created. Instead, it sets up the project so that when you do create files later on they will be created with package definitions already included in them.
Every application must have a starting point, and for BlackBerry applications it is at a method named main. The use of the name main goes all the way back to the C programming language, if not further. At that time, simply making a method named main was enough to be able to run an application. However, because Java is an object-oriented language, you can't just make a method named main. In Java, all methods must be in a class, and this includes the method main as well.
In addition to the main method all BlackBerry applications must contain an object derived from Application as well. As both the Application-derived class and the main method are required, it is standard practice to include the main method in the same class as your Application.
As we just said, every BlackBerry application must contain a class derived from Application. The Application class contains the bare essentials for interacting with the BlackBerry operating system. If an application displays a User Interface (UI) then the bare essentials in the Application class are not enough. Instead, you should use UiApplication—the derived class that handles the special processing needed to interact with the user as well as the operating system.
So, the next step is to create a class derived from UiApplication and that contains the main method to serve as the starting point of your BlackBerry application.
The next step is to set the superclass for your new class. The superclass is another name for a base class, or the class from which your new class will be derived. Eclipse offers a strong browser tool to quickly and easily find the class.
You just created the first class for use in your new application! Well, to be more accurate you used Eclipse to set up a new class with some standard elements based on how you filled out the dialog. You could have done the same thing by simply creating a new file and manually adding all of the code by hand, but that's just not as interesting, is it? To be real though, the tools that Eclipse provides are truly helpful and easy to use.
The New Java Class dialog that is displayed has many options that can be set and which will cause Eclipse to generate different code. Notice that the package name has already been supplied in the dialog because we started creating this class by right-clicking on the package name in the project. Also, the Source Folder is properly set already because you created the package inside the src folder previously.
Now, let's look at the code that was generated.
package com.rimdev.demos.tipcalc;
import net.rim.device.api.ui.UiApplication;
public class TipCalcApplication extends UiApplication {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
The first line of code is the package declaration for com.rimdev.demos.tipcalc. This line defines the package where the TipCalcApplication class will reside. The package can be specified in the New Class dialog but because we previously added the package to the project, the package was supplied automatically to the new New Class dialog.
package com.rimdev.demos.tipcalc;
The next line is an import statement for net.rim.device.api.ui.UiApplication. Import statements are similar to .NET using or imports statements and declare which libraries are being used. The Java convention is to specifically import each class being referenced. It is possible to wildcard the import statement though, in which case the class name would be replaced with *, that is, net.rim.device.api.ui.*.
When doing this all of the classes in that package will be imported into your application and this can make coding easier. It can certainly be annoying having to go back each time you want to use a new class and add the import statement for it. Eclipse is pretty smart and shouldn't include any classes unless they are actually being used when it compiles your application, so there shouldn't be any negative impact on performance. Having said all that, the established convention is not to use wildcarding because it also makes it less clear for someone looking at your application later on to know exactly which classes are being used. In the end, it is probably best to stay with the established convention, which we will do in this article.
import net.rim.device.api.ui.UiApplication;
Next, we have the class declaration itself. Again, notice that the extends keyword is already added and the class chosen to be the superclass, UiApplication, is added as well. These are added because we chose the UiApplication to be the superclass in the New Class dialog.
public class TipCalcApplication extends UiApplication {
Lastly, notice that the public static void main method is also created. Remember that every application must have a main method, and this is that method. The method was added because we checked the checkbox for it. Very simple and easy! The words public and static are special keywords that allow the main method to be called by the system before any of the objects in your application are created.
public static void main(String[] args) {
// TODO Auto-generated method stub
}
Now that you have the class created with some of the boilerplate code it's time to expand it and make the application actually do something.
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// Create a new instance of the application.
TipCalcApplication theApp = new TipCalcApplication();
// To make the application enter the event thread and start
processing messages,
// we invoke the enterEventDispatcher() method.
theApp.enterEventDispatcher();
}
private TipCalcApplication()
{
// Push the main screen instance onto the UI stack for
rendering.
pushScreen(new TipCalcMainScreen());
}
The code that you just added takes the simple generated code that you got from the New Class wizard and expands it to set up and start the application.
The first thing you did was to put some code in the initially empty main method. This code in the main function is used to actually create an instance of the application's object, which happens to contain the main method. This may seem strange unless you are used to it and understand what the static keyword means. If not, then just understand that static means that the main method can be called without an instance of the object that contains it. You still do need to create an instance of the application though, and so that's the first step.
theApp = new TipCalcApplication();
The next line of code in the main method is the call to the enterEventDispatcher method on the application that you just created. This is a method already implemented in the UiApplication class. It does all of the setup necessary to get the application started, runs the application, and waits until the application is finished.
theApp.enterEventDispatcher();
As we said earlier, an Application object is required, but it's the main function that is the actual entry point of the program. When the main function is exited the application is terminated and cleaned up by the operating system. The Application object, and more specifically the call to enterEventDispatcher, is why a class derived from Application is required.
The last thing to do for this class is to create the constructor and show the first screen. We haven't created the screen yet, but we can go ahead and create the code to use it.
The constructor is also very simple and does only one thing. You could do more in the setup and initialization of things in the application constructor of course (if your application needs it), but this simple application does not. Here we create a new instance of the TipCalcMainScreen class and then push it onto the UI stack. The TipCalcMainScreen is the class that you will create next and is the screen that you will display to the user. We will come back to pushScreen and the UI Stack later.
pushScreen(new TipCalcMainScreen());