A status message can be displayed in Blackberry using method show of class net.rim.device.api.ui.component.Status. Using this method you specify a certain amount of time that the message should be displayed but, is there any way to hide this status message BEFORE this time?
I am using this code for displaying status messages in my application:
public static void status(final String message, final int time) {
UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { Status.show(message, time); } });
}
EDIT: Solution that worked for me (thanks to Eugen Martynov solution)
public static void hideStatus() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Screen activeScreen = UiApplication.getUiApplication().getActiveScreen();
if (activeScreen instanceof Status) {
activeScreen.close();
}
}
});
}
According to javadoc there no concrete method to close status.
However you could try to ask UiApplication.getUiApplication().getActiveScreen() and try to call close() of it
Related
I would like to know about Vaadin's detach() method. How can I understand below definition from API ?
Called before the UI is removed from the session.
I got a problem when creating custom listener such as BroadCaster .
MyCustomListener.java
public interface MyCustomListener {
void fireEvent(MyCustomEvent event);
}
MyCustomEvent.java
public class MyCustomEvent {
private String message;
public MyCustomEvent(final String message) {
this.message = message;
}
public final String getMessage() {
return message;
}
}
MyCustomDispatcher.java
public final class MyCustomDispatcher {
private static LinkedList<MyCustomListener> customListeners = new LinkedList<MyCustomListener>();
private static ExecutorService executorService = Executors.newSingleThreadExecutor();
private MyCustomDispatcher() {
}
public static synchronized void register(final MyCustomListener listener) {
customListeners.add(listener);
}
public static synchronized void unregister(final MyCustomListener listener) {
customListeners.remove(listener);
}
public static synchronized void invokeMyCustomEvent(final String message) {
if (message == null || message.trim().length() <= 0) {
return;
}
for (final MyCustomListener listener : customListeners) {
executorService.execute(new Runnable() {
public void run() {
listener.fireEvent(new MyCustomEvent(message));
}
});
}
}
}
I call this listener from my UI class as ...
public class HelloWorldUI extends UI implements MyCustomListener {
#Override
protected void init(VaadinRequest request) {
System.out.println("Getting initialized !");
MyCustomDispatcher.register(this);
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
setSizeFull();
layout.addComponent(new Label("Hello World !"));
}
#Override
public void detach() {
System.out.println("Listener was Unregister !");
MyCustomDispatcher.unregister(this);
super.detach();
}
#Override
public void fireEvent(MyCustomEvent event) {
// Do Something
}
}
I call unregister() method of my custom listener inside detach() method for
from some examples for custom listener
to avoid receiving messages for UIs no longer in use (and ensuring that the detached UI can be garbage collected).
Cleaning up resources in a UI
My problem was due to detach() method because when I refreshed my browser , my listener instance was deleted (from detach() method). So , I can't get fireEvent() anymore. I debugged , detach() method was called after init() method of my UI when refreshing browser. But if I remove calling unregister(MyCustomListener listener) from detach() method , that may cause nesting events (previous listeners were still alive).
What am I wrong ? How can I fix it ? Any suggestions ?
Sorry ! this is stupid question . Vaadin's component were server-side codes and I should avoid using static as I much as I can. When I am using my custom listeners as static-resources , these events were share all others. If someone invokes one event , every users will get same.
Static collection of listeners (sharing events) may only suitable for server-push.
I shouldn't create custom listeners as like this.
Thanks #HenriKerola for explanation of using static fields in vaadin and about the creating new UI instance when browser was refresh.
I am trying to handle an event in BrowserField when the user actually clicks a link.
I studied BrowserFieldListener, tried its documentCreated() method but that gives me a response when the page starts loading. I want a trigger the moment user clicks a link inside browserField.
What am i missing here?
Override handleNavigationRequest() of ProtocolController like
ProtocolController controller = new ProtocolController(browserField) {
public void handleNavigationRequest(BrowserFieldRequest request) throws Exception {
/*
Here you get the redirection link using
request.getURL()
and do what you want to do
*/
// to display url in browserfield use
InputConnection inputConnection = handleResourceRequest(request);
browserField.displayContent(inputConnection, request.getURL());
}
};
browserField.getConfig().setProperty(BrowserFieldConfig.CONTROLLER, controller);
Use the following class that was I used
public class CacheProtocolController extends ProtocolController{
public CacheProtocolController() {
super(browserField);
}
/**
* Handle navigation requests (e.g., link clicks)
*/
public void handleNavigationRequest(final BrowserFieldRequest request) throws Exception {
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
// TODO Auto-generated method stub
Logger.debug("*******URL*******",request.getURL() );
});
}
/**
* Handle resource request (e.g., images, external css/javascript resources)
*/
public InputConnection handleResourceRequest(BrowserFieldRequest request) throws Exception {
return super.handleResourceRequest(request);
}
}
I have solved this problem using the following class:
public class CacheProtocolController extends ProtocolController{
private SparseList sparseList = null;
private int imageIndex ;
private int click = 0;
private BrowserField browserField = null;
public CacheProtocolController(BrowserField browserField,SparseList sparseList,int imageIndex ) {
super(browserField);
this.sparseList = sparseList;
this.imageIndex = imageIndex;
}
/**
* Handle navigation requests (e.g., link clicks)
*/
public void handleNavigationRequest(final BrowserFieldRequest request) throws Exception {
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
Logger.debug("*******URL*******",request.getURL() );
String requestUrl = null;
requestUrl = FileManipulations.replaceAll(request.getURL(), "file:///SDCard/BlackBerry/pictures/", "../");
Logger.debug("*******requestUrl*******",requestUrl );
Enumeration enumeration = sparseList.elements();
while (enumeration.hasMoreElements()) {
final News news = (News) enumeration.nextElement();
if(news.getDetailsURL().equalsIgnoreCase(requestUrl)){
if(click == 1){
click = 0;
UiApplication.getUiApplication().pushScreen(new DetailedNewsScreen(news.getImageURL() , imageIndex));
} else
click++;
}
}
}
});
}
/**
* Handle resource request (e.g., images, external css/javascript resources)
*/
public InputConnection handleResourceRequest(BrowserFieldRequest request) throws Exception {
return super.handleResourceRequest(request);
}
}
And in the MainScren use the following
browserField = new BrowserField();
browserField.getConfig().setProperty(BrowserFieldConfig.CONTROLLER, new CacheProtocolController(browserField,List,index));
I'm trying to popup a global dialog from a background thread that I started from an alternate entry point.
public static void main(String[] args) {
MyApp theApp = new MyApp();
if (args != null && args.length > 0 && args[0].equals("test")) {
new Thread(new Runnable() {
public void run() {
try {
synchronized (UiApplication.getEventLock()) {
UiEngine ui = Ui.getUiEngine();
Screen screen = new Dialog(Dialog.D_OK, "Test", Dialog.OK,
Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),
Manager.VERTICAL_SCROLL);
ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_MODAL);
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
}).start();
} else {
theApp.enterEventDispatcher();
}
}
I tried so many variations to make it work but it's still not showing up. I tried
synchronizing Application.getEventLock(), I also tried
UiApplication.getUiApplication().invokeLater,
UiApplication.getUiApplication().invokeAndWait. I even tried synchronizing the eventlock first before calling the invokeLater (which I think is redundant, but I still tried...). I'm not sure what I'm doing wrong.
okk i am giving you a sample demo ....
First of all edit the BlackBerry_App_Descriptor.xml click on Application Tab
In ApplicationArgument write alternate and check Auto Run on start up
Click on Alternate Entry Points click on add and write in the title BackgroundApp
Make a class which will extend Application class rather than UiApplication class like this way
import net.rim.device.api.system.Alert;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiEngine;
import net.rim.device.api.ui.component.Dialog;
public class BackGroundApp extends Application {
// this class is used for the background processing .....
public void startBackgroundThread()
{
new Thread(){
public void run() {
while (true) {
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (getEventLock()) {
//with this UiEngine pushGlobal dialogs
//whenever with the app in background
UiEngine ui = Ui.getUiEngine();
Screen screen = new Dialog(Dialog.D_OK, "You have updates!",
Dialog.OK, Bitmap
.getPredefinedBitmap(Bitmap.EXCLAMATION),
Manager.VERTICAL_SCROLL);
ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_QUEUE);
}
}
}
}.start();
}
}
Make a class which will extend UiApplication class like this way
public class GuiTest extends UiApplication {
static Timer t;
public static void main(String[] args) {
if(args.length>0&&"alternate".equals(args[0])){
BackGroundApp app = new BackGroundApp();
app.startBackgroundThread();
app.enterEventDispatcher();
}
else{
GuiTest test = new GuiTest();
test.enterEventDispatcher();
}
}
public GuiTest(){
Myscreen screeMyscreen = new Myscreen();
pushScreen(screeMyscreen);
}
}
Now make a class MyScreen and add all your Ui in it .... and push the screen
public class Myscreen extends MainScreen {
public Myscreen(){
CreateGui();
}
public void CreateGui(){
// Your Ui goes here .......
}
}
run the sample you will see after one minute a dialog will appear on your screen no matter if you are in the application or out side of it. Thanks may be this might be help full.
i am new in blackberry developer. i am use a pillsetbutton and pillfieldbutton
but when i am click pillfieldbutton no any action is performed.I am using setchangeListener() method.but no any Action is performed.i am going Through this process.
public DemoPill() {
PillButtonSet objButtonSet=new PillButtonSet();
final PillButtonField objButtonField1=new PillButtonField("NSE");
final PillButtonField objButtonField2=new PillButtonField("BSE");
objButtonSet.add(objButtonField1);
objButtonSet.add(objButtonField2);
this.add(objButtonSet);
bjButtonSet.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
System.out.println("Hi ");
if(field==objButtonField1)
{
System.out.println("This Is NSE Button");
}
else if(field==objButtonField2)
{
System.out.println("This Is BSE Button");
}
}
});
}
}
You are printing it on console. So without debugging the code you will never know if your click is consumed. So just use an event thread to see the output on your screen. I have provided you the sample just check it. It will show the output on your screen. You can also use Dialog.inform(String message ) But its always good to do it on event thread.
public DemoPill() {
PillButtonSet objButtonSet=new PillButtonSet();
final PillButtonField objButtonField1=new PillButtonField("NSE");
final PillButtonField objButtonField2=new PillButtonField("BSE");
objButtonSet.add(objButtonField1);
objButtonSet.add(objButtonField2);
this.add(objButtonSet);
bjButtonSet.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
// System.out.println("Hi ");
if(field==objButtonField1)
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.inform("objButtonField1 button clicked")
}
});
}
else if(field==objButtonField2)
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.inform("objButtonField2 button clicked")
}
});
}
}
});
}
}
May be this will help cheers. :)
You only can view the output of
System.out.println("ANYDATA");
in debug mode not in run.
Try to debug it not to run it.
I have a bitmap field in my blackberry5 app with fieldChanged listener attached to it which works absolutely fine
now my problem is that I also have an associated menu for the same purpose (I can not remove it's the requirement) and on click the menu I get a JVM 104 IllegalStateException
here is my menu class
public class TabMenu extends MenuItem{
MainScreen menuScreen;
Field button;
public TabMenu(String menuLabel,MainScreen menuScreen,Field button)
{
super(menuLabel, 1, 0);
this.menuScreen = menuScreen;
this.button = button;
}//end constructor
public void run()
{
FieldChangeListener listener = (FieldChangeListener)this.menuScreen;
listener.fieldChanged(this.button, this.button.getIndex());
this.button.setFocus();
}
}
and here is menu and fieldchnaged code
protected void makeMenu(Menu menu, int instance) {
menu.add(new RefreshMenu());
menu.addSeparator();
menu.add(new TabMenu("Go >", this, goTab));
menu.addSeparator();
}
public void fieldChanged(Field field, int context) {
if (field == goTab) {
Dialog.alert("goinf")
}
}
Try changing your TabMenu#run() method to the following:
public void run() {
this.button.fieldChangedNotify(this.button.getIndex());
this.button.setFocus();
}