Download and install BlackBerry Java Plug-in for Eclipse
Repeat the above for BlackBerry Torch 9800 simulator
Launch Eclipse
Create new BlackBerry Project: File->New->BlackBerry Project
Set the title of the project
Add Elements on Main Screen
Place a applications icon into res->image
Open BlackBerry_App_Descriptor
Select the icon, click the Add button
Define the Application
Create a class called Menu. This will provide the user with an interface to navigate between screens.
public class Menu extends UiApplication {
...
}
This allows the user to view Screen 1(our start screen) and then ultimately begin drawing on Screen2 (drawing screen).
It allows us to push screens onto the stack in order get them to be displayed.
The code to implement the Menu class is as follows:
// Push a screen onto the UI stack for rendering.
ButtonField start = new ButtonField( "Start", ButtonField.CONSUME_CLICK | ButtonField.FIELD_HCENTER);
ButtonField about = new ButtonField( "About", ButtonField.CONSUME_CLICK | ButtonField.FIELD_HCENTER);
HorizontalFieldManager horizontalFieldManager = getFieldManager();
VerticalFieldManager innerManager = new VerticalFieldManager(HorizontalFieldManager.USE_ALL_WIDTH | HorizontalFieldManager.USE_ALL_HEIGHT);
screen.add(horizontalFieldManager);
horizontalFieldManager.add( innerManager );
innerManager.add(start);
innerManager.add(about);
innerManager.setPadding((Display.getHeight()/2)-30, 0, 0, 0);
start.setChangeListener( new FieldChangeListener() {
public void fieldChanged( Field arg0, int arg1 ) {
pushScreen(new Screen2());
}
} );
pushScreen( screen);
Next we will be implementing Screen1 which will provide the user with a nice background image, as well as two buttons (one to view the about information, and one to begin drawing).
The code is as follows:
public class Screen1 extends MainScreen {
public Screen1() {
setTitle( "Drawsy" );
}
public void close(){
super.close();
}
}
The 3rd class is Screen2, which does the bulk of the work in our application.
Upon instantiation, numerous managers are created for various different tasks.
GridFieldManagers are used to align data neatly and quickly (used for the menu at the bottom of the screen).
AbsoluteFieldManagers enable us to draw bitmaps at a specified x and y coordinate on the screen, something other FieldManagers are unable to perform.
All menu interaction is done through screen positions which we figure out using some math depending on the devices screen width and height (all of which are available to developers).
We create the color screen by creating another GridFieldManager and setting each square to a different hex value to acheive the look and amount of colors we wanted. Example code below:
private final int [] colours = {
0x000000,0x000033,0x000066,0x000099,0x0000CC,0x0000FF,
0x003300,0x003333,0x003366,0x003399,0x0033CC,0x0033FF,
0x00FF00,0x00FF33,0x00FF66,0x00FF99,0x00FFCC,0x00FFFF,
0x660000,0x660033,0x660066,0x660099,0x6600CC,0x6600FF,
0x666600,0x666633,0x666666,0x666699,0x6666CC,0x6666FF,
0xFF0000,0xFF0033,0xFF0066,0xFF0099,0xFF00CC,0xFF00FF,
0xFF9900,0xFF9933,0xFF9966,0xFF9999,0xFF99CC,0xFF99FF,
0xFFFF00,0xFFFF33,0xFFFF66,0xFFFF99,0xFFFFCC,0xFFFFFF
};
public void setColorGrid(GridFieldManager cg){
int i, h,w, rows = 10, cols = 6, rh = 3, rw = 2;
h = displayHeight;
w = displayWidth;
cg.setEditable(true);
for (i = 0; i < colours.length; i++){
cg.add(new ButtonField( "", ButtonField.CONSUME_CLICK | ButtonField.FIELD_HCENTER));
cg.getFieldAtIndex(i).setPadding(h/(rows*rh), w/(cols*rw), h/(rows*rh), w/(cols*rw));
cg.getFieldAtIndex(i).setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
cg.getFieldAtIndex(i).setBackground(BackgroundFactory.createSolidBackground(colours[i]));
cg.setColumnPadding(0);
cg.setRowPadding(0);
}
}
The screen is saved between color choices by saving the manager in a temp variable, deleting it from the screen, then adding the gridFieldManager holding the color choices, waiting for user interaction, then deleting and re-adding the drawing screen.
Trackball event:
int top = 0, bottom = (displayHeight-(grid.getHeight()-(bitmap.getHeight()+12)))/9,
left = 0, right = displayWidth/6;
if(dx > 0)
tbX += dx*10;
else
tbX += dx*10;
if(dy > 0)
tbY += dy*10;
else
tbY += dy*10;
if(added){
for(int i = 0;i < colours.length;i++){
if(tbX > left && tbX < right && tbY > top && tbY < bottom){
grid.getFieldAtIndex(0).setBackground(BackgroundFactory.createSolidBackground(colours[i]));
currentColour = colours[i];
}
if((i+1)%6 == 0){
top = bottom;
bottom +=(displayHeight-(grid.getHeight()-(bitmap.getHeight()+12)))/9;
left = 0;
right = displayWidth/6;
}
else{
left = right;
right += displayWidth/6;
}
}
}
Bitmap bm = Bitmap.getBitmapResource("square.png");
BitmapField bmf = new BitmapField(bm){
protected void paint(Graphics g){
}
};
doMenuEvent(menuEvent(tbX, tbY));
bmf.setPadding(0, 0, height, width);
if(draw && !added){
drawsy(bmf, tbX, tbY);
}
else{
if(bmf2 != null){
screen.delete(bmf2);
drawsy(bmf, tbX, tbY);
bmf2 = bmf;
}
else{
drawsy(bmf, tbX, tbY);
bmf2 = bmf;
}
}
return true;
Touch event:
final int touchX = message.getX(1);
final int touchY = message.getY(1);
int top = 0, bottom = (displayHeight-(grid.getHeight()-(bitmap.getHeight()+12)))/9,
left = 0, right = displayWidth/6;
if(added){
for(int i = 0;i < colours.length;i++){
if(touchX > left && touchX < right && touchY > top && touchY < bottom){
grid.getFieldAtIndex(0).setBackground(BackgroundFactory.createSolidBackground(colours[i]));
currentColour = colours[i];
}
if((i+1)%6 == 0){
top = bottom;
bottom +=(displayHeight-(grid.getHeight()-(bitmap.getHeight()+12)))/9;
left = 0;
right = displayWidth/6;
}
else{
left = right;
right += displayWidth/6;
}
}
}
Bitmap bm = Bitmap.getBitmapResource("square.png");
BitmapField bmf = new BitmapField(bm){
protected void paint(Graphics g){
}
};
doMenuEvent(menuEvent(touchX, touchY));
if(!added){
bmf.setPadding(0, 0, height, width);
drawsy(bmf, touchX, touchY);
}
return true;
Clearing the screen is simply deleting all the fields in the manager
Resizing the brush is done by simply dividing our original bitmap size(or multiplying).
Setting the brush to a marker (translucent colors) or paintbrush was done with a simple global flag checking if it was true or false.
Usage
doMenuEvent(menuEvent(touchX, touchY));
MenuEvent
private int menuEvent(int x, int y){
int rc = -1;
for(int i = 0;i < 4; i++){
if( x > grid.getFieldAtIndex(i).getContentLeft() &&
x < (grid.getFieldAtIndex(i).getContentLeft() + bitmap.getWidth()) &&
y > (displayHeight -(grid.getFieldAtIndex(0).getContentTop())) &&
y < (displayHeight)){
rc = i;
break;
}
}
return rc;
}
Drawing was done in an odd way. The simplest solution we came up with, was to use a square bitmap and recolor its background if any different colors were chosen, and resize accordingly. This worked well for the most part, tho we do run into some performance issues if there are too many bitmaps on the screen at once
The program works with both touch events and scroll wheel events, tho scroll wheel events are still buggy.
Using the program
Our program, dubbed Drawsy, allows the user to create works of art on most blackberrys (Above version 5.0.0)
First select start to begin drawing
You are then provided with a blank canvas and some options to work with
You can change the color of your brush
You can change the size of a brush
You can clear the screen
You can switch between a marker and a paintbrush to achieve translucent colors.
This being said, our program provides the user with an open ended experience which is only limited by their imagination