Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
jiggak
Posts: 28
Registered: ‎07-24-2008
My Device: Not Specified

How to block on the event thread?

I am trying to implement a global dialog that prompts the user to make a selection and blocks until a selection has been made.

 

Using the standard Dialog class, this sort of thing works:

 

Application.getApplication().invokeLater(new Runnable() {
public void run() {
if (Dialog.ask(Dialog.D_YES_NO) == Dialog.YES) {
// perform some action
}

// this line is not reached until users makes a selection
}
});

 

 However this causes the UI to stop responding:

 

Application.getApplication().invokeLater(new Runnable() {
public void run() {
MyDialog.ask();

}
});

class MyDialog extends PopupScreen implements FieldChangeListener {
private int choice = 0;
private ButtonField yes, no;

public static int ask() {
MyDialog d = new MyDialog();
d.show();

return d.choice;
}

public MyDialog() {
super(new VerticalFieldManager());

yes = new ButtonField("Yes", ButtonField.CONSUME_CLICK);
yes.setFieldChangeListener(this);

no = new ButtonField("No", ButtonField.CONSUME_CLICK);
no.setFieldChangeListener(this);

add(yes);
add(no);
}

public synchronized void show() {
UiApplication.getUiApplication().pushGlobalScreen(this, 0, true);
try { wait(); }

catch (InterruptedException e) { }

}

public void fieldChanged(Field field, int context) {
choice = field == yes? 1 : 2;
UiApplication.getUiApplication.dismissStatus(this);
synchronized (this) { notify(); }
}
}

 

Is there any way I can make this work?

 

 

Please use plain text.
Developer
marchywka
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: How to block on the event thread?

So who is it you expect to respond once you call wait() from the ui thread?

I guess you could call invokeandwait, or whatever it is exactly, or just

call invokelater from your thread and have YOUR thread wait() on something that

gets notified from the field change listener.

 

Please use plain text.
Developer
jiggak
Posts: 28
Registered: ‎07-24-2008
My Device: Not Specified

Re: How to block on the event thread?

Yes I'm certainly not surprised that my implementation doesn't work.

 

I'm just curious if there is a way to mimick the functionality of a modal dialog without using UiApplication.pushModalScreen().

 

Calling MyDialog.ask() from a non-event thread, and using invokeLater to push the screen will work.  However, I was hoping for a way to use this dialog in exactly the same way as the builtin Dialog class is used.

Please use plain text.
Developer
marchywka
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: How to block on the event thread?

You WANT to have to put invoke calls everywhere in your code? Why not just make a ctor or factory that takes

a UIApplication and bury all the waiting stuff in your new classe?

 

Please use plain text.
Developer
peter_strange
Posts: 19,609
Registered: ‎07-14-2008
My Device: Not Specified

Re: How to block on the event thread?

Does DialogClosedListener help?
Please use plain text.
Developer
jiggak
Posts: 28
Registered: ‎07-24-2008
My Device: Not Specified

Re: How to block on the event thread?

Well, if this was a question about practicality then this would work:

 

 

new Thread(new Runnable() { public void run() { MyDialog.ask(); } }).start(); class MyDialog extends PopupScreen implements FieldChangeListener { private int choice = 0; private ButtonField yes, no; public static int ask() { if (UiApplication.isEventDispatchThread()) throw new IllegalStateException("Must use MyDialog from non-event thread"); MyDialog d = new MyDialog(); d.show(); return d.choice; } public MyDialog() { super(new VerticalFieldManager()); yes = new ButtonField("Yes", ButtonField.CONSUME_CLICK); yes.setFieldChangeListener(this); no = new ButtonField("No", ButtonField.CONSUME_CLICK); no.setFieldChangeListener(this); add(yes); add(no); } public synchronized void show() { UiApplication.getUiApplication().pushGlobalScreen(this, 0, true); try { wait(); } catch (InterruptedException e) { } } public void fieldChanged(Field field, int context) { choice = field == yes? 1 : 2; UiApplication.getUiApplication.dismissStatus(this); synchronized (this) { notify(); } } }

 

For now this is what I've had to do to make it work.

 

But I was just curious how the builtin Dialog class got away with blocking on the event thread.

 

Please use plain text.
Developer
jiggak
Posts: 28
Registered: ‎07-24-2008
My Device: Not Specified

Re: How to block on the event thread?

Hi Peter,

 

I could use a callback, but I like the static blocking method.  This way I can have a sequence of prompts one after the other without having to chain them in the callback method implementations.

Please use plain text.