Display与线程的关系
一个线程只能有一个Display实例,SWT自动将new的Display与当前线程永远关联,当在线程中创建(new)第二个Display时,SWT抛出Exception。
创建第一个Dispaly的线程未必是UI线程,一个SWT程序可以有多个线程,每个线程里都可以再创建Display。所以SWT程序可以有多个Display实例。
Display.getDefault()
返回第一个创建的Display,如果还没有Display被创建,则new一个新的Display返回,绝对不会返回Null。
// Source Code
public static Display getDefault () {
synchronized (Device.class) {
if (Default == null) Default = new Display ();
return Default;
}
}
Display.getCurrent()
返回在当前线程中的Display实例,如果当前线程是非UI线程,很有可能其没有Display实例,返回null。用的时候注意,判断是否为null。
public static Display getDisplay() {
Display display = Display.getCurrent();
//非UI线程时,有可能是null
if (display == null)
display = Display.getDefault();
return display;
}
Display.getDefault()并非UI线程中的display,使用请三思
在SWT程序或者RCP程序中,经常会见到如下代码来访问UI线程:
Display.getDefault().(a)syncExec(new Runnable() {….});
此处问题在于:如果在UI线程的Display创建之前,有一个另外一个线程创建了一个Display,这时使用Display.getDefault()获得的将不是UI线程上的Display,上述代码会抛出运行时异常。我们需要的是UI线程上的Display,不然的话如何从Display上获得Cursor相关信息,如何获得Font相关信息,如何和UI线程syncExec代码。
最安全的办法:将UI线程中创建的Display保存起来,统一使用。这也是为什么RCP程序中不推荐使用Display.getDefault()来获得workbench的Display。
RCP程序中获得Display
PlatformUI.getWorkbench().getDisplay(); //获得workbench的display
该方法注释中写道:RCP程序应当使用该方法来获得workbench的display,而不是使用“Display.getDefault()”来获得。