I was just thinking of how to achieve the simple task to get a javascript like
alert(), where the business logic stops until the user closes the alert.
And here is was I'm suggesting and this works:
import java.util.concurrent.Semaphore;
import org.apache.pivot.wtk.Dialog;
import org.apache.pivot.wtk.DialogStateListener;
public class Model implements Runnable {
private static App gui;
private Model() {}
@Override
public void run() {
// The business logic
BlockingNotifier.alert("Wait, I've stopped the business logic");
System.out.println("ok now I run again");
BlockingNotifier.alert("bye");
}
public static void start(App app) {
gui = app;
new Thread(new Model()).start();
}
private static class BlockingNotifier {
private static Semaphore lock = new Semaphore(0);
public static void alert(String txt) {
DialogStateListener listener = new
DialogStateListener.Adapter() {
@Override
public void dialogClosed(Dialog arg0, boolean
arg1) {
lock.release();
}
};
gui.openDialog(txt, listener);
try {
lock.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
import org.apache.pivot.collections.Map;
import org.apache.pivot.wtk.*;
public class App implements Application {
private BoxPane content = new BoxPane();
Frame frame = new Frame();
@Override
public void resume() throws Exception {}
@Override
public boolean shutdown(boolean arg0) throws Exception {
return false;
}
@Override
public void startup(Display arg0, Map<String, String> arg1)
throws Exception {
frame.open(arg0);
frame.setContent(content);
Model.start(this);
}
@Override
public void suspend() throws Exception {}
public static void main(String[] args) {
DesktopApplicationContext.main(App.class, args);
}
public void openDialog(String txt, DialogStateListener listener) {
Dialog dialog = new Dialog();
dialog.setContent(new Label(txt));
dialog.open(frame);
dialog.getDialogStateListeners().add(listener);
}
}
On Jan 26, 2010, at 7:45 PM, Greg Brown wrote:
> I'm not sure exactly what you are suggesting here. All UI-related operations
> must occur on the EDT. This includes model updates as well as business logic.
>
> You can execute any task in the background, but you must always notify the UI
> by calling ApplicationContext.queueCallback(). You shouldn't ever call into
> the UI directly from another thread.
>
>
> On Jan 26, 2010, at 1:00 PM, Andreas Siegrist wrote:
>
>> It's impossible.
>> So you should keep the gui and your model+logic in seperate threads.
>> It's the only way to do the thing you want.
>>
>> On Jan 26, 2010, at 6:50 PM, Clint Gilbert wrote:
>>
>>> -----BEGIN PGP SIGNED MESSAGE-----
>>> Hash: SHA1
>>>
>>>
>>> Yeah, that's the behavior I saw when I tried a solution like Andreas's
>>> using a CountDownLatch or a Lock/Condition pair. :(
>>>
>>> Todd Volkert wrote:
>>>> But the dialog is opened on the EDT, meaning that you'll lock up the UI
>>>> thread, and the UI will appear to hang.
>>>>
>>>> -T
>>>>
>>>> On Tue, Jan 26, 2010 at 12:43 PM, Andreas Siegrist
>>>> <[email protected]<mailto:[email protected]>> wrote:
>>>> I'm sorry I think I've misunderstood your questions.
>>>> So if you want to do that:
>>>> new Dialog("ajsdfoj");
>>>> System.out.println("I'm 100% sure that the Dialog is closed now!");
>>>>
>>>> try it with this class:
>>>>
>>>> import java.util.concurrent.Semaphore;
>>>>
>>>> import org.apache.pivot.wtk.Dialog;
>>>> import org.apache.pivot.wtk.DialogCloseListener;
>>>> import org.apache.pivot.wtk.Display;
>>>> import org.apache.pivot.wtk.Window;
>>>>
>>>> public class BlockingDialog extends Dialog {
>>>> static Semaphore lock = new Semaphore(0);
>>>>
>>>> public void open(Display display, Window owner, boolean modal) {
>>>> DialogCloseListener closeListener = new
>>>> DialogCloseListener() {
>>>> @Override
>>>> public void dialogClosed(Dialog arg0, boolean
>>>> arg1) {
>>>> lock.release();
>>>> }
>>>> };
>>>> open(display, owner, modal, closeListener);
>>>>
>>>> try {
>>>> lock.acquire();
>>>> } catch (InterruptedException e) {
>>>> e.printStackTrace();
>>>> }
>>>> }
>>>> }
>>>>
>>>>
>>>> On Jan 26, 2010, at 6:13 PM, Clint Gilbert wrote:
>>>>
>>>> Thanks very much, I'll try this out later. I tried similar strategies
>>>> with different util.concurrent primitives, but never with a Semaphore in
>>>> this way.
>>>>
>>>> Andreas Siegrist wrote:
>>>>>>> like that:
>>>>>>>
>>>>>>> import java.util.concurrent.Semaphore;
>>>>>>>
>>>>>>> import org.apache.pivot.wtk.Dialog;
>>>>>>> import org.apache.pivot.wtk.DialogCloseListener;
>>>>>>> import org.apache.pivot.wtk.Display;
>>>>>>> import org.apache.pivot.wtk.Window;
>>>>>>>
>>>>>>> public class DialogProxy extends Dialog {
>>>>>>> static Semaphore lock = new Semaphore(1);
>>>>>>>
>>>>>>> public void open(Display display, Window owner, boolean modal) {
>>>>>>> try {
>>>>>>> lock.acquire();
>>>>>>> DialogCloseListener closeListener = new
>>>>>>> DialogCloseListener() {
>>>>>>> @Override
>>>>>>> public void dialogClosed(Dialog arg0, boolean
>>>>>>> arg1) {
>>>>>>> lock.release();
>>>>>>> }
>>>>>>> };
>>>>>>> open(display, owner, modal, closeListener);
>>>>>>>
>>>>>>> } catch (InterruptedException e) {
>>>>>>> e.printStackTrace();
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> On Jan 26, 2010, at 5:51 PM, Clint Gilbert wrote:
>>>>>>>
>>>>>>> Could you elaborate on this please?
>>>>>>>
>>>>>>> Andreas Siegrist wrote:
>>>>>>>>>> Hi there
>>>>>>>>>>
>>>>>>>>>> I also did something like that
>>>>>>>>>> All I needed to do is making a Proxy class with a synchronized
>>>>>>>>>> method.
>>>>>>>>>>
>>>>>>>>>> Andreas
>>>>>>>>>>
>>>>>>>>>> On Jan 26, 2010, at 3:06 PM, Christopher Brind wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Bob,
>>>>>>>>>>>
>>>>>>>>>>> This isn't really about being modal, but about stopping the flow of
>>>>>>>>>>> execution. For example, in Javascript:
>>>>>>>>>>>
>>>>>>>>>>> Alert.show("hello");
>>>>>>>>>>> Alert.show("world");
>>>>>>>>>>>
>>>>>>>>>>> The second alert doesn't appear until you press OK on the first.
>>>>>>>>>>>
>>>>>>>>>>> In Pivot or Swing (and every other UI framework?) if you popup an
>>>>>>>>>>> Alert processing continues, for instance in Flex:
>>>>>>>>>>>
>>>>>>>>>>> Alert.show("hello");
>>>>>>>>>>> Alert.show("world");
>>>>>>>>>>>
>>>>>>>>>>> The second alert appears immediately and on top of the previous one.
>>>>>>>>>>>
>>>>>>>>>>> Clint wants to achieve the first scenario, but this is not possible
>>>>>>>>>>> with Pivot.
>>>>>>>>>>>
>>>>>>>>>>> Cheers,
>>>>>>>>>>> Chris
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 2010/1/26 Bob Santos
>>>>>>>>>>> <[email protected]<mailto:[email protected]>>
>>>>>>>>>>> If I'm not mistaken, in Swing, you can create confirm
>>>>>>>>>>> dialogs(Yes/No), message dialogs or option dialogs by using
>>>>>>>>>>> JOptionPane and also I think they are by default modal(?), which
>>>>>>>>>>> means access to other part of the application is not allowed until
>>>>>>>>>>> interaction with the active dialog is done.
>>>>>>>>>>>
>>>>>>>>>>> You can also create your custom dialog by extending Dialog and
>>>>>>>>>>> specifying the modality.
>>>>>>>>>>>
>>>>>>>>>>> And yes it helps to know that everything you want to do with the UI
>>>>>>>>>>> should be done within the EDT as Greg stated.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Tue, Jan 26, 2010 at 9:40 PM, Greg Brown
>>>>>>>>>>> <[email protected]<mailto:[email protected]>> wrote:
>>>>>>>>>>> Hi Clint,
>>>>>>>>>>>
>>>>>>>>>>>> Now, my question: Is it possible to achieve behavior like the
>>>>>>>>>>>> Javascript's alert() function with Pivot? That is, I'd like to
>>>>>>>>>>>> put up a
>>>>>>>>>>>> simple yes/no "do something"/"please don't" popup on the screen,
>>>>>>>>>>>> and
>>>>>>>>>>>> have the app block - the alert doesn't just block input to other
>>>>>>>>>>>> elements - until the user chooses an option, or closes the popup.
>>>>>>>>>>>> This
>>>>>>>>>>>> is possible in SWT, I don't know about Swing.
>>>>>>>>>>> Sorry, it is not possible - as you noted, Window#open() is not a
>>>>>>>>>>> blocking call in WTK. Pivot is ultimately based on AWT, which uses
>>>>>>>>>>> a push model for event notifications (vs. pull). If you were to
>>>>>>>>>>> call a blocking method from a user input event such as a button
>>>>>>>>>>> press, no further event processing could occur until that method
>>>>>>>>>>> had returned, and the entire UI would appear to freeze.
>>>>>>>>>>>
>>>>>>>>>>> I personally don't mind the anonymous inner class syntax:
>>>>>>>>>>>
>>>>>>>>>>> dialog.open(owner, new DialogCloseListener() {
>>>>>>>>>>> @Override
>>>>>>>>>>> public void dialogClosed(Dialog dialog, boolean modal) {
>>>>>>>>>>> // Get selected option and act on it
>>>>>>>>>>> }
>>>>>>>>>>> });
>>>>>>>>>>>
>>>>>>>>>>> I actually think this reflects a pretty consistent design - you
>>>>>>>>>>> open the dialog in response to one event (e.g. "button pressed"),
>>>>>>>>>>> and you handle the dialog's result in response to another event
>>>>>>>>>>> (e.g. "dialog closed").
>>>>>>>>>>>
>>>>>>>>>>>> Making the call to Dialog.open() from another thread doesn't have
>>>>>>>>>>>> any effect.
>>>>>>>>>>> Note that, as in Swing, multi-threaded access to UI elements is not
>>>>>>>>>>> supported. All UI operations must be performed on the EDT.
>>>>>>>>>>>
>>>>>>>>>>> Hope this helps,
>>>>>>>>>>> Greg
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>> -----BEGIN PGP SIGNATURE-----
>>> Version: GnuPG v1.4.9 (GNU/Linux)
>>> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>>>
>>> iEYEARECAAYFAktfK0oACgkQ5IyIbnMUeTuAqQCeOW6N30B02+lbxrC1NZPTeabs
>>> d1UAn3kkJ8ihtRhF+8Q6Tl4G9N0diW9m
>>> =p74V
>>> -----END PGP SIGNATURE-----
>>
>