Archive for the ‘Projects’ Category

A BlackBerry Application for the Nation.

I created a library for creating applications for the YouTubes on Sunday night and the first application I decided to use it for was a Philip Defranco app. Hope everybody likes it.

 

Download Page

 

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;
    }
}

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.