Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I detect that a SWT dialog has been opened and is visible?

I have an SWT WizardDialog with a number of pages. When this dialog first opens I have to do a check for some conditions and if those conditions are met I need to show a popup over the freshly opened dialog.

So I have this code to listen for SWT.Show event. The event listener responds to SWT.Show to conduct its tests and show a message box:

  final WizardDialog dialog = new WizardDialog(shell, wizard);
  dialog.setTitle("New Wizard");
  dialog.create();
  dialog.getShell().addListener(SWT.Show, new Listener()
  {
     private boolean firstShowing = true;

     @Override
     public void handleEvent(Event event)
     {
        if (firstShowing && someConditionExists())
        {
          MessageBox messageBox = new MessageBox(dialog.getShell(), SWT.OK
                 | SWT.ICON_WARNING);
          messageBox.setMessage("Test");
          messageBox.open();
          firstShowing = false;
        }
     }
  });
  dialog.open();

Except it's called too soon! The dialog is not visible when the handler is called. My message box appears before the dialog is visible and the dialog only appears when I dismiss the message box.

So clearly the SWT.Show is unreliable, at least on Windows where I'm running it. I've also tried putting this code into a ShellListener on the activation but that happens even before the SWT.Show example above.

So how do I reliably show a message box when the dialog is made visible?

Plan B is a dirty timer based hack where a timer is set to fire 200 ms into the future and hope that it triggers when the dialog is visible but obviously this could introduce it's own issues.

like image 423
locka Avatar asked Sep 12 '11 12:09

locka


2 Answers

I'm using in similar situation (need that appStarted() is called after application window is visible) something like below.

public class App extends ApplicationWindow {

    @Override
    protected Control createContents(Composite parent) {
        // ...

        getShell().addShellListener(new ShellAdapter() {

            @Override
            public void shellActivated(ShellEvent shellevent) {
                if (!started) {
                    Shell s = (Shell) shellevent.getSource();
                    s.setVisible(true);
                    appStarted();
                    started = true;
                }
            }
        });
    }
}

Maybe You can use the same like below:

final WizardDialog dialog = new WizardDialog(shell, wizard);
dialog.setTitle("New Wizard");
dialog.create();
dialog.getShell().addShellListener(new ShellAdapter() {

    @Override
    public void shellActivated(ShellEvent shellevent) {

        if (firstShowing && someConditionExists()) {
            Shell s = (Shell) shellevent.getSource();
            s.setVisible(true);

            MessageBox messageBox = new MessageBox(dialog.getShell(), SWT.OK | SWT.ICON_WARNING);
            messageBox.setMessage("Test");
            messageBox.open();
            firstShowing = false;
        }

    }
});
dialog.open();
like image 86
marioosh Avatar answered Oct 16 '22 19:10

marioosh


Instead of hooking the SWT.Show event, you may get more luck with hooking a PaintListener on to your dialog's Composite. (You'll probably want to unhook it during the first execution.)

like image 25
Edward Thomson Avatar answered Oct 16 '22 20:10

Edward Thomson