pivot-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Todd Volkert <tvolk...@gmail.com>
Subject Re: Blocking while a dialog/prompt/alert/sheet is open, like Javascript's alert() ?
Date Tue, 26 Jan 2010 19:42:44 GMT
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
<andreas.siegrist@me.com>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 <
> andreas.siegrist@me.com<mailto:andreas.siegrist@me.com>> 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 <bob.santosjr@gmail.com<mailto:
> bob.santosjr@gmail.com>>
> >>>>>>>>>>> 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
<gkbrown@mac.com
> <mailto:gkbrown@mac.com>> 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-----
> >>
> >
>
>

Mime
View raw message