Archive for July, 2011

Creating a BlackBerry License Screen Agreement Popup

All the native BlackBerry applications have a license agreement that pops up looking like this. With the class I am including below it should be very easy to create your own. Resource files should be used. It is simple to create them by right clicking on your “res” folder and selecting “BlackBerry Resource File” from the menu. This will also create the class in “.locale_interfaces” used to access those resources. After adding the required keys you should change the license agreement value to “Convert to Multiple Values” and then add the agreement within the popup. The file that the below usage example uses is:

LicensePopup.java

I will include the usage first as it is a little more complex. The popup must be called prior to entering the main thread, or event dispatcher. The way this is done is as follows:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected static ResourceBundle _resources = ResourceBundle.getBundle(BBiCalResource.BUNDLE_ID, BBiCalResource.BUNDLE_NAME);
/**
* Is synonymous with the main function. I separated it and the main function calls run().
*/
public void run(){
	invokeLater(new Runnable() {
		public void run() {
			LicensePopup popupDialog = new LicensePopup(_resources.getStringArray(BBiCalResource.ABOUT_LICENSE),
					_resources.getString(BBiCalResource.MENUITEM_ACCEPT), _resources.getString(BBiCalResource.MENUITEM_DECLINE), 6);
			pushGlobalScreen(popupDialog, 1, UiEngine.GLOBAL_MODAL);
 
			if(!popupDialog.isLicenseAccepted()) {
				System.exit(0);
			}
			else {
				//TODO persistant store that the license was accepted.
				requestForeground();
				pushScreen( new HomeScreen() );
			}
		}
        });
 
	enterEventDispatcher();
}

Below is the license agreement class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package ca.dftr.lib.ui.components;
 
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
 
/**
 * Pop up screen that looks like the default BlackBerry License screen
 * @author deforbes
 */
public class LicensePopup extends PopupScreen {
    private ButtonField _btnOkay;
    private ButtonField _btnCancel;
    private RichTextField _licenseTextField;
    private boolean _accepted;
 
    /**
     * Create the License Popup
     * @param licenseText The actual License as a string array (each line is a part of the array). Best to use a resource array
     * @param acceptBtnText Text on the accept button
     * @param declineBtnText Text on the decline button
     * @param fontSize Size of the font in the popup. (RIM uses 6)
     */
    public LicensePopup(String[] licenseText, String acceptBtnText, String declineBtnText, int fontSize) {
        super(new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR));
 
        if (fontSize <= 0){
        	fontSize = 6;
        }
        Font font = Font.getDefault().derive(Font.PLAIN, fontSize, Ui.UNITS_pt);
 
        _licenseTextField = new RichTextField(RichTextField.READONLY);
        for(int i=0; i<licenseText.length; i++) {
        	_licenseTextField.insert(licenseText[i]);
            if(i < licenseText.length - 1) {
            	_licenseTextField.insert("\n");
            }
        }
        _licenseTextField.setFont(font);
        _licenseTextField.setEditable(false);
 
        _btnOkay = new ButtonField(acceptBtnText, ButtonField.CONSUME_CLICK | Field.FIELD_HCENTER);
        _btnOkay.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
            	setAccepted(true);
            }});
        _btnCancel = new ButtonField(declineBtnText, ButtonField.CONSUME_CLICK | Field.FIELD_HCENTER);
        _btnCancel.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
            	setAccepted(false);
            }});
 
        add(_licenseTextField);
        add(new SeparatorField());
        add(_btnOkay);
        add(_btnCancel);
    }
 
    /**
     * Set whether the user clicked accept or decline
     * @param accepted Whether user accepted the license
     */
    private void setAccepted(boolean accepted) {
        _accepted = accepted;
        this.close();
    }
 
    /**
     * @return Whether or not the user accepted the license agreement
     */
    public boolean isLicenseAccepted() {
        return _accepted;
    }
}

Getting Started: BlackBerry JRE installation for different OS support

This information is outdated. Take it as you will.
There are a few problems with figuring out how to do things within the world of BlackBerry Development. These getting started posts will try to alleviate some of the problems caused by such things as:
  1. The getting started links after creating a BlackBerry Developer Zone login return 404 errors.
  2. Downloading and installing the correct JRE components often fails (with older JRE’s) and requires a login to an account for swdownloads.blackberry.com.
  3. Very difficult to figure out how to automatically compile for multiple platforms
After a few hours of searching I happened upon this link. Prior to this there appears to have been nowhere to find this information except through word of mouth. Since many BlackBerry.com websites often get lost in the void, a summary:
  1. Download and install the latest BlackBerry plug-in for Eclipse. Note that this should install a separate Eclipse: do not try to combine the installation that you’ve been working on for your Android application. Use two separate Eclipse instances for BB or Droid.
  2. Open it up after choosing a workspace and click the “Help” button on the top toolbar. Go to “Install new software” and add a new site named Blackberry Java Plug-in Update Site with location of http://www.blackberry.com/go/eclipseUpdate/3.6/java .
  3. Expand the “BlackBerry Java Plug-in Category and choose the SDK’s. Remember, the lowest version you can download (4.5.0.xx) is the lowest SDK you can use for your general library. So check the API reference to make sure everything that you need is there. This is due to the way that development for multiple OS’ work as is explained here  by Derek Konigsberg who created LogicMail.
  4. Optionally change the color scheme to what you are more comfortable with. If you do not like the default you can change the Eclipse background and colors by going to the same “Install new software” but using http://eclipse-color-theme.github.com/update/ as the site.
What that page does not tell you is that you will have a heck of a time downloading any SDK below OS7. After a few tries I found I had to do them individually, restarting eclipse after each install, or it would fail when asking for my credentials. I also found I had to create a new, fake, developer zone login. This login had to be confirmed (by checking email and clicking link) and had to have my information second checked and confirmed, which happens after your first login. After that, I was able to download the SDKs one by one.
My recommendation is to support only OS5 and up. This is due to the fact that majority of the devices that could be upgraded were. This is also due to the fact that it is a lot easier to do networking tasks (*todo, link to networking post) as there was an overhaul as of OS5.  It is also likely that the BlackBerry application player for QNX will better support 5 and up. However, if your device is a pearl flip for example, you are left with no choice but to support 4.6.1+.
The best information for a just starting BlackBerry java developer would be also from Derek at the site linked above. So that it is not lost, it is also here

Easily Create BlackBerry “Social Feeds” Like Pane UI

As I have been working on plenty of projects of late I have decided to start making bits and pieces of the source available. I will not make the whole thing available however I do hope to make the learning curve less for others than it was for me. Below is an OS 6.0+ class which is similar to the BlackBerry native application Social Feeds. I have condensed the default way of invoking a PaneView into an easily customized basic class. As the default way uses the MVC pattern it can be a little convoluted if you are simply looking for a basic “pretty” view.

Included in this post:

ColoredLabelField.java

BasicPaneManagerView.java

Below is the BasicPaneView class. This is by no means a perfect implementation. This code is simply what I threw together last night and as I finish this application it may improve in quality. Any of those updates will be updated in this post.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package ca.dftr.calendar.ui.components;
 
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.pane.HorizontalScrollableController;
import net.rim.device.api.ui.component.pane.Pane;
import net.rim.device.api.ui.component.pane.PaneManagerController;
import net.rim.device.api.ui.component.pane.PaneManagerModel;
import net.rim.device.api.ui.component.pane.PaneManagerView;
import net.rim.device.api.ui.component.pane.PaneView;
import net.rim.device.api.ui.component.pane.TitleView;
 
/**
 * A simplified way of creating a PaneView style of UI
 * @author deforbes
 */
public class BasicPaneManagerView extends PaneManagerView{
	private TitleView _header;
	private PaneManagerModel _model;
	private int _currentlySelectedIndex = 0;
	private boolean _curSelectedBeenSet = false;
 
	/**
	 * Pane View Constructor
	 * @param enableLooping Do the panes loop. (i.e. In UI with 3 panes, can you swipe left from 1-3)
	 * @param style Field Styles. (Good idea to pass in Field.FOCUSABLE for example)
	 * @param title The header style. The container that will house the pane titles.
	 */
	public BasicPaneManagerView(boolean enableLooping, long style, TitleView title){
		super(style, title, new PaneView(0));
		_header = title;;
 
		_model = new PaneManagerModel();
		_model.enableLooping(enableLooping);
		title.setModel(_model);
		PaneManagerController controller = null;
		controller = new HorizontalScrollableController();
		controller.setModel(_model);
		controller.setView(this);
		_model.setController(controller);
		this.setController(controller);
 
		PaneView paneView = new PaneView(Field.FOCUSABLE);
		paneView.setModel(_model);
		super.setPane(paneView);
 
		this.setModel(_model);
		_model.setView(this);
	}
 
	/**
	 * Get TitleView header associated with this Pane Manager
	 * @return TitleView header associated with this Pane Manager
	 */
	public TitleView getHeader(){
		return _header;
	}
 
	/**
	 * Add a pane to the pane collection
	 * @param paneToAdd Insert pane into manager
	 */
	public void addPane(Pane paneToAdd){
		_model.addPane(paneToAdd);
		if (!_curSelectedBeenSet){
			this.setCurrentlySelectedIndex(_currentlySelectedIndex);
		}
	}
 
	/**
	 * Set the start pane. By default it will be set to the first pane added to the collection
	 * @param currentlySelected Which pane will appear to user first on paint.
	 */
	public void setCurrentlySelectedIndex(int currentlySelected){
		_model.setCurrentlySelectedIndex(currentlySelected);
	}
 
	/**
	 * Create a default pane
	 * @param title Title to appear in the TitleView header
	 * @param field The content handler for layout within the pane body. (i.e VerticalFieldManager or HorizontalFieldManager)
	 * @param titleColor Color of the text to appear in the header.
	 * @return A new unattached Pane
	 */
	public static Pane CreatePane(String title, Manager field, int titleColor){
		ColoredLabelField paneTitle = new ColoredLabelField(title, Field.FOCUSABLE | Field.FIELD_HCENTER, titleColor);
		Pane pane = new Pane(paneTitle, field);
		return pane;
	}
}

And now for the usage. Obviously this is done within the class you are using to build a UI and not just pasted into a file:

1
2
3
4
5
6
7
TitleView header1 = new HorizontalScrollableTitleView(Field.FOCUSABLE);
BasicPaneManagerView paneView = new BasicPaneManagerView(false, Field.FOCUSABLE | BasicPaneManagerView.DIRECTION_NONE , header1);
paneView.addPane(createFirstPane());
paneView.addPane(createSecondPane());
paneView.addPane(createThirdPane());
 
add(paneView);

And finally, to create a pane and add it to the PaneViewManager we just created:

1
2
3
4
5
6
7
8
9
private Pane createFirstPane(){
        //Manager for content
	VerticalFieldManager vfm = new VerticalFieldManager(Field.USE_ALL_HEIGHT);
	//Add the content
        ButtonField buttonField_1 = new ButtonField( "Content first pane", ButtonField.CONSUME_CLICK | ButtonField.FIELD_RIGHT );
        vfm.add( buttonField_1 );
        //Create the pane
	return BasicPaneManagerView.CreatePane("Calendars", vfm, Color.WHITE);
}

Optionally you can style your header and panes to look pretty. After the line:

TitleView header1 = new HorizontalScrollableTitleView(Field.FOCUSABLE);

You can optionally put:

1
2
header1.setBackground(BackgroundFactory.createSolidBackground(Color.BLACK));
header1.setBorder(BorderFactory.createBevelBorder(new XYEdges(10, 10, 10, 10), new XYEdges(0,0,0,0), new XYEdges(0,0,0,0)));

To style the title to look like this.

Feel free to comment on this. I always love to improve my code.

-Devin

Return top

INFORMATION

I do not adhere to a schedule. I post when I have something to say. I'm a programmer who in my spare time enjoys contemplating the meaning of life, the universe and, everything. So there will be code as well as random little stories, essays and, musing about whatever interests me at the moment.