Applying Project Configurations, Abilities, and Preprocessor Blocks
To get a better understanding of project configurations, abilities, and preprocessor blocks, you can use these NetBeans Mobility Pack features to address the device fragmentation issues associated with the StockQuote MIDlet suite.
|Figure 7. Multiple Build and Dist to Support Project Configurations: The NetBeans IDE with Mobility Pack uses multiple build and distribution folders in a single MIDP project to manage the multiple sets of class files and deployment code it creates based on the project configurations. You will see one build and dist folder for each project configuration associated with your project.|
New vs. Old J2ME
First, let's take on the issue that two of the targeted devices support newer versions of MIDP and CLDC while another of the target devices, namely an older J2ME phone, does not. This is a common problem in J2ME development and its greatest impact in this application is what primitive types each supports. With CLDC 1.1, floating point numbers were addedan important feature when trying to obtain, store, and retrieve dollar and cent amounts that are often expressed in floats. For the older phone, two separate integer values must be managed to track dollars and cents. This problem could easily necessitate having to write two separate applications.
Using an ability labeled newJ2ME and preprocessor blocks, program lines dealing with both integers and floating point numbers can be added to the same source code. The IDE editor and compiler will use the preprocessor blocks marked by the ability labels to essentially comment and uncomment various lines of the application based on which project configuration (and thus, which associated device) is selected. For example, the following code in the HistoricQuotesMidlet retrieves prices out of the record store. Depending on which project configuration with its associated ability (in this case whether a newJ2ME device) is selected, the corresponding preprocessor blocks allow for prices to be retrieved as an array of floats in one case (newJ2ME ability) or as an array of integers in the other case (!newJ2ME abilitymeaning not having the newJ2ME ability). In the case below, a project configuration with newJ2ME ability is selected as the !newJ2ME ability code has been commented out by the IDE.
//-- int prices = retrievePrices(currentSymbol);
float prices = retrievePrices(currentSymbol);
These preprocessor blocks are sprinkled throughout the StockQuotes example code. Yes, it does mean that you have to write code for each instance of device fragmentation, but at least it's all in a single code base and the IDE helps you assign and modify associations of code with particular devices. In fact, the way the IDE does this is that it actually manages multiple mini-projects for your single code base. Open the files tab of the NetBeans IDE as shown in Figure 7
and you will notice that there is a build and distribution folder for each of the project configurations. These are all managed by NetBeans, but you can see how your project configurations lead to this file structure.
|Figure 8. Big vs. Small Screen Device Fragmentation: Using an ability and preprocessor blocks, screen information appropriate to the project configuration and associated devices is turned on or off to allow the application to generically build these displays without worrying about the screen sizes.|
Abilities and preprocessor blocks can also be used to deal with the various screen display sizes. The PDA device has a much larger display screen. Therefore, in this example, the chart displaying stock and mutual fund prices should be scaled to take advantage of larger display. Furthermore, more historical prices can be displayed when a larger screen is available (see Figure 8).
In the ChartCanvas code that graphically displays the stock quote prices, a second ability is used to designate certain screen parameters for "big screens" versus non-big screens. The application then uses these parameters to effectively scale the drawing to the size of the screen associated with the project configuration's target devices.
//-- static final int MAX_PRICES_DISPLAYED = 10;
//-- static final int START_X_POSITION = 60;
//-- static final int MAX_BAR_SIZE = 500;
//-- static final int ROW_HEIGHT = 20;
static final int MAX_PRICES_DISPLAYED = 5;
static final int START_X_POSITION = 40;
static final int MAX_BAR_SIZE = 100;
static final int ROW_HEIGHT = 15;