11-04-2010 10:22 AM
Hi,
My Specs are:
- Eclipse IDE build 20100218-1602
- BlackBerry Java Plugin Version: 1.1.2.201004161203-16
- BlackBerry Java SDK Version: 5.0.0.25
I have a BrowserField2 that loads a specific page. While it loads I have 'Please Wait' Popup but it goes away alot sooner ending up with a Blank screen until the page loads. This can confuse the users.
I want the Popup to stay until the page has loaded 100%.
What am I doing wrong?
Heres part of my code:
protected void onUiEngineAttached(boolean attached)
{
if(attached)
{
try
{
//Instantiate Web Content Request
GetWebContent getRequest = new GetWebContent(_browserField, _request);
//Pass background process and waiting message
PleaseWaitPopupScreen.showScreenAndWait(getRequest, _res.getString(LOADING_NEWS));
}
catch(Exception e)
{
deleteAll();
add(new LabelField("ERROR:\n\n"));
add(new LabelField(e.getMessage()));
}
}
}
public class GetWebContent implements Runnable
{
public GetWebContent(BrowserField _browserField, BrowserFieldRequest _request){
//constructor
}
public void run(){
//Get the Web Content for the BrowserField
_browserField.requestContent(_request);
}
}
Here's some more:
public static void showScreenAndWait(final Runnable runThis, String wait_message) {
final PleaseWaitPopupScreen thisScreen = new PleaseWaitPopupScreen(wait_message);
Thread threadToRun = new Thread() {
public void run() {
// First, display this screen
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(thisSc reen);
}
});
// Now run the code that must be executed in the Background
try
{
runThis.run();
} catch (Throwable t)
{
t.printStackTrace();
throw new RuntimeException("Exception detected while waiting: " + t.toString());
}
// Now dismiss this screen
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(thisScr een);
}
});
}
};
threadToRun.start();
}
Please help!
Solved! Go to Solution.
11-04-2010 10:38 AM
i think requestContent is not a blocking operation, therefor returning before the action was finished.
you can use a http://www.blackberry.com/developers/docs/6.0.0api
11-04-2010 10:44 AM
Hi thanks alot for the response.
Can you please give me a more specific example?
I've looked into that Listener but due to lack of knowledge on Java and BlackBerry dev I failed to set it up.
Here's how the Screen is setup:
private BrowserField _browserField;
private boolean _documentLoaded = false;
private BrowserFieldRequest _request;
/**
* Creates a new BrowserFieldScreen object
* @param request The URI of the content to display in this BrowserFieldScreen
* @param enableScriptMenu True if a context menu is to be created for this BrowserFieldScreen instance, false otherwise
*/
public WebNewsScreen(BrowserFieldRequest request, boolean enableScriptMenu)
{
super("WebNewsScreen", true); //construct
this.setTitle(_res.getString(SCREEN_NEWS_TITLE)); //Set the Screen Title
addKeyListener(new BrowserFieldScreenKeyListener());
BrowserFieldConfig config = new BrowserFieldConfig();
config.setProperty(BrowserFieldConfig.ALLOW_CS_XHR, Boolean.TRUE);
_browserField = new BrowserField(config);
_browserField.addListener(new InnerBrowserListener());
add(_browserField);
/*custom webpage resizing
CustomManager manager = new CustomManager();
manager.add(_browserField);
add(manager);
*/
_request = request;
}
Thanks for your help!
11-04-2010 10:50 AM
you add the listener to the browserfield in your code.
all you have to do now is to move the control of the popup screen into the listener methods.
i would guess that aborted, error etc all undisplay the popup, same as documentLoaded.
by using
http://www.blackberry.com/developers/docs/6.0.0api
you can also display a progress if you want to.
11-04-2010 10:51 AM
I'll give it a try thanks!
11-04-2010 11:42 AM
Hi,
Im having trouble moving the controls of the PopupScreen into the listener because the popup screen 'thisScreen' is final (created in public static void showScreenAndWait()).
Can you please help me out? Here's the two screens to give you a better idea of my problem.
WebNewsScreen.java
/*
* WebNewsScreen.java
*
* Copyright © 1998-2010 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.fxpro.screens;
import org.w3c.dom.*;
import org.w3c.dom.events.*;
import com.fxpro.FxProApp;
import com.fxpro.pleasewait.PleaseWaitPopupScreen;
import net.rim.device.api.script.*;
import net.rim.device.api.browser.field2.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.system.*;
/**
* The MainScreen class for the Browser Field 2 Demo application
*/
public class WebNewsScreen extends TitleScreen
{
private BrowserField _browserField;
private boolean _documentLoaded = false;
private BrowserFieldRequest _request;
/**
* Creates a new BrowserFieldScreen object
* @param request The URI of the content to display in this BrowserFieldScreen
* @param enableScriptMenu True if a context menu is to be created for this BrowserFieldScreen instance, false otherwise
*/
public WebNewsScreen(BrowserFieldRequest request, boolean enableScriptMenu)
{
super("WebNewsScreen", true); //construct
this.setTitle(_res.getString(SCREEN_NEWS_TITLE)); //Set the Screen Title
addKeyListener(new BrowserFieldScreenKeyListener());
BrowserFieldConfig config = new BrowserFieldConfig();
config.setProperty(BrowserFieldConfig.ALLOW_CS_XHR, Boolean.TRUE);
_browserField = new BrowserField(config);
_browserField.addListener(new InnerBrowserListener());
//Listener to monitor when the page Loads
BrowserFieldListener listener = new BrowserFieldListener() {
public void documentLoaded(BrowserField browserField, Document document) throws Exception
{
if ((browserField != null) && (document != null))
{
}
super.documentLoaded(browserField, document);
}
};
_browserField.addListener( listener );
add(_browserField);
/*custom web page resizing
CustomManager manager = new CustomManager();
manager.add(_browserField);
add(manager);
*/
_request = request;
}
/**
* @see Screen#onUiEngineAttached(boolean)
*/
protected void onUiEngineAttached(boolean attached)
{
if(attached)
{
try
{
//Instantiate Web Content Request
GetWebContent getRequest = new GetWebContent(_browserField, _request);
//Pass background process and waiting message
PleaseWaitPopupScreen.showScreenAndWait(getRequest, _res.getString(LOADING_NEWS));
}
catch(Exception e)
{
deleteAll();
add(new LabelField("ERROR:\n\n"));
add(new LabelField(e.getMessage()));
}
}
}
public class GetWebContent implements Runnable
{
public GetWebContent(BrowserField _browserField, BrowserFieldRequest _request){
//constructor
}
public void run(){
//Get the Web Content for the BrowserField
_browserField.requestContent(_request);
}
}
/**
* @see MainScreen#onSavePrompt()
*/
public boolean onSavePrompt()
{
// Prevent the save dialog from being displayed
return true;
}
/**
* Returns this screen's BrowserField object
* @return This screen's BrowserField object
*/
public BrowserField getBrowserField()
{
return _browserField;
}
/**
* @see MainScreen#makeMenu(Menu, int)
*/
public void makeMenu(Menu menu, int instance)
{
super.makeMenu(menu, instance);
if(_documentLoaded && _browserField.getDocumentUrl().equals("local:///index.html"))
{
try
{
Scriptable contextMenuItems = (Scriptable) _browserField.getScriptEngine().executeScript("makeContextMenu()", null);
if(contextMenuItems != null)
{
MenuItem defaultItem = null;
Integer length = (Integer) contextMenuItems.getField("length");
for(int i = 0; i < length.intValue(); i++)
{
Scriptable menuItem = (Scriptable)contextMenuItems.getElement(i);
if(menuItem != null)
{
String label = (String)menuItem.getField("label");
Object action = menuItem.getField("action");
MenuItem item = null;
if(action instanceof String)
{
item = new ScriptableMenuItem(label, new SimpleScriptableFunction((String)action));
}
else if(action instanceof ScriptableFunction)
{
item = new ScriptableMenuItem(label, (ScriptableFunction)action);
}
if(item != null)
{
menu.add(item);
Object isDefault = menuItem.getField("defaultItem");
if(isDefault != null && Scriptable.UNDEFINED.equals(isDefault) == false
&& ((Boolean) isDefault).booleanValue())
{
defaultItem = item;
}
}
}
}
if(defaultItem != null)
{
menu.setDefault(defaultItem);
}
}
}
catch(Exception e)
{
FxProApp.errorDialog("Error calling javascript script makeContextMenu().." + e.getMessage(), false);
}
}
}
/**
* A class to listen for BrowserField events
*/
private class InnerBrowserListener extends BrowserFieldListener
{
/**
* @see BrowserFieldListener#documentCreated(BrowserField, ScriptEngine, Document)
*/
public void documentCreated(BrowserField browserField, ScriptEngine scriptEngine, Document document) throws Exception
{
((EventTarget) document).addEventListener("load", new EventListener()
{
public void handleEvent(Event evt)
{
_documentLoaded = true;
}
}, false);
}
}
/**
* A MenuItem class used to launch various scriptable functions
*/
private static class ScriptableMenuItem extends MenuItem
{
ScriptableFunction _function;
/**
* Creates a new ScriptableMenuItem object
* @param label The label for this MenuItem
* @param function The ScriptableFunction to be executed by this MenuItem
*/
public ScriptableMenuItem(String label, ScriptableFunction function)
{
super(label, 0, 0);
_function = function;
}
public void run()
{
if(Application.isEventDispatchThread())
{
new Thread(this).start();
}
else
{
try
{
_function.invoke(null, null);
}
catch(Exception e)
{
FxProApp.errorDialog("Error invoking ScriptableFunction: " + e.getMessage(), false);
}
}
}
}
/**
* A class representing a function in the script environment
*/
private class SimpleScriptableFunction extends ScriptableFunction
{
String _action;
/**
* Creates a new SimpleScriptableFunction object
* @param action The action to be executed by this ScriptableFunction
*/
public SimpleScriptableFunction(String action)
{
_action = action;
}
/**
* @see ScriptableFunction#invoke(Object, Object[])
*/
public Object invoke(Object thiz, Object[] args) throws Exception
{
_browserField.getScriptEngine().executeScript(_action, null);
return UNDEFINED;
}
}
/**
* A KeyListener implementation
*/
private class BrowserFieldScreenKeyListener implements KeyListener
{
/**
* @see KeyListener#keyChar(char, int, int)
*/
public boolean keyChar(final char key, int status, int time)
{
if(key == 'n')
{
Runnable nextRunnable = new Runnable()
{
public void run()
{
try
{
BrowserFieldHistory browserFieldHistory = getBrowserField().getHistory();
if(browserFieldHistory.canGoForward())
{
browserFieldHistory.goForward();
}
}
catch(Exception e)
{
System.out.println("Error executing js:next(): " + e.getMessage());
}
}
};
new Thread(nextRunnable).start();
return true;
}
else if(key == 'p' || key == Characters.ESCAPE)
{
Runnable previousRunnable = new Runnable()
{
public void run()
{
try
{
BrowserFieldHistory browserFieldHistory = getBrowserField().getHistory();
if(browserFieldHistory.canGoBack())
{
browserFieldHistory.goBack();
}
else
{
if(key == Characters.ESCAPE)
{
synchronized(Application.getEventLock())
{
close();
}
}
}
}
catch(Exception e)
{
System.out.println("Error executing js:previous(): " + e.getMessage());
}
}
};
new Thread(previousRunnable).start();
return true;
}
else if(key == Characters.ENTER)
{
Runnable submitRunnable = new Runnable()
{
public void run()
{
try
{
getBrowserField().getScriptEngine().executeScript("submitSearch()", null);
}
catch(final Exception e)
{
System.out.println("Error executing js:submitSearch(): " + e.getMessage());
}
}
};
new Thread(submitRunnable).start();
return true;
}
return false;
}
/**
* @see KeyListener#keyDown(int, int)
*/
public boolean keyDown(int keycode, int time)
{
return false;
}
/**
* @see KeyListener#keyRepeat(int, int)
*/
public boolean keyRepeat(int keycode, int time)
{
return false;
}
/**
* @see KeyListener#keyStatus(int, int)
*/
public boolean keyStatus(int keycode, int time)
{
return false;
}
/**
* @see KeyListener#keyUp(int, int)
*/
public boolean keyUp(int keycode, int time)
{
return false;
}
}
/*
* Customize the size of the BrowserScreen
*/
/*final class CustomManager extends VerticalFieldManager {
CustomManager() {
super(Manager.VERTICAL_SCROLL |Manager.VERTICAL_SCROLLBAR);
}
public void sublayout(int maxWidth, int maxHeight) {
super.sublayout(50, 50);
}
}*/
}
PleaseWaitPopupScreen.java
package com.fxpro.pleasewait;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.system.GIFEncodedImage;
import net.rim.device.api.ui.Field;
import java.lang.Throwable;
import java.lang.RuntimeException;
public class PleaseWaitPopupScreen extends PopupScreen {
//statics ------------------------------------------------------------------
private AnimatedGIFField _ourAnimation = null;
private LabelField _ourLabelField = null;
private PleaseWaitPopupScreen(String text) {
super(new VerticalFieldManager(VerticalFieldManager.VERTICAL_SCROLL | VerticalFieldManager.VERTICAL_SCROLLBAR));
GIFEncodedImage ourAnimation = (GIFEncodedImage) GIFEncodedImage.getEncodedImageResource("cycle.agif");
_ourAnimation = new AnimatedGIFField(ourAnimation, Field.FIELD_HCENTER);
this.add(_ourAnimation);
_ourLabelField = new LabelField(text, Field.FIELD_HCENTER);
this.add(_ourLabelField);
}
public static void showScreenAndWait(final Runnable runThis, String wait_message) {
final PleaseWaitPopupScreen thisScreen = new PleaseWaitPopupScreen(wait_message);
Thread threadToRun = new Thread() {
public void run() {
// First, display this screen
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(thisScreen);
}
});
// Now run the code that must be executed in the Background
try
{
runThis.run();
} catch (Throwable t)
{
t.printStackTrace();
throw new RuntimeException("Exception detected while waiting: " + t.toString());
}
// Now dismiss this screen
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(thisScreen);
}
});
}
};
threadToRun.start();
}
}
11-04-2010 12:42 PM
11-05-2010 03:11 AM
Worked like a charm! Thank you so much for your support!
Basically I moved the instantiation of the popup screen to the WebNewsScreen on Class Level so that I could pop it on the Listener.
Here's part of the code for future reference:
WebNewsScreen.java
private BrowserField _browserField;
private boolean _documentLoaded = false;
private BrowserFieldRequest _request;
//Instantiate the Waiting Screen
final PleaseWaitPopupScreen waitScreen = new PleaseWaitPopupScreen(_res.getString(LOADING_NEWS) );
/**
* Creates a new BrowserFieldScreen object
* @param request The URI of the content to display in this BrowserFieldScreen
* @param enableScriptMenu True if a context menu is to be created for this BrowserFieldScreen instance, false otherwise
*/
public WebNewsScreen(BrowserFieldRequest request, boolean enableScriptMenu)
{
super("WebNewsScreen", true); //construct
this.setTitle(_res.getString(SCREEN_NEWS_TITLE)); //Set the Screen Title
addKeyListener(new BrowserFieldScreenKeyListener());
BrowserFieldConfig config = new BrowserFieldConfig();
config.setProperty(BrowserFieldConfig.ALLOW_CS_XHR , Boolean.TRUE);
_browserField = new BrowserField(config);
_browserField.addListener(new InnerBrowserListener());
//Listener to monitor when the page Loads
BrowserFieldListener listener = new BrowserFieldListener() {
public void documentLoaded(BrowserField browserField, Document document) throws Exception
{
if ((browserField != null) && (document != null))
{
//Pop the Waiting Screen when the page has loaded
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(waitScr een);
}
});
}
super.documentLoaded(browserField, document);
}
};
_browserField.addListener( listener );
add(_browserField);
/*custom web page resizing
CustomManager manager = new CustomManager();
manager.add(_browserField);
add(manager);
*/
_request = request;
}
/**
* @see Screen#onUiEngineAttached(boolean)
*/
protected void onUiEngineAttached(boolean attached)
{
if(attached)
{
try
{
//Instantiate Web Content Request
GetWebContent getRequest = new GetWebContent(_browserField, _request);
//Pass background process and waiting screen
PleaseWaitPopupScreen.showScreenAndWait(getRequest , waitScreen);
}
catch(Exception e)
{
deleteAll();
add(new LabelField("ERROR:\n\n"));
add(new LabelField(e.getMessage()));
}
}
}
public class GetWebContent implements Runnable
{
public GetWebContent(BrowserField _browserField, BrowserFieldRequest _request){
//constructor
}
public void run(){
//Get the Web Content for the BrowserField
_browserField.requestContent(_request);
}
}
11-05-2010 08:01 AM
Hi,
by declaring the popupscreen on the classlevel to make it known to the listener, I now face another problem... :-(
I now tried to add the cancel button as per the example I follow:
I cannot see how to add the Cancel button as it uses the pupupscreen object to pass the process to be cancelled.
Help!!!