Wednesday, January 2, 2013

Blackberry Java Development: Working with Dialogs

Like me, if you moved to Blackberry Development after having experience on some other platform, you might find yourself a little out of resources or maybe much more than little. In iOS or Android or even Windows Phone you could find resources and tutorials on everything ranging from creating a button to a high-end game. But in case of Blackberry you would quickly realize there is nothing more than just API references and insufficient docs. Just to make a simple thing work you will have to dig deeper into support forums with no guarantee for an answer. One such aspect is Dialogs, as Blackberry docs only provide a picture of the type of Dialog and best practices relating to it and no where they state how to work with them. So, here's simple guide to different types of dialogs in Blackberry.


Alert Dialogs
As the name suggests, the dialogs are used to alert users for an action or an error. An alert dialog can be closed by pressing the OK button or back key(called ESC key in Blackberry ecosystem).

Usage:
Dialog.alert("No internet connectivity");


This automatically puts a OK button and '!' as the icon in the dialog. Alert dialogs are very useful in notifying users of some error or an action that is required on their part.

Inform Dialogs
According to the UI Guidelines on Blackberry docs, Information Dialogs should be used to provide feedback about a user action and these dialogs should not contain any buttons. Also, these dialog boxes should be closed automatically after a predefined period of time, or users should be able to close them by pressing the Escape key. But the default inform dialog contains a OK button and it doesn't accepts any parameter to make it close after a certain period of time. The only method available is inform(String message). So the only difference between alert and inform dialog, I noticed was the icon of the dialog. Alert dialogs uses '!' bitmap whereas inform dialogs use 'i' letter as the icon by default.

Usage:
Dialog.inform("Message Deleted.");



Input Dialogs
Input dialogs contains an EditField that would allow users to enter input and an OK button to confirm input. But again the UI Guidelines only shows a screenshot of the dialog and do not state how to create one. So, here's an easy way to get desired output.

Usage:
BasicEditField inputField = new BasicEditField();                      

    Dialog d = new Dialog(Dialog.D_OK_CANCEL, "Enter your Username:", Dialog.OK, null, Dialog.DEFAULT_CLOSE);
    d.add(inputField);      

    int i = d.doModal();

    if (i == Dialog.OK) {
        Dialog.inform("Your Username is : " + inputField.getText());
    }


First, we create a BasicEditField like we do for a screen. Then we create a dialog which has two buttons i.e OK and Cancel asking users to enter their username. The default selection of the dialog is OK button and for the bitmap we have passed null as we don't want any icon for the dialog. You can choose any other type of dialog like a standard OK dialog using Dialog.D_OK which can be cancelled by the user by pressing the ESC key. Then we simply add the EditField to our dialog.
The doModal(); method actually shows the dialog to the user and pauses the execution until an action is received from the user. We store the user's choice i.e OK or Cancel in an int variable i; If the user pressed OK then we print the username on the screen using an inform dialog.
For explanation purpose I have restricted to a short piece code but in a real life situation you should also keep in mind exception handling and various other issues that may occur while handling user inputs.

Status Dialogs
Status dialogs are used to signal users that some process is going. Users cannot cancel this dialog i.e ESC has no effect on this dialog. Moreover, the features stated for the inform dialog are actually performed by Status dialog like; it doesn't contain an OK button and can be closed automatically after certain period of time.

Usage:
1 Status.show("One of the textfields is empty!");

2 Status.show("One of the textfields is empty!", 5000);

3 Status.show("Processing...", Bitmap.getPredefinedBitmap(Bitmap.HOURGLASS), 5000);

int value of 5000(milliseconds) makes the dialog to be closed after 5 secs automatically. And if you don't pass any value for time; default value of 2 seconds is used.


Inquiry Dialogs or Ask Dialogs
Another very useful type of dialog that may be used to confirm an action on the user's part like when a user cancelling a process or deleting some data. This dialog has a (?) mark as it's icon.

Usage:
Standard Yes No Dialog
int ans = Dialog.ask(Dialog.D_YES_NO);
    if (ans == Dialog.NO) {
        // Do Nothing
    } else {
        System.exit(0);
    }

Standard Save Dialog
int ans = Dialog.ask(Dialog.D_SAVE);
    if (ans == Dialog.SAVE) {
        // Save Data
    }
    else if (ans == Dialog.DISCARD) {
        System.exit(0);
    }    else {
        // Cancel Selected, Do Nothing
    }
Dialog.D_Save

Custom Ask Dialog with CheckboxField
Now, we will create a custom dialog with customized message, choices and bitmap.
CheckboxField check = new CheckboxField("Always warn me before quiting", true);

CheckboxField check = new CheckboxField("Always warn me before quiting", true);

Dialog d = new Dialog("Exit, without saving?", new String[] {"Save and Exit", "Exit without saving", "Cancel"}, new int[] {2,1,0}, 2, Bitmap.getPredefinedBitmap(Bitmap.QUESTION));
d.add(check);

int result = d.doModal();

 if (result == 2) {

    if (check.getChecked())
        // set warning to false in Preferences/SQLite
    }

    // Save Progress

    System.exit(0);
}

else if ( result == 1) {

    if (check.getChecked())
        // set warning to false in Preferences/SQLite
    }

    System.exit(0);
    }

else
        // Do Nothing


Exit, without saving? - Custom Message
new String[] {"Save and Exit", "Exit without saving", "Cancel"} - Custom Choices
new int[] {2,1,0} - Custom Values for Choices
2 - Default Selected Choice
Bitmap.getPredefinedBitmap(Bitmap.QUESTION) - Question (?) Icon

setDontAskAgainPrompt
This method allows you to add a "Don't ask again" checkbox to your dialog. Something like we did above but this method is not customizable.
setDontAskAgainPrompt(true);

// Global variables created
Dialog myDialog;
boolean readAccess;
.....

// Dialog initialized
myDialog = new Dialog(Dialog.D_YES_NO, "Allow this application to read call log?", Dialog.YES, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), 0L);
// Property set
myDialog.setDontAskAgainPrompt(true);
.....

// bringing it to work
if (myDialog.isDontAskAgainChecked() == false) {
    int ans = myDialog.doModal();
   
    if (ans == Dialog.YES) {
        // Allow
        readAccess = true;
    }
    else {
        // don't allow
        readAccess = false;
    }
}
else {
    if (readAccess){
    // Allow
    }
    else
    // Don't allow
}

Some Tips
> You can always attach a CloseListener to your Dialog if you want capture the close event of the dialog.
myDialog.setDialogClosedListener(new DialogClosedListener() {           

    public void dialogClosed(Dialog dialog, int choice) {
  // TODO Auto-generated method stub

        System.out.println("[LOG] Output Choice: " + choice);
    }

});
DialogClosedListener only work with dialogs created modelessly i.e setDialogClosedListener will not work with doModal method. For getting this listener to work, you have to use myDialog.show(); instead of myDialog.doModal();. The Dialog.show(); does not wait for user input before returning which means it does not pauses the execution of the program and the statement after this method continue to execute.

> Many times you don't want a dialog to be closed without getting a user input. For this you can prevent users to close the dialog by pressing ESC key. This can be achieved by using the setEscapeEnabled method.
myDialog.setEscapeEnabled(false);

I hope, through this tutorial, I was able to get you through various Blackberry Dialog scenarios. If you still have any issue you can add a comment.
Also, if this article helped you, consider SHARING with your friends.

2 comments:

  1. Java lovers’ gona love it, Check it out.... JavaOne 2013 is apparently being held at Hyderabad this year as well (8-9 May) at the same place guys…. They have also started accepting registrations (check this: http://bit.ly/YMPeJ8 )

    ReplyDelete