Display a progress screen for BlackBerry app - blackberry

How to display a progress screen when BlackBerry application is fetching data from remote server ?
I want an progress screen without animated gif without any button. (OK or Cancel )

public class ProgressDialog extends PopupScreen
{
public ProgressDialog(String waitString)
{
super(new VerticalFieldManager());
add(new LabelField(waitString,Field.FIELD_HCENTER));//add a string which u want to show for progressing
}
}
ProgressDialog progress = new ProgressDialog("Please Wait...");
//Add screen to UI
UiApplication.getUiApplication().pushScreen(progress);
//Remove screen from UI
progress.close();

ProgressBar progressBar = new ProgressBar("Waiting for location update....",50,1000);
progressBar.start(); // Start progress bar
progressBar.remove(); //remove progress bar
ProgressBar Thread
public class ProgressBar extends Thread {
Thread thd;
private int maximum, timeout;
private boolean useful = true;
private PopupScreen popup;
private int iterations = 0;
/**
* Object constructor
*
* #param title
* Text to display on popup area
* #param maximum
* Range / width of the gauge field of progress bar
* #param timeout
* Milliseconds to pause between updates to progress bar
* #see GaugeField
* #see Thread
* #see PopupScreen
*/
public ProgressBar(String title, int maximum, int timeout) {
this.maximum = maximum;
this.timeout = timeout;
VerticalFieldManager manager = new VerticalFieldManager();
popup = new PopupScreen(manager);
manager.add(new LabelField(title));
}
/**
* run() method for starting thread
*/
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(popup);
}
});
int iterations = 0;
while (useful) {
System.out.println("I m here in while runn "+ useful);
try {
Thread.sleep(timeout);
} catch (Exception e) {
}
if (++iterations > maximum)
{
iterations = 1;
useful = false;
UiApplication.getUiApplication().invokeLater( new Runnable()
{
public void run ()
{
_locationProvider.reset();
Dialog.alert("Location not found.");
}
} );
}
// gaugeField.setValue(iterations);
}
if (popup.isDisplayed()) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(popup);
}
});
}
}
/**
* Method to shutdown the thread and remove the popup screen
*
*/
public synchronized void remove() {
useful = false;
}
}

Related

Blackberry scrolling doesn't redraw fields

I have a very strange problem at the moment.
Basically when I scroll in a screen, the fields don't get redrawn completely or consistently.
I have a Screen (NO_VERTICAL_SCROLL), with a manager as a titlebar. Below that I have a vertical field manager (VERTICAL_SCROLL) with labelfields. When I scroll the vfm one or two lines of the labelfields, which were already visible, get redrawn. The section I'm scrolling down to has absolutely nothing drawn.
I tried invalidate(), and calling doPaint in a scrollchangelistener, but its actually much worse. It results in the titlebar only being partially redrawn.
In the code below I used a custom FontManager, DimenManager, and ImageResourceManager to return values dependent on screen size. I used a custom BitmapButtonField and ClickableLabel in order to change the state of a field when a click is being held in.
public class BaseScreen extends MainScreen implements StringsResource
{
protected ResourceBundle resources;
public BaseScreen(long style)
{
super(style);
StandardTitleBar titlebar = new StandardTitleBar();
titlebar.addSignalIndicator();
titlebar.addClock();
titlebar.addNotifications();
setTitle(titlebar);
resources = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);
}
}
public class TandCScreen extends BaseScreen
{
final String copy_text1 = "long text here";
final String copy_text2 = "even longer text here";
ColoredLabelField label_title;
ColoredLabelField label_subtitle;
ColoredLabelField label1;
ColoredLabelField label2;
ClickableLabel label3;
public TandCScreen()
{
super(NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR);
label_title = new ColoredLabelField(resources.getString(STRING_APP_NAME), Color.WHITE, DrawStyle.HCENTER | USE_ALL_WIDTH);
label_title.setBackground(BackgroundFactory.createSolidBackground(0x60223b));
label_subtitle = new ColoredLabelField(resources.getString(STRING_TANDC_TITLE), 0x58585b, DrawStyle.HCENTER | USE_ALL_WIDTH);
label1 = new ColoredLabelField(copy_text1, 0x58585b, USE_ALL_WIDTH);
label2 = new ColoredLabelField("", 0xa7a9ab, USE_ALL_WIDTH);
label3 = new ClickableLabel("Read more...")
{
protected void unclick()
{
super.unclick();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
ColoredLabelField label = new ColoredLabelField(copy_text2, 0xa7a9ab, 0);
label.setFont(FontManager.body());
label.setMargin(0, 0, DimenManager.interField(), 0);
label2.getManager().replace(label2, label);
label3.getManager().delete(label3);
}
});
}
};
label_title.setFont(FontManager.subtitle());
label_subtitle.setFont(FontManager.subtitle());
label1.setFont(FontManager.body());
label2.setFont(FontManager.body());
label3.setFont(FontManager.body());
BitmapButtonField button_accept = new BitmapButtonField(ImageResourceManager.buttonAccept(), ImageResourceManager.buttonAcceptHover(), FIELD_HCENTER)
{
protected void click()
{
super.click();
setImage(ImageResourceManager.buttonAcceptSelected());
setFocusImage(ImageResourceManager.buttonAcceptSelected());
}
protected void unclick()
{
super.unclick();
PersistentStoreManager.setTandCAccepted(true);
UiApplication.getUiApplication().pushScreen(new LoginScreen());
close();
}
};
BitmapButtonField button_decline = new BitmapButtonField(ImageResourceManager.buttonDecline(), ImageResourceManager.buttonDeclineHover(), FIELD_HCENTER)
{
protected void click()
{
super.click();
setImage(ImageResourceManager.buttonDeclineSelected());
setFocusImage(ImageResourceManager.buttonDeclineSelected());
}
protected void unclick()
{
super.unclick();
close();
}
};
int margin = (VariableManager.DISPLAY_WIDTH - button_accept.getPreferredWidth()) / 2;
// calculate where to put ellipsis
Font font = label2.getFont();
int max_length = (VariableManager.DISPLAY_WIDTH - margin * 2) * 2;
int i = copy_text2.length() - 1;
while (font.getAdvance(copy_text2.substring(0, i)) + font.getAdvance("...") >= max_length)
i--;
label2.setText(copy_text2.substring(0, i).trim() + "...");
VerticalFieldManager vfm = new VerticalFieldManager(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
vfm.add(new NullField());
vfm.add(label_subtitle);
vfm.add(new Seperator());
vfm.add(label1);
vfm.add(label2);
vfm.add(label3);
vfm.add(button_accept);
vfm.add(button_decline);
vfm.setMargin(0, margin, 0, margin);
// paddings
int padding = (DimenManager.header() - label_title.getPreferredHeight()) / 2;
label_title.setPadding(padding, 0, padding, 0);
label_subtitle.setPadding(DimenManager.interField(), 0, DimenManager.interField(), 0);
label1.setMargin(DimenManager.interField(), 0, DimenManager.interField(), 0);
label3.setMargin(DimenManager.interField(), 0, DimenManager.interField(), button_accept.getPreferredWidth() - label3.getPreferredWidth());
button_decline.setMargin(DimenManager.interField(), 0, DimenManager.interButton(), 0);
add(label_title);
add(vfm);
}
protected boolean onSavePrompt()
{
return false;
}
protected void makeMenu(Menu menu, int instance)
{
if (instance == Menu.INSTANCE_CONTEXT)
{
ContextMenu contextMenu = ContextMenu.getInstance();
contextMenu.setTarget(this);
contextMenu.clear();
this.makeContextMenu(contextMenu);
menu.deleteAll();
menu.add(contextMenu);
}
else
{
super.makeMenu(menu, instance);
}
}
protected void makeContextMenu(ContextMenu contextMenu)
{
}
/**
* Clickable labelfield which changes color on down press, and fires action
* on release. Action is canceled if touch moves outside field bounds.
*
* #author kevin
*
*/
private class ClickableLabel extends LabelField
{
private boolean canceled = true;
private boolean consumed = false;
protected boolean pressed = false;
public ClickableLabel(String label)
{
super(label, LabelField.FOCUSABLE | USE_ALL_WIDTH);
setFont(FontManager.body());
}
protected void paint(Graphics g)
{
// background
if (pressed)
{
g.setColor(0x2C1721);
}
else if (isFocus())
{
g.setColor(0x993C6B);
}
else
{
g.setColor(0x60223B);
}
int padding_y = (getPreferredHeight() - getFont().getHeight()) / 2;
int padding_x = getPaddingLeft();
g.drawText(getText(), padding_x, padding_y);
}
public int getPreferredHeight()
{
return ImageResourceManager.highlight().getHeight();
}
protected void layout(int width, int height)
{
height = getPreferredHeight();
super.layout(width, height);
setExtent(width, height);
}
// --------- Highlight selected row ---------
protected void onFocus(int direction)
{
super.onFocus(direction);
invalidate();
}
protected void onUnfocus()
{
super.onUnfocus();
invalidate();
}
// --------------------------------------------
protected void drawFocus(Graphics graphics, boolean on)
{
}
/**
* Called when trackpad pressed, or touchscreen touched
*/
protected void click()
{
pressed = true;
invalidate();
}
/**
* Called when trackpad released, or touchscreen released
*/
protected void unclick()
{
cancel();
}
protected void cancel()
{
pressed = false;
invalidate();
}
protected boolean navigationClick(int status, int time)
{
if (status != 0)
{
if (consumed)
{
consumed = false;
}
else
{
click();
}
}
return true;
}
protected boolean navigationUnclick(int status, int time)
{
if (status != 0)
{
if (consumed)
consumed = false;
else
unclick();
}
return true;
}
protected boolean touchEvent(TouchEvent message)
{
int x = message.getX(1);
int y = message.getY(1);
if (x < 0 || y < 0 || x > getExtent().width || y > getExtent().height)
{
// Outside the field
if (!canceled)
{
cancel();
}
canceled = true;
return false;
}
if (message.getEvent() == TouchEvent.UP)
{
if (canceled)
cancel();
else
unclick();
consumed = true;
return true;
}
if (message.getEvent() == TouchEvent.DOWN)
{
click();
consumed = true;
canceled = false;
return true;
}
return super.touchEvent(message);
}
}
private class Seperator extends SeparatorField
{
protected void paint(Graphics graphics)
{
graphics.setColor(0xa7a9ab);
super.paint(graphics);
}
}
}
Thanks in advance for any suggestions
I don't think it is possible to do anything but guess at your problem without looking at your code. But whatever your problem is, I am confident that it is based on a misunderstanding of how to use Managers within a Screen. So I recommend that you review the following articles to improve your knowledge in this area and so hopefully resolve the problem yourself:
Start here:
UI Introduction
This provides the Background around Managers and Fields.
Then read this article:
MainScreen Explained
I suspect as a result of reading this article, you may be able to discard your 'title bar' and use setTitle() or setBanner() to provide this function.
I hope this resolves your problems.
A few other points:
In all my years of BB programming, I have never had to use doPaint() to get something painting the way I wanted. I can't think of a situation that this will in fact help. So if you think you need it, try invalidate() instead.
I have used invalidate() when I making a change to the Field that will change its on screen appearance (but not its size). I have used it in a scroll change listener. But it is a method of last resort.
Remember that LabelFields are not focusable, so in OS's before 6, that made them a problem to scroll.
Found the issue. On the labelfields, there was a setExtent(getPreferredWidth(), getPreferredHeight()); that was reducing the size of the area to redraw. Very stupid mistake.
Thanks to everyone who tried to help.

Cant scrolling during .notifyDataSetChanged()

In following project here is example
I'm using with .notifyDataSetChanged(); this method .post(new Runnable(){ to scroll down after adding new item
private void addItemsToList() {
int randomVal = MIN + (int) (Math.random() * ((MAX - MIN) + 1));
mItems.add(String.valueOf(randomVal));
mListAdapter.notifyDataSetChanged();
mCompleteListView.post(new Runnable(){
public void run() {
mCompleteListView.setSelection(mCompleteListView.getCount() - 1);
}});
}
public class ReceiverThread extends Thread {
String line;
String name;
ReceiverThread(String name, String line){
this.line=line;
this.name=name;
}
public void run() {
OpenStream.this.runOnUiThread(new Runnable() {
public void run() {
addItemsToList();}}}}
BUT when I want scroll up by using finger, new programmatically added item scrolls listview to down.
How I can set off .post(new Runnable() when I touch the screen and using finger to scroll? or what can I do to don't let listview scroll down when I touch the screen?
I've added this code, and now when I touch listview there is no scrolling to down
mCompleteListView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
flag = true;
Log.e(MainActivity.tag,"onTouch "+flag);
}else{
flag = false;
Log.e(MainActivity.tag,"onTouch "+flag);
}
return false;
}
});

App Error 104 uncaught : runtime exception while running blackberry application

I have created one application to get My location coordinates using GPS after deploying my code in simulator i am getting above error with explanation -
uncaught exception:pushmodalscreen called by a non-event thread
I am not able to figure out whats going wrong.
/**
* GPSDemo.java
*
* Copyright © 1998-2011 Research In Motion Ltd.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.gps;
import java.util.*;
import javax.microedition.location.*;
import net.rim.device.api.command.*;
import net.rim.device.api.gps.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.util.*;
import net.rim.blackberry.api.invoke.*;
import net.rim.blackberry.api.maps.*;
import net.rim.blackberry.api.menuitem.*;
/**
* This application acts as a simple travel computer, recording route
* coordinates, speed and altitude. Recording begins as soon as the
* application is invoked.
*/
public class GPSScreen extends UiApplication
{
// Represents the number of updates over which altitude is calculated, in seconds
private static final int GRADE_INTERVAL = 5;
private static final long ID = 0x5d459971bb15ae7aL;
// Represents period of the position query, in seconds
private static int _interval = 1;
private double _latitude;
private double _longitude;
private LocationProvider _locationProvider;
private GPSDemoScreen _screen;
private MapView _mapview = new MapView();
/**
* Entry point for application
*
* #param args Command line arguments (not used)
*/
public static void main(String[] args)
{
// Create a new instance of the application and make the currently
// running thread the application's event dispatch thread.
new GPSScreen().enterEventDispatcher();
}
/**
* Create a new GPSDemo object
*/
public GPSScreen()
{
_screen = new GPSDemoScreen();
_screen.setTitle("GPS Demo");
// Attempt to start the location listening thread
if(startLocationUpdate())
{
_screen.setState(_locationProvider.getState());
}
// Render the screen
pushScreen(_screen);
}
/**
* Invokes the Location API with Standalone criteria
*
* #return True if the <code>LocationProvider</code> was successfully started, false otherwise
*/
private boolean startLocationUpdate()
{
boolean returnValue = false;
if(!(GPSInfo.getDefaultGPSMode() == GPSInfo.GPS_MODE_NONE))
{
try
{
Criteria criteria = new Criteria();
criteria.setCostAllowed(false);
_locationProvider = LocationProvider.getInstance(criteria);
if(_locationProvider != null)
{
/*
* Only a single listener can be associated with a provider,
* and unsetting it involves the same call but with null.
* Therefore, there is no need to cache the listener
* instance request an update every second.
*/
_locationProvider.setLocationListener(new LocationListenerImpl(), _interval, -1, -1);
returnValue = true;
}
else
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Failed to obtain a location provider, exiting...");
System.exit(0);
}
});
}
}
catch(final LocationException le)
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Failed to instantiate LocationProvider object, exiting..." + le.toString());
System.exit(0);
}
});
}
}
else
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("GPS is not supported on this device, exiting...");
System.exit(0);
}
});
}
return true;
}
/**
* Implementation of the LocationListener interface. Listens for updates to
* the device location and displays the results.
*/
private class LocationListenerImpl implements LocationListener
{
/**
* #see javax.microedition.location.LocationListener#locationUpdated(LocationProvider,Location)
*/
public void locationUpdated(LocationProvider provider, Location location)
{
if(location.isValid())
{
_longitude = location.getQualifiedCoordinates().getLongitude();
_latitude = location.getQualifiedCoordinates().getLatitude();
_mapview.setZoom(Integer.parseInt("0.1"));
try
{
int latitude = (int) (100000 * _latitude);
int longitude = (int) (100000 * _longitude);
if (latitude > 9000000 || latitude < -9000000 || longitude >= 18000000 || longitude < -18000000)
{
throw new IllegalArgumentException ();
}
_mapview.setLatitude(latitude);
_mapview.setLongitude(longitude);
// Invoke BlackBerry Maps application with provided MapView object.
Invoke.invokeApplication(Invoke.APP_TYPE_MAPS, new MapsArguments(_mapview));
}
catch(RuntimeException re)
{
// An exception is thrown when any of the following occur :
// Latitude is invalid : Valid range: [-90, 90]
// Longitude is invalid : Valid range: [-180, 180)
// Minus sign between 2 numbers.
Dialog.alert("Temporary Unavailable Service");
}
}
}
/**
* #see javax.microedition.location.LocationListener#providerStateChanged(LocationProvider, int)
*/
public void providerStateChanged(LocationProvider provider, int newState)
{
if(newState == LocationProvider.TEMPORARILY_UNAVAILABLE)
{
provider.reset();
}
_screen.setState(newState);
}
}
/**
* The main screen to display the current GPS information
*/
private final class GPSDemoScreen extends MainScreen
{
TextField _statusTextField;
/**
* Create a new GPSDemoScreen object
*/
GPSDemoScreen()
{
// Initialize UI
_statusTextField = new TextField(Field.NON_FOCUSABLE);
}
/**
* Display the state of the GPS service
*
* #param newState The state to display
*/
public void setState(final int newState)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
/**
* #see java.lang.Runnable#run()
*/
public void run()
{
switch(newState)
{
case LocationProvider.AVAILABLE:
_statusTextField.setText("Available");
break;
case LocationProvider.OUT_OF_SERVICE:
_statusTextField.setText("Out of Service");
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
_statusTextField.setText("Temporarily Unavailable");
break;
}
}
});
}
/**
* #see net.rim.device.api.ui.Screen#close()
*/
public void close()
{
if(_locationProvider != null)
{
_locationProvider.reset();
_locationProvider.setLocationListener(null, -1, -1, -1);
}
super.close();
}
}
}
I've seen that error when Dialog.alert() is used outside of the event thread. Looking at your code, I see LocationListenerImpl.locationUpdated assumes it is running on the event thread. If it is not, the UI update code would throw an exception, and then your exception handler will try to display a dialog, and that will fail as well.

why menus come on the double click of panes, i don't want that menus appear

Hi friends I got sample code for Pane Manager from blackberry samples but when i run that sample and double click on tabs ,menus appear .I don't want to show that menus on click.how to do it.please tell me why this is happening? i am not understanding the code.Please help
public class PaneManagerDemo extends UiApplication
{
/**
* Entry point for the application
* #param args Command line arguments (not used)
*/
public static void main(String[] args)
{
UiApplication app = new PaneManagerDemo();
app.enterEventDispatcher();
}
/**
* Creates a new PaneManagerDemo object
*/
public PaneManagerDemo()
{
invokeLater(new Runnable()
{
public void run()
{
int headerType = 0;
// Display a dialog for user to select header type
OptionDialog dialog = new OptionDialog();
int result = dialog.doModal();
if(result == Dialog.OK)
{
headerType = dialog.getHeaderType();
}
else if(result == Dialog.CANCEL)
{
System.exit(0);
}
//PaneScreen screen = new PaneScreen(headerType);
PaneScreen screen = new PaneScreen(headerType);
pushScreen(screen);
}
});
}
/**
* A dialog popup used to choose a header type
*/
private static class OptionDialog extends Dialog
{
public static final int SCROLL_HEADER_TYPE = 0;
public static final int TAB_HEADER_TYPE = 1;
private ObjectChoiceField _choiceField;
/**
* Create a new HeaderDialog object
*/
public OptionDialog()
{
super(Dialog.D_OK_CANCEL, "Choose Header Type", Dialog.OK, null, Dialog.GLOBAL_STATUS);
_choiceField = new ObjectChoiceField("", new String[]{"Scrollable", "Tab"}, 0);
add(_choiceField);
_choiceField.setFocus();
}
/**
* Returns an integer representing the header type
*
* #return SCROLL_HEADER_TYPE if scrollable header selected, TAB_HEADER_TYPE if tab header selected
*/
public int getHeaderType()
{
return _choiceField.getSelectedIndex();
}
}
/**
* Main screen for the application. Displays three panes
* switchable via horizontal scroll field or tabs, depending
* on user selection.
*/
private final static class PaneScreen extends MainScreen
{
/**
* Creates a new PaneScreen object
* #param headerType The header type for the PaneManager, scrollable or tab style
*/
public PaneScreen(int headerType)
{
super(Field.FOCUSABLE);
// Instantiate the model for the pane manager and enable looping
PaneManagerModel model = new PaneManagerModel();
model.enableLooping(true);
// Create a pane
VerticalFieldManager vfm = new VerticalFieldManager();
vfm.add(new LabelField("Data 1"));
XYEdges edgesOne = new XYEdges(1, 1, 1, 1);
vfm.setBorder(BorderFactory.createRoundedBorder(edgesOne));
Pane pane = new Pane(new LabelField("Pane 1", Field.FOCUSABLE | Field.FIELD_HCENTER), vfm);
// Add the pane to the model
model.addPane(pane);
// Create a second pane
vfm = new VerticalFieldManager();
for(int i = 0; i < 30; i++)
{
vfm.add(new LabelField("Data " + i, Field.FOCUSABLE));
}
LabelField iconTextLabelField = new LabelField("Pane 2");
model.addPane(new Pane(iconTextLabelField, vfm));
// Create a third pane
vfm = new VerticalFieldManager();
ButtonField button = new ButtonField("Button", ButtonField.CONSUME_CLICK | ButtonField.NEVER_DIRTY);
button.setChangeListener( new FieldChangeListener()
{
public void fieldChanged(Field field, int context)
{
Dialog.inform("Button activated.");
}
});
vfm.add(button);
model.addPane(new Pane(new LabelField("Pane 3"), vfm));
// Choose which pane the model is displaying
model.setCurrentlySelectedIndex(1);
// Create the header and initialize the model and visual properties
TitleView header = null;
PaneManagerController controller = null;
if(headerType == OptionDialog.SCROLL_HEADER_TYPE)
{
header = new HorizontalScrollableTitleView(Field.FOCUSABLE);
controller = new HorizontalScrollableController();
}
else if(headerType == OptionDialog.TAB_HEADER_TYPE)
{
header = new HorizontalTabTitleView(Field.FOCUSABLE);
((HorizontalTabTitleView)header).setNumberOfDisplayedTabs(model.numberOfPanes());
controller = new HorizontalTabController();
}
else
{
throw new IllegalStateException("Header type is not valid.");
}
header.setModel(model);
XYEdges edgesFour = new XYEdges(4, 4, 4, 4);
header.setBorder(BorderFactory.createRoundedBorder(edgesFour));
// Set arrow images
Bitmap leftArrow = Bitmap.getBitmapResource("leftArrow.png");
Bitmap rightArrow = Bitmap.getBitmapResource("rightArrow.png");
if(leftArrow != null)
{
header.setLeftArrow(leftArrow);
}
if(rightArrow != null)
{
header.setRightArrow(rightArrow);
}
// Create the PaneView object, which will display the panes and is
// controlled by the model.
PaneView paneView = new PaneView(Field.FOCUSABLE);
paneView.setBorder(BorderFactory.createSimpleBorder(edgesOne));
paneView.setModel(model);
// Initialize the PaneManagerView
PaneManagerView view = new PaneManagerView(Field.FOCUSABLE, header, paneView);
view.setModel(model);
view.setBorder(BorderFactory.createRoundedBorder(edgesFour));
model.setView(view);
// Initialize the Controller
controller.setModel(model);
controller.setView(view);
model.setController(controller);
view.setController(controller);
add(view);
}
}
}
If you want to hide context menu (popup menu) just write this code
protected boolean navigationClick(int status, int time)
{
return true;
}
This is totally works good for me .

Vertical scrollbar with jump points - setVerticalScroll locking UI

I have a question about the BlackBerry VerticalScrollField and scrolling which seems to lock or make the UI unstable. The following code is a BlackBerry screen with worlds as content on the left (in a scroll field) and a jumpbar off to the right that allows clicking into the content.
When a jump letter is clicked the setVerticalScroll method is called, it performs the scroll but has the unfortunate side effect of rendering the UI unstable or unusable. The scroll call is done on the UI thread so its not clear what the source of the error is. The app is being tested in a 6.0 simulator.
I've included the class which can be copied into BB Eclipse for hacking/testing.
The section that kicks of the scrolling can be found towards the bottom with the following code:
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run() {
scroller.setVerticalScroll(y, true);
}});
Here's the full class:
package test;
import java.util.Vector;
import net.rim.device.api.system.ApplicationManager;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.Status;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
public class Startup extends UiApplication {
private int[] jump;
static final String[] words = new String[]{
"auto", "apple", "bear", "car", "farm", "ferret", "gold",
"green", "garden", "hedge", "happy", "igloo", "infrared",
"jelly", "kangaroo", "lemon", "lion", "marble", "moon",
"nine", "opera", "orange", "people", "puppy", "pear",
"quince", "race", "run", "sunset", "token", "willow", "zebra"
};
private final static String[] alphabet = new String[]{"A","B","C","D","E",
"F","G","H","I","J","K","L","M","N","O","P","Q","R",
"S","T","U","V","W","X","Y","Z","#"};
private VerticalFieldManager scroller;
public Startup() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(new ScrollScreen());
}
});
}
public static void main(String[] args) {
ApplicationManager app = ApplicationManager.getApplicationManager();
while (app.inStartup()) {
try { Thread.sleep(200); } catch (Throwable e) {}
}
Startup startup = new Startup();
startup.enterEventDispatcher();
}
/**
* Screen with content in a scrollbar left and a letters on the right that
* can be used to jump into the content.
*/
class ScrollScreen extends MainScreen {
public ScrollScreen() {
super(NO_HORIZONTAL_SCROLL | NO_VERTICAL_SCROLL);
HorizontalFieldManager hfm = new HorizontalFieldManager(USE_ALL_HEIGHT | NO_VERTICAL_SCROLL | NO_HORIZONTAL_SCROLL){
protected void sublayout(int maxWidth, int maxHeight) {
Field scroll = getField(0);
Field alpha = getField(1);
layoutChild(alpha, maxWidth, maxHeight);
layoutChild(scroll, maxWidth-alpha.getWidth(), maxHeight);
setPositionChild(scroll, 0, 0);
setPositionChild(alpha, maxWidth-alpha.getWidth(), 0);
setExtent(maxWidth, maxHeight);
}
};
hfm.add(createScrollContent());
hfm.add(createAlphabetJumpBar());
add(hfm);
}
private Field createScrollContent() {
Vector vocabulary = new Vector();
for (int ii=0; ii<alphabet.length; ii++)
vocabulary.addElement(alphabet[ii]);
scroller = new VerticalFieldManager(VERTICAL_SCROLL | USE_ALL_WIDTH) {
protected void sublayout(int maxWidth, int maxHeight) {
// Record the jump offsets
int y = 0;
for (int ii=0; ii<getFieldCount(); ii++) {
Field field = getField(ii);
layoutChild(field, maxWidth, maxHeight);
setPositionChild(field, 0, y);
if (field instanceof WordField) {
WordField object = (WordField)field;;
char character = object.getWord().toLowerCase().charAt(0);
int offset = ((int)character)-(int)alphabet[0].toLowerCase().charAt(0);
if (offset < 0 || offset > jump.length)
offset = jump.length-1;
while (offset >= 0 && offset < jump.length && jump[offset] == 0) {
jump[offset] = y;
offset--;
}
}
y += field.getHeight();
}
int offset = jump.length-1;
do {
jump[offset] = y;
offset--;
} while (offset >= 0 && jump[offset] == 0);
setExtent(maxWidth, maxHeight);
setVirtualExtent(maxWidth, y+10);
}
};
jump = new int[alphabet.length];
Font largeFont = Font.getDefault().derive(Font.PLAIN, 46);
for (int ii=0; ii<words.length; ii++) {
WordField wordField = new WordField(words[ii]);
wordField.setFont(largeFont);
scroller.add(wordField);
}
return scroller;
}
private Field createAlphabetJumpBar() {
VerticalFieldManager vfm = new VerticalFieldManager() {
protected void sublayout(int maxWidth, int maxHeight) {
int y = 0;
int width = 0;
double allowedAlphaHeight = (double)maxHeight / (double)getFieldCount();
for (int ii=0; ii<getFieldCount(); ii++) {
WordField field = (WordField)getField(ii);
layoutChild(field, maxWidth, (int)allowedAlphaHeight);
setPositionChild(field, 0, y);
y += field.getHeight();
double paddedY = Math.floor(allowedAlphaHeight*(ii+1));
if (y < paddedY) y = (int)paddedY;
width = Math.max(width, field.getWidth());
}
setExtent(width, maxHeight);
}
};
for (int ii=0; ii<alphabet.length; ii++) {
vfm.add(new AlphaField(alphabet[ii]){
protected boolean touchEvent(TouchEvent message) {
if (message.getEvent() == TouchEvent.UP) {
int startOffset = (int)alphabet[0].charAt(0);
int offset = ((int)getWord().charAt(0)) - startOffset;
final int y = offset == 0 ? 0 : jump[offset - 1];
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run() {
scroller.setVerticalScroll(y, true);
}});
}
return true;
}
});
}
return vfm;
}
class WordField extends LabelField {
private final String word;
public WordField(String word) {
super(word);
this.word = word;
}
public String getWord() { return word; }
}
Font alphaFont = null;
class AlphaField extends WordField {
public AlphaField(String word) {
super(word);
}
protected void layout(int width, int height) {
if (alphaFont == null)
alphaFont = Font.getDefault().derive(Font.PLAIN, height);
setExtent(alphaFont.getAdvance(getWord()), alphaFont.getHeight());
}
protected void paint(Graphics graphics) {
graphics.setFont(alphaFont);
graphics.drawText(getWord(), 0, 0);
}
}
/**
* For debugging.
* #see net.rim.device.api.ui.Screen#keyChar(char, int, int)
*/
protected boolean keyChar(char c, int status, int time) {
if ('o' == c) { // shows the jump offsets into the scroll field
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run() {
StringBuffer buf = new StringBuffer();
for (int ii=0; ii<jump.length; ii++) {
buf.append(alphabet[ii]+"="+jump[ii]);
if (ii<jump.length-1)
buf.append(",");
}
Status.show("offsets="+buf.toString());
}});
}
return super.keyChar(c, status, time);
}
}
}
You're using UiApplication.invokeLater in a few places where you're already on the UI event thread, so those are redundant - the debug code in keyChar and the setVerticalScroll call from the touchEvent handler. The Runnable is executed synchronously when you do an invokeLater from the UI thread, with no delay specified.
Are you sure you want to set the scroll explicitly? One option would be to set the focus on the WordField you are interested in, by calling setFocus(), then the OS will do the scrolling events to move that field on screen for you.
If you really need to explicitly set the vertical scroll, your problem may be that the touch event is already causing scroll, so setting it again causes problems. You can get around this by specifying a one millisecond delay for your invokeLater(...). This means your Runnable will be added to the event queue, instead of executing synchronously. That way the scroll won't be changed in the middle of another event call-stack.
Finally tracked down the issue - if the touchEvent for the alphabet label field returns a true then it locks up the main scroll field, if however return super.touchEvent(message) is called the scrolling happens and the scroll field can still be scrolled up and down by clicking on the screen.
This may be a bug in the BlackBerry OS or just the simulator. The Field.touchEvent() documentation for 6.0 recommends returning true if the method consumes the event; however doing so (at least in the above code) causes another UI field to loose the ability to detect touch events which would cause it to scroll.

Resources