However, that's not code that you should use in production, because you're calling gui.openDialog() on a worker thread, which opens up a slew of multi-threading issues. UI methods are meant to be called on the EDT and provide no synchronization constructs.
-T On Tue, Jan 26, 2010 at 2:32 PM, Andreas Siegrist <[email protected]>wrote: > 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----- > >> > > > >
