eclipse 如何检测 SWT 对话框已打开并且可见?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7387818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I detect that a SWT dialog has been opened and is visible?
提问by locka
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.
我有一个WizardDialog
有很多页的 SWT 。当这个对话框第一次打开时,我必须检查一些条件,如果满足这些条件,我需要在新打开的对话框上显示一个弹出窗口。
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:
所以我有这个代码来监听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();
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 Window
s 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.
很明显,这SWT.Show
是不可靠的,至少在Window
我运行它的地方是这样。我也尝试将此代码放入ShellListener
激活中,但这甚至发生在SWT.Show
上面的示例之前。
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.
计划 B 是一个基于脏定时器的 hack,其中一个定时器被设置为在未来 200 毫秒内触发,并希望它在对话框可见时触发,但显然这可能会引入它自己的问题。
回答by marioosh
I'm using in similar situation (need that appStarted()
is called after application window is visible) something like below.
我在类似的情况下使用(需要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;
}
}
});
}
}
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();
回答by Edward Thomson
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.)
与挂钩SWT.Show
事件不同,将 a 挂钩PaintListener
到对话框的Composite
. (您可能希望在第一次执行时解开它。)
回答by Geoff Alexander
I know that this is an old thread. But in case someone finds it useful, I found that overriding Dialog.create() rather than Dialog.open() worked for me.
我知道这是一个旧线程。但如果有人觉得它有用,我发现覆盖 Dialog.create() 而不是 Dialog.open() 对我有用。
回答by jefflunt
What about overriding dialog.open()
methodon your WizardDialog
class? The first line of the overridden method would call super.open()
, which would make it visible. Just put your custom code after that, in the .open()
method.
在dialog.open()
你的WizardDialog
班级上覆盖方法怎么样?重写方法的第一行将调用super.open()
,这将使其可见。只需将您的自定义代码放在.open()
方法中。
The issue with the approach you're taking above appears to be that it responds to a Show event, which is simply notification that Show has been requested, not that the dialog is visible. The Show event could very well be designed to allow you to know when something is about to be shown, and take some action before that happens, as you've experienced.
您在上面采用的方法的问题似乎是它响应 Show事件,这只是表明已请求 Show 的通知,而不是对话框可见。Show 事件可以很好地设计为让您知道什么时候将要显示某些内容,并在此之前采取一些措施,正如您所经历的那样。
回答by Arjen Rodenhuis
The code of mariooshcan be further improved, by storing the ShellAdapter
in a variable.
marioosh的代码可以通过将 存储ShellAdapter
在变量中来进一步改进。
Remove the ShellAdapter
when the listener is triggered for the first time.
ShellAdapter
首次触发侦听器时删除。
The variable started
is no longer needed.
started
不再需要该变量。
The statement s.setVisible(true);
is not necessary, because this event is just triggered when the shell gets visible.
该语句s.setVisible(true);
不是必需的,因为此事件仅在 shell 可见时触发。
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);
}
}