But*_*840 3 java swt dispose eclipse-rcp
什么是处理SWT炮弹的正确方法?我按照Dialog API文档中给出的模板创建了一些成功的Dialogs.对话的SWT API说:
用户定义对话框的基本模板通常如下所示:
Run Code Online (Sandbox Code Playgroud)public class MyDialog extends Dialog { Object result; public MyDialog (Shell parent, int style) { super (parent, style); } public MyDialog (Shell parent) { this (parent, 0); // your default style bits go here (not the Shell's style bits) } public Object open () { Shell parent = getParent(); Shell shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); shell.setText(getText()); // Your code goes here (widget creation, set result, etc). shell.open(); Display display = parent.getDisplay(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } return result; } }
我创建的对话框在Windows上没有自己的任务栏图标,正如我期望的对话框.我现在想创建一些Shell,如果我理解正确将在Windows上收到自己的任务栏条目?
与上述API文档中给出的说明相反,我还看到一篇文章似乎暗示如API文档中所示的while循环是错误的方法.相反,本文建议使用close事件侦听器来处理Shell.
处理SWT炮弹的正确方法是什么(当谈到主题时,对话也是如此)?
Mik*_*els 10
希望我能帮助解释这里发生的事情.
Dialog基本上只是一个方便的子类类,因为Shell它本身不应该是子类.Dialog如果需要,您可以根本不创建shell .在这种情况下,您的MyDialog类是其他人可以用来重复打开相同类型的对话框的类.
只要shell打开,这段代码就会驱动SWT事件循环(单击shell上的关闭按钮会默认配置shell):
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
Run Code Online (Sandbox Code Playgroud)
您必须Display.readAndDispatch定期致电以防止您的SWT应用程序"锁定".基本上它会导致应用程序正确处理来自操作系统的所有传入事件(键盘和鼠标事件,重新绘制事件等).readAndDispatch基本上从应用程序的事件队列中获取一个事件并调用正确的侦听器.在Eclipse RCP应用程序中,工作台通常负责"抽取"事件循环,您不必乱用它.这里有关于事件循环的更多信息.
在此上下文中"手动"泵送事件循环的目的是防止MyDialog.open在未处置外壳时返回,但仍使应用程序不"挂起".如果你的MyDialog.open方法试图等待shell处理,但是它没有引发事件循环,你的应用程序将"锁定",因为没有事件循环运行,shell无法通知它应该被处置!
您可以在不使用此模式的情况下创建shell.这是一个非常简单的SWT应用程序的例子,它可以同时打开大量的shell并且只要其中至少有一个仍然打开就会一直运行(我省略了包声明和导入):
public class Shells {
private static int numDisposals = 0;
public static void main(String[] args) {
Display d = Display.getDefault();
for (int i = 0; i < 5; i++) {
Shell s = new Shell(d);
s.open();
s.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent arg0) {
numDisposals++;
}
});
}
while (numDisposals < 5) {
while (!d.readAndDispatch()) {
d.sleep();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我DisposeListener向每个shell 添加一个,以便在关闭shell时执行某些操作.您还可以使用IShellListener更直接地侦听close事件,甚至实际阻止它(例如,如果shell包含未保存的工作,您可能想要这样做).这是对第一个启动5个shell并随机阻止你关闭它们的程序的一个恼人的修改:
public class Shells {
private static Random r = new Random();
private static int numDisposals = 0;
public static void main(String[] args) {
Display d = Display.getDefault();
for (int i = 0; i < 5; i++) {
Shell s = new Shell(d);
s.open();
s.addShellListener(new ShellAdapter() {
@Override
public void shellClosed(ShellEvent e) {
boolean close = r.nextBoolean();
if (close) {
System.out.println("Alright, shell closing.");
} else {
System.out.println("Try again.");
}
e.doit = close;
}
});
s.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent arg0) {
numDisposals++;
}
});
}
while (numDisposals < 5) {
while (!d.readAndDispatch()) {
d.sleep();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于使事情变得更加清晰!
编辑添加:我不完全确定为什么你没有为你的shell获取一个Windows任务栏项,但我怀疑它与你传递给shell的构造函数的样式标志有关.我的示例中的shell没有样式标志,它们都有一个任务栏图标.
| 归档时间: |
|
| 查看次数: |
10477 次 |
| 最近记录: |