SWT应用程序中的Display实例

By | 2015年8月7日

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()”来获得。