This morning I got the idea to add some UI utility classes to my mobile library. I really like ease of use API’s where their functionality is somewhat self evident based on its naming. I had been earlier looking at how to add controls to the forms that were not part of the toolkit including creating my own custom controls to be emended.  So this I expect is the first of several articles as I move forward to add more functionality to libraries. Hope it helps.

Enhancing the Platform

There comes a time when a client will ask you for something that is not part of the core platform functionality. This could be to show data in a report form or extend the UI. Digging around in the code that is provided out of the box will not provide any insight into how to accomplish the task required. This is where digging into Java and the BlackBerry SDK will provide the best results.

The scenario is as follows;

The customer likes the way the account form looks but would like to break up the view in a way to distinguish different areas of the data. For example display the address information grouped by separator lines. When completed the account main screen should look like :

clip_image002

Note the separator line between the account field and address field and also between the postal and division field.

Step 1 – Looking for a solution

Looking into the mobile platform there is no UI element available for a separator. So we now have to look outside for a solution. Knowing that each of the controls that are displayed on a BlackBerry form are derived from a field control (net.rim.device.api.ui.Field) it is completely possible for the creation of a custom control to provide this kind of support. However when looking into the BB SDK we can find that a SeparatorField is available that will serve the purpose nicely.

Now knowing the control that will be hosted in the screen we need to define how it should be added. This is where understanding that fields on BlackBerry are hosted with a layout manager. Each field has a method aptly named getManager that will return the layout manager where the field is sited.

So now we know how the field is hosted, and what control to use it is time to code up the solution.

Writing the code

You could write the code for this functionality in the Mobile Application Architect however this would require more effort in your part to ensure that it works the first time. Since there are no visual cues in AA compilation is the only way to determine if your code is good.

This is where we jump back out into Eclipse and work with the mobile project we completed earlier. Being a big fan of creating reusable code instead of writhing the bulk of the code in the Account detail form we will create a new extended API class.

Startup eclipse and open your ‘sage’ workspace. Locate the sage.mobile.customization.forms package in the package explorer

clip_image004

Using the context menu options select New->Class

Name the new class UIUtility and uncheck the ‘Include Public void main…’ checkbox. Click done and a new empty class file is opened for you.

Note that the class is placed in the sage.mobile.customizations.forms package for you.

Stubbing out the methods

Part of the design of APIs is ensuring that the exposed functionality will make sense to not only you but any of the potential consumers of the functionality. If the methods are easily understood, less documentation in the calling code will need to be written.

So in thinking about the functionality we may like the following items

Insert separator before – adds the separator line before a given field

Insert separator after – adds the separator line after a given field

Also we understand that the separator field derives from the field so we could even expose more functionality by providing insert field before and after methods.

This gives us the following signatures

InsertFieldBefore(FormCodeBehind, FieldName, Field)

InsertFieldAfter(FormCodeBehind,FieldName,Field)

InsertSeparatorBefore(FormCodeBehind,FieldName)

InsertSeperatorAfter(FormCodeBehind,FieldName)

Now you might be thinking why the FormCodeBehind property. Well if you dig into the mobile API any changes we would be making to the form is through the code behind class. This class also provides the control lookup functionality that we need to get access to the underlying manager.

Your stubbed out class should look like

clip_image006

What is interesting is the immediate feedback you get in eclipse for any errors that are occurring. If you notice the clip_image008 image – selecting will provide some hints on how to fix the found issue

The indicated issues have to do with types not being imported into the class file. By adding these 2 lines in to the class file the errors are removed;

import net.rim.device.api.ui.Field;

import sage.mobile.codebinding.FormCodeBehind;

Now to write the code. In the AddFieldBefore method add the following code. You will notice an error on the line that the Manager variable is defined;

clip_image010

Again click on the error symbol, and import the net.rim.device.api.ui.Manager type.

Looking at the code we start off by guarding from invalid input from the caller. Remember this is a API method and we do not know who will be using it. Accessing the code behind getControl method we will get the control that our new one should be positioned beside. If we can find the field we then get the manager. Remember the manager is what the fields are hosted on. You can think of it as an invisible panel control. Finally we find out the index of the control layed out in the manager and insert our new control at the same position bumping the aligned control ahead.

Filling out the AddFieldAfter code looks like this;

clip_image012

The only notable change is the calculation of the new control index to position it after the aligned control.

Now that we have our ‘Generic’ one size fits all methods we can create our separator specific ones. These methods are quite easy to implement and I will show both methods

clip_image014

Again note the errors and resolve them by importing the net.rim.device.api.ui.component.SeparatorField type

Moving Class back into Application Architect

Now that the class has been created and error free we want to move it back into AA. There is no fancy way to do this then create a new Java class in AA and copy and paste your code from the eclipse project into your AA class.

On the Mobile Customizations tree select the ‘Java Classes’ item and using the context menu choose ‘New’.

The Add Item dialog is displayed. Choose the ‘Base Java Class’ template. For plugin name enter UIUtility.

Replace the default text with the contents of the UIUtility class created in eclipse. Save the changes.

For the code to be compiled and accessible to the forms you will have to add the UIUtlity class to any of the targeted BlackBerry client systems.

Augmenting the Account Form

The bulk of the code required is written, and included in the client system. Compile the client system and ensure that it indeed does compile successfully.

Once you are satisfied that the CS compiles successfully open up the account form. Remember that we started out this exercise with wanting to separate the address from account and also postal from division. From this the 2 target controls that we want to separate are named ‘Address1’ and ‘Postal’.

Note: Control lookup is case sensitive so ensure that the case matches both control name and text name in the code.

In the code behind for the account we are going to add 2 new lines (one for each seperator). Add the following lines to the FormShow method.

clip_image016

Remember to access this new functionality you will need to import the type. The import line to add is;

import sage.mobile.customizations.forms.UIUtilities;

Save the changes, compile and deploy the client system. Start up the simulator, check for and download your customizations.

When you now open up the account detail screen you should now have the proper level of field separation.

Leave a Reply