Cosc 4730 Blackberry GUI Blackberry • Blackberry's can use MIDlet, just like standard JavaME phone – But the preferred method is different. • With 30+ examples, only one is a MIDlet with an dialog box. • base class is the application class, but is not a MIDlet. application is closer in nature to a standard Java program, then a JavaMe app. There is a Main class! • uses MainScreen for each screen that the applications is using. – Note, you can have many screens, which "stack", only the top screen is "active". • No separate menus. All menu items going to the blackberry menu. BlackBerry example •Sample app using MIDlet code •It works, but by BlackBerry standards, it’s very ugly. •Blackberry has provided extensions for MIDlets. BlackBerry extensions for MIDlets. • Import net.rim.device.api.lcdui • And import net.rim.device.api.lcdui.control • extends • • • • • • (with touchsupport and addition controls) BlackBerryCanvas BlackBerryCustonItem BlackBerryForm BlackBerryList BlackBerryTextBox MIDlet vs UiApplication • Since Blackberry has both implementations, the objects (ie labels, radiobuttons, etc) drawn on the screen can be confusing in the documentation. Plus you can’t use both! – All UiApplication are extended from the field class and end with field. – This lecture will cover the fields and ignore MIDlets for the rest of the course. UiApplication • Using their net.rim.device.api.ui and net.rim.device.api.ui.componet • All the items come back and there are many more, including a buttonfield. • Development guide. Note you may need to know the version of the OS a device is using. Older versions mostly work on newer versions, but the reverse is not true. (same is true for android) • • • • • • http://www.blackberry.com/developers/docs/4.5.0api/index.html http://www.blackberry.com/developers/docs/4.6.0api/index.html http://www.blackberry.com/developers/docs/4.7.0api/index.html http://www.blackberry.com/developers/docs/5.0.0api/index.html http://www.blackberry.com/developers/docs/6.0.0api/index.html http://www.blackberry.com/developers/docs/7.1.0api/index.html Basics • There is a "main" class, which extends the UiApplication class. – It's job is to initiate the "screen" class and push it onto the UI stack. • UI Stack is the "stack" of screens. The top screen is the active screen and the other screens are inactive (but may still be running) • The Screen class is the application, interacting the user and writing to the "screen", which extends MainScreen – You may have multiple screens, which you can push onto the stack, and "pop" to the top. – Blackberry convention, is call the "screen" class, the name of the appname with screen • HelloWorld extends UiApplication • HelloWorldScreen extends MainScreen – Fields use the add(field) method to put objects (like textfields) on the screen. Blackberry Application import net.rim.device.api.ui.* Import net.rim.device.api.ui.componet.*; class HelloWorldDemo extends UiApplication { /* Entry point for application. */ public static void main(String[] args) { // Create a new instance of the application. HelloWorldDemo theApp = new HelloWorldDemo(); // To make the application enter the event thread and start processing messages, // we invoke the enterEventDispatcher() method. theApp.enterEventDispatcher(); } /** * The default constructor. Creates all of the RIM UI components and pushes the * application's root screen onto the UI stack. */ HelloWorldDemo() { // Push the main screen instance onto the UI stack for rendering. //Where HelloWorldScreen class extends MainScreen pushScreen(new HelloWorldScreen()); } } BlackBerry MainScreen class HelloWorldScreen extends MainScreen { HelloWorldScreen() { LabelField title = new LabelField("Hello World Demo" , LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH); setTitle(title); // Add a read only text field (RichTextField) to the screen. The RichTextField // is focusable by default. In this case we provide a style to make the field // non-focusable. add(new RichTextField("Hello World!" ,Field.NON_FOCUSABLE)); } /** * Display a dialog box to the user with "Goodbye!" when the application * is closed. * * @see net.rim.device.api.ui.Screen#close() */ public void close() //overriding method, when screen closes, this is called. { //Note, if this is the last screen on the stack, then application closes. Otherwise, next screen on stack becomes visible. // Display a farewell message before closing application. Dialog.alert("Goodbye!"); System.exit(0); super.close(); } } Fields • • • • BitmapField ButtonField LabelField TextField – EditField – RichTextField – ActiveRichTextField • ChoiceField • DateField • GauageField • SeparatorField • RadioButtonField – RadioButtonGroup • • • • • CheckBoxField ListField MapField NullField TreeField Fields New in API 5.0.0 • • • • SpinBoxField Autocomplete text field Picker dialog boxes Fields that appear temporarily on a screen • Using the Eyelid Field Manager (layout manager) • Image creation • Screen transitions • Covered in the Screen part of this lecture. • Complete list of new APIs: • http://docs.blackberry.com/en/developers/deliverables/11945/ New_in_this_release_521868_11.jsp Fields New in API 6.0.0 • • • • New Activity indicators Image scrolling, using PictureScrollField Layout Managers, absolute and Pane Managers More menu options and toolbars (similar to the android menus actually) • Tables (TableView) and Lists ( ListField) – Lists can be simple or Rich (with pictures) • More offline content for the browser, loading you own stuff, when the network is unavailable. • For the full list – http://docs.blackberry.com/en/developers/deliverables/17966/ Screen_APIs_1245069_11.jsp Fields New in API 7.0.0 • Send Menu API – A BlackBerry® user can use a Send menu item to send content to another application • Layering UI elements – For example, you can use a ComponentCanvas to display a series of buttons on top of a video field or camera field. • • • • Barcode scanning, image data scanning OnenVG API methods OpenGL ES 2.0 For the full list – http://docs.blackberry.com/en/developers/deliverables/2 9281/User_interface_1653672_11.jsp Fields (2) • Fields have "styles" that change the way a field functions, looks, or responds to the user • Example, Note the style is a bitwise field. – Bitmap(bmp, FIELD.HCENTER | FIELD.FIELD_VCENTER| FIELD.FOCUSABLE) – LabelField ("BlackBerry App", DrawStyle.ELLIPSIS | LabelField.USE_ALL_WIDTH); • All fields can be extended as well, to provide more "interesting“/custom fields. Fields styles • These are the common set of styles can be used. • Fields inherited from class net.rim.device.api.ui.Field – ACTION_INVOKE, AXIS_HORIZONTAL, AXIS_SEQUENTIAL, AXIS_VERTICAL, EDITABLE, EDITABLE_MASK, FIELD_BOTTOM, FIELD_HALIGN_MASK, FIELD_HCENTER, FIELD_LEADING, FIELD_LEFT, FIELD_RIGHT, FIELD_TOP, FIELD_TRAILING, FIELD_VALIGN_MASK, FIELD_VCENTER, FOCUSABLE, FOCUSABLE_MASK, HIGHLIGHT_FOCUS, HIGHLIGHT_SELECT, NON_FOCUSABLE, NON_SPELLCHECKABLE, READONLY, SPELLCHECKABLE, SPELLCHECKABLE_MASK, STATUS_MOVE_FOCUS_HORIZONTALLY, STATUS_MOVE_FOCUS_VERTICALLY, USE_ALL_HEIGHT, USE_ALL_WIDTH, VISUAL_STATE_ACTIVE, VISUAL_STATE_DISABLED, VISUAL_STATE_DISABLED_FOCUS, VISUAL_STATE_FOCUS, VISUAL_STATE_NORMAL • Fields inherited from interface net.rim.device.api.ui.DrawStyle – BASELINE, BOTTOM, ELLIPSIS, HALIGN_MASK, HCENTER, HDEFAULT, HFULL, LEADING, LEFT, RIGHT, TOP, TRAILING, TRUNCATE_BEGINNING, VALIGN_MASK, VCENTER, VDEFAULT, VFULL, ELLIPSIS BitmapField and LabelField • Bitmapfield. Display a bitmap – BitmapField(Bitmap) or BitmapField(Bitmap, long style) – The default style is LEFT (and TOP) – you can combine one of VCENTER, TOP, and BOTTOM with one of HCENTER, LEFT, and RIGHT. • And If you want this field to be focusable, then you should also include Field.FOCUSABLE • LabelField – Displays a label. • Optionally can shorten text (with an ellipsis) that is too long. – Valid styles for a label field are: Field.FOCUSABLE, Field.USE_ALL_WIDTH, DrawStyle.ELLIPSIS, any of Field's horizontal or vertical alignment styles. ButtonField • Contains a button control. • When the user presses a ButtonField the FieldChangeListener that was set by invoking setChangeListener() is notified by its fieldChanged() method being invoked. – The code below demonstrates how to use this technique to respond to button presses. – FieldChangeListener listener = new FieldChangeListener() { • public void fieldChanged(Field field, int context) { – ButtonField buttonField = (ButtonField) field; – System.out.println("Button pressed: " + buttonField.getLabel()); • } – }; – ButtonField buttonField = new ButtonField("Test Button"); – buttonField.setChangeListener(listener); • Styles, Default: DrawStyle.VCENTER and DrawStyle.HCENTER. • ButtonField.CONSUME_CLICK This click won't passed beyond the button. – Otherwise, the menu will also likely be called. Text Fields • TextField – A simple editable text field. set the field as Field.EDITABLE, for input. – Style specific to TextField. • CONSUME_INPUT – • DEFAULT_MAXCHARS – • Enables jump-to-end of field behavior. NO_COMPLEX_INPUT – Suggests complex input • NO_EDIT_MODE_INPUT • NO_LEARNING – – • • If set, edit mode is disabled on this field static long Suggests auto learning feature disable for current text component. static long NO_NEWLINE – Ignore newlines from user input or pasting. static long NO_SWITCHING_INPUT – • Default maximum number of characters allowed in this field. JUMP_FOCUS_AT_END – • Determines whether or not this field should consume all input characters. Do not allow IM switching in this field Edit fields built with this style do not allow IM switching within this field. Subclasses: BasicEditField, RichTextField – Subclasses of BasicEditField: EditField, PasswordEditField – Subclass of RichTextField: ActiveRichTextField Text Fields (2) • EditField – Displays a label in front of the text contents. If the contents occupy more than one line the text will flow around the label. The caret position is behaves as if it were between characters in the text contents, however it appears as a full inverted box on the character immediately following the caret. – If this field is Field.EDITABLE, typing inserts text into the contents at the caret position – Styles from BasicEditField • FILTER_DEFAULT, FILTER_EMAIL, FILTER_FILENAME, FILTER_HEXADECIMAL, FILTER_INTEGER, FILTER_LOWERCASE, FILTER_NUMERIC, FILTER_PHONE, FILTER_PIN_ADDRESS, FILTER_REAL_NUMERIC, FILTER_UPPERCASE, FILTER_URL – Styles from TextField and Field are also usable. – Example: • EditField("Number of people: ", "10", 3, EditField.FILTER_INTEGER); • Number of people is the label, 10 is the default value, and it will only accept integers values up to 3 digits (ie 999 is the max value) – Subclasses: AutoTextField and EmailAddressEditField • AutoTextField has a subclass of ActiveTextEditField Text Fields (3) • RichTextField – Read-only field that supports richly formatted text – Can be set to editable, via setEditable(Boolean) method. • ActiveRichTextField which is a subclass of RichTextField – Uses a supplied set of string patterns to scan through a simple text string and pick out "active" regions. – These active regions are highlighted with underlining and will supply additional menu verbs if the user clicks on them. – You would use this field type when you want to have your program make content within the field active (so the user can click them and perform actions) within the application. A BlackBerry automatically creates menu items for the standard web URLs, email addresses, phone numbers, and PIN. Developers can create custom string patterns (for order or part numbers, for example) and make them active within an application. FieldChange listener • The Fieldchange listener is the primary listener • Before you saw it for the button. – Using the field parameter you can figure out which field has changed – FieldChangeListener listener = new FieldChangeListener() { • public void fieldChanged(Field field, int context) { – If (field == button1) { – } else if (field == textfield) { – } • } – }; – fieldX.setChangeListener(listener); FieldChange listener (2) • Using the implements class FormExampleBBscreen extends MainScreen implements FieldChangeListener{ … list.setChangeListener(this); button1.setChangeListener(this); Both Call the same listener, declared later … public void fieldChanged(Field field, int context) { … } ChoiceField • Using windows terms, it’s a drop-down list • Subclasses: NumericChoiceField and ObjectChoiceField • Styles: EDITABLE by default, and uses Field.USE_ALL_WIDTH style, with the label on the leading edge of the line and the choice on the trailing edge, separated by any available space. Setting the Field.FIELD_LEFT, Field.FIELD_RIGHT, or Field.FIELD_HCENTER style will cause the label and choice to be joined together with no space in between • Example: Using ObjectChoiceField ObjectChoiceField MyCF; String choices[] = {“Laramie”, “Cheyenne”, “Casper”}; MyCF = new ObjectChoiceField(“Select a City”, choices); add(MyCF); – Add a fieldchangedlistener and MyCF.getChoice().toString() to get the selected value. DateField • Stores date and time values. – Can be set to editable and the text values behaves like a ChoiceField (eg. months, weekdays) • Styles – specific to DateField • DateField.DATE mode, this field only displays the date component of the currently set value. • DateField.DATE_TIME mode, this field displays the date and time of the currently set value. • DateField.TIME mode, this field only displays the time component of the currently set value. – Uses Field and DrawStyle as well. GuageField • Displays a horizontal bar that you can use for numeric selection or as a progress indicator. – Use EDITABLE to allow the user to change it. – Styles, use FIELD styles, plus • GuageField.LABEL_AS_PROGRESS – Display the label as the progress value. static int • GuageField.NO_TEXT – Do not display progress value in text form. • GuagefIield.PERCENT – Displays progress as a percentage. SeparatorField • Displays a separator, currently always a horizontal line. • Styles: While you can use Field styles, not sure why you would – Separator has 3 styles as well • LINE_HORIZONTAL – Field should draw a horizontal line. • LINE_MASK – Mask for which way line should be drawn. • LINE_VERTICAL – Field should draw a vertical line. RadioButtonField • Field to provide a radio-button control. – Displays a circular button to the left of the text label. With the default font, this button is either empty or contain a solid circle depending on the state of the field. – When this field has the focus, the button appears inverted. • You group together Radio buttons fields using the RadioButtonGroup. – At most one button within the group can be selected at any one time. – The group can be programmatically created or changed so that no button is selected, but a user cannot deselect all fields in the group • Styles use the standard Field Style – A RadioButtonField is EDITABLE by default CheckBoxField • Displays a checkbox before the text label. In the default font, this box appears either empty, or containing a check mark, depending upon the state of the field. • Example: CheckBoxField myCB = new CheckBoxField(“pick me”, False, Field.USE_ALL_WIDTH); • False is not checked. The style field can be left off. add(myCB); ListField • Implements a listbox, which contains rows of selectable list items. – A ListField uses a class that implements the ListFieldCallback interface to perform drawing tasks. – A ListField must register a class that implements the ListFieldCallback interface using the setCallback method before the class can be used. – After registration, when a ListField must display an item in its list, it invokes the appropriate methods of the registered callback class. • Displays a vertical list of set height items. – Optionally, you can build a list field as ListField.MULTI_SELECT. Currently, this means the user is allowed to select a range of items. MapField • Map field renders a map using the current mapping service. • There are three basic ways to navigate the MapField: – move(int int) - move the map by a certain number of pixels. – moveTo(Coordinates) - move the map to the location specified by a Coordinate object. – moveTo(int int) - move the map to the specified latitude and longitude. • And there are two basic ways to change the currently displayed view: – setRotation(int) - rotate the current view. – setZoom(int) - change the zoom level of the current view. NullField • A field of no size. • This class provides a field of zero size, which you might find useful for implementing nonstandard focus changing. – Add a focus change listener to the field and move focus appropriately when it is triggered. TreeField • A simple field to show a tree structure. • Shows a field structure useful for displaying objects in a hierarchy. – like a set of nested folders. SpinBoxField • BlackBerry API 5.0.0+ • A user interface component for selecting a single item from a list where the user can spin through the various choices. – This component is useful when the candidates for selection are sequential e.g. months, numbers, or a list in alphabetical order. • This particular class is abstract. Use the TextSpingBoxField or create your own. TextSpinBoxField String[] choices = {"New York", "Paris", "Barcelona", "Beijing", "Moscow", "Brasilia", "Melbourne"}; TextSpinBoxField spinBoxField = new TextSpinBoxField(choices); spinBoxField.setVisibleRows(3); add(new LabelField("Choose city:")); add(new SeparatorField()); HorizontalFieldManager hfm = new HorizontalFieldManager(Field.FIELD_HCENTER); hfm.add(spinBoxField); add(hfm); Pickers • net.rim.device.api.ui.picker – DateTimePicker • A user interface component for picking a date only, time only, and date and time together. – FilePicker • A user interface component for picking a file. AutoCompleteField • lets you create a text field that presents users with a changing list of words that are associated with the characters they have typed in the field. • Users can select one of the presented matches or continue typing to further restrict the choices presented in the list. • When you construct an AutoCompleteField you must associate a BasicFilteredList with it. • The BasicFilteredList includes the data objects that are compared against to produce the list of matches presented to the user. • You can configure both which fields in the data objects are compared against and which fields are displayed when a match occurs Layouts • The Screen class has "layout managers", but are called Field Managers • There are several screen classes, covered later. • Still not as good as Swing's layout managers, but up to the task • You can add fieldManagers to fieldManagers to make a more "custom" display. – – – – – – – – – Manager used to create custom layout manager. FlowFieldManager HorizontalFieldManager VerticalFieldManger Default Screen layout for Full and MainScreen. DialogFieldManager SpingBoxFieldManager (BlackBerry API 5.0.0+) GridFieldManager (BlackBerry API 5.0.0+) EyelidFieldManager (BlackBerry API 5.0.0+) AbsoluteFieldManager (Blackberry API 6.0.0+) FieldManager Visual Example FieldManager with Code import net.rim.device.api.ui.UiApplication import net.rim.device.api.ui.component.*; import net.rim.device.api.container.*; ... add(new Label Field("Field 1")); add(new Label Field("Field 2")); add(new Label Field("Field 3")); // Now l ets switch to a Hori zontal flow manager Horizontal FieldManager hfm = new Hori zontal FieldManager() ; this. add(hfm); hfm. add(new Label Field("Label Field 4")) ; hfm. add(new Label Field("Label Field 5")) ; hfm. add(new EditField(" Edit Field", "1") ); hfm. add(new EditField(" Edit Field", "2") ); // Now a flow field manager FlowFieldManager flowManager = new FlowFieldManager(); this. add(flowManager) ; ButtonField button1 = new ButtonField("Button 1"); ButtonField button2 = new ButtonField("Button 2"); ButtonField button3 = new ButtonField("Button 3"); ButtonField button4 = new ButtonField("Button 4"); flowManager. add(button1) ; flowManager. add(button2) ; flowManager. add(button3) ; flowManager. add(button4) ; // Back to using the defaul t verti cal flow manager this. add(new SeparatorField()); this. add(new RichTextField("Let' s add some more edit fields: ")) ; add(new EditField("Edit Field", "3" ) ); add(new EditField("Edit Field", "4" ) ); GridFieldManager • You can position fields in rows and columns on a screen to create a grid by using the GridFieldManager class that is provided in the net.rim.device.api.ui.container class. – Functions very similar to a the grid layout in Swing. – For 4.7 and below, see reference at end for layout. There is a custom java class that creates a gridlayout • After you create a grid, you can add fields, delete fields, and specify the grid's properties. For example, you can use a grid layout to display multiple images on a screen. EyelidFieldManager • You can display fields on a pair of temporary managers that appear on the top and bottom of a screen by using the EyelidFieldManager class that is provided in the net.rim.device.api.ui.extension.container package. • For example, when users view an image, you can display a description of the image along the top or bottom of the screen. You can define the amount of time that the information appears on a screen. • By default, the fields appear when the user moves the trackball or, on a BlackBerry® device with a touch screen, when the user touches the screen. The fields disappear after a period of inactivity. Screens • Screen is the base class for all screens. • FullScreen is a screen that contains a single, vertical field manager. Extends Screen • MainScreen Extends FullScreen – Main screen objects contain a title section, a separator element, and a main scrollable section (actually a single vertical field manager used to maintain a list of fields). When the screen gets to handle an ENTER key event (i.e. when the event is not consumed by one the fields managed by its contained vertical field manager), the screen consumes the key to scroll its list forward. – Has a default menu • addMenuItem(MenuItem i) • removeMenuItem(MenuItem i) • adding objects to the a screen – add(Field field) – Invalidate() repaints the whole screen. Assuming you don’t override paint, just repaints the fields displaying Screens (2) • Screen translations (blackberry 5.0.0+) – http://docs.blackberry.com/en/developers/deliverables/11945/Screen _transitions_789396_11.jsp • You can apply a visual effect that appears when your application opens or closes a screen by using the TransitionContext class in the net.rim.device.api.ui package. – For example, you can reveal a new screen that your application opens by sliding it onto the display on the device. • After you create a screen transition, you must register it within your application, specify the outgoing and incoming screens, the events that cause the transition to occur, and the transition to display using methods available in the UiEngineInstance class. • Translations – Wipe, Zoom, Fade, Slide (pushing screen previous screen or over, which slides over the previous screen) Using multiple screens. • Use the UiApplication, you can push a new screen "on top" of you current screen. – And use the transitions from previous slide as well. – UiApplication.getUiApplication().pushScreen(new CustomScreen()); • Where CustomScreen is your screen. It's now on top of the UI Stack. If you need to pass info, pass parameters and use the constructor or create a variable for the screen, call a method, and then use pushScreen(varscreen). – If your screen is currently in the background for some reason or another then it can use: • UiApplication.getUiApplication().requestForeground(); Using a Splash Screen. • If you want your app to have a splash screen on startup you can do something like this: public class Splash extends UiApplication { public static void main( String[] args ){ Splash app = new Splash(); app.enterEventDispatcher(); } splash() { //splash screen pushScreen(new SplashScreen()); //wait for it close pushScreen(new SplashMainScreen()); } … } • Or the SpashScreen, can just as easily, pushScreen the SplashMainScreen and then the SplashScreen closes • an app is done when all screens have closed. Dialogs and background app's • If you application is running in the background with no screens. – You can use a dialog box to "alert" the user of something. – Assuming your app extends UiApplication, you can use something like this: synchronized(Application.getEventLock()){ UiEngine ui = Ui.getUiEngine(); Screen screen = new Dialog(Dialog.D_OK, "Look out!!!", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION), Manager.VERTICAL_SCROLL); ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_QUEUE); } • We’ll come back to Dialogs and Menus later. FormExample for BB • See the code in handout page. Written with native BB methods. References • BlackBerry Development Fundamentals, John Wargo, Addison Wesley, 2010 • http://www.blackberry.com/developers/docs/ 5.0.0api/index.html • Working with BlackBerry Layout Managers – http://developerlife.com/tutorials/?p=808 Q&A