Как определить, что диалоговое окно SWT открыто и является видимым? - PullRequest
3 голосов
/ 12 сентября 2011

У меня есть SWT WizardDialog с несколькими страницами. Когда этот диалог открывается впервые, я должен проверить некоторые условия, и если эти условия соблюдены, мне нужно показать всплывающее окно поверх только что открытого диалога.

Итак, у меня есть этот код для прослушивания события SWT.Show. Слушатель событий отвечает на SWT.Show, чтобы провести его тесты и показать окно сообщения:

  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();

За исключением того, что он называется слишком рано! Диалог не виден, когда вызывается обработчик. Мое окно сообщения появляется до того, как диалоговое окно становится видимым, и диалоговое окно появляется только тогда, когда я закрываю окно сообщения.

Очевидно, что SWT.Show ненадежен, по крайней мере, в Windows, где я его запускаю. Я также попытался поместить этот код в ShellListener при активации, но это происходит еще до примера SWT.Show выше.

Так как мне надежно отобразить окно сообщения, когда диалог становится видимым?

План B - это хак на основе грязного таймера, когда таймер настроен на запуск 200 мс в будущем и надеется, что он сработает, когда диалоговое окно станет видимым, но, очевидно, это может создать свои собственные проблемы.

Ответы [ 5 ]

4 голосов
/ 16 августа 2012

Я использую в аналогичной ситуации (нужно, чтобы appStarted() вызывалось после того, как окно приложения стало видимым), что-то вроде ниже.

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;
                }
            }
        });
    }
}

Возможно Вы можете использовать то же, что и ниже:

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();
2 голосов
/ 12 сентября 2011

Вместо того, чтобы подключить событие SWT.Show, вы можете получить больше удачи, подключив PaintListener к диалоговому окну Composite. (Возможно, вы захотите отсоединить его во время первого выполнения.)

1 голос
/ 10 сентября 2015

Я знаю, что это старая тема. Но в случае, если кто-то сочтет это полезным, я обнаружил, что переопределение Dialog.create (), а не Dialog.open () работает для меня.

1 голос
/ 12 сентября 2011

Как насчет переопределения dialog.open() метода в вашем WizardDialog классе? Первая строка переопределенного метода вызовет super.open(), что сделает его видимым. Просто поместите свой код после этого в методе .open().

Проблема с подходом, который вы используете выше, по-видимому, заключается в том, что он отвечает на событие Show , которое является просто уведомлением о том, что Show был запрошен, не то, что диалоговое окно является видимым . Событие «Шоу» вполне может быть спроектировано так, чтобы вы могли знать, когда что-то должно быть показано, и предпринять некоторые действия до того, как это произойдет, как вы уже видели.

0 голосов
/ 25 апреля 2016

Код marioosh может быть улучшен путем сохранения ShellAdapter в переменной.

Удалите ShellAdapter при первом запуске прослушивателя.

Переменная started больше не нужна.

Инструкция s.setVisible(true); не обязательна, потому что это событие срабатывает, когда оболочка становится видимой.

public class App extends ApplicationWindow {

    @Override
    protected Control createContents(Composite parent) {
        // ...
        ShellAdapter shellActivatedAdapter = new ShellAdapter() {

            @Override
            public void shellActivated(ShellEvent shellevent) {
                shellevent.getSource().removeShellListener(shellActivatedAdapter);
                appStarted();
            }
        };

        getShell().addShellListener(shellActivatedAdapter);
    }
}
...