2012-01-12 44 views
8

我被告知并且有read必须通过调用它们的dispose方法明确处置SWT对象。然而,在我用下面的代码进行的测试中,我注意到至少有Shell报告自己被处置,尽管在我的代码中任何地方都不会调用dispose方法(也不会出现)。我是否需要明确处理SWT壳?

import java.util.ArrayList; 
import java.util.List; 
import org.eclipse.swt.events.DisposeEvent; 
import org.eclipse.swt.events.DisposeListener; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 


    public class Test { 

     private static int numDisposals = 0; 
     private static List<Shell> shells = new ArrayList<Shell>(); 

    public static void main(String[] args) { 
     Display d = Display.getDefault(); 
     for (int i = 0; i < 3; i++) { 
      Shell s = new Shell(d); 
      shells.add(s); 
      s.setText(String.valueOf(i)); 
      s.open(); 
      s.addDisposeListener(new DisposeListener() { 

       @Override 
       public void widgetDisposed(DisposeEvent notUsed) { 
        numDisposals++; 
        printShellStatus(); 
       } 
      }); 
     } 
     while (numDisposals < 3) { 
      while (!d.readAndDispatch()) { 
       d.sleep(); 
      } 
     } 
     printShellStatus(); 
    } 

    public static void printShellStatus() { 
     System.out.println("Which shells are disposed?"); 
     for (Shell shell : shells) { 
      if (shell.isDisposed()) { 
       System.out.println("I am disposed."); 
      } else if (!shell.isDisposed()) { 
       System.out.println("I am NOT disposed."); 
      } 
     } 
    } 
} 

因此,壳真的需要明确处置?如果是这样,你怎么知道什么时候处理一个Shell,处理方法出现在哪里?

回答

13

所援引的paper了这一点:

窗口小部件本身通常并不需要通过编程设置 。当用户 关闭它的窗口时,壳和它的孩子被丢弃。

所以虽然壳确实需要处置,但您的负担不在此限。你也不需要给任何孩子打电话dispose,因为处置父母会为你做。再次,从您引用的链接中获得:

当您处置一个Shell时,它的子对象被丢弃。事实上,处置任何Composite将会处理所有Composite的孩子。

但是,您必须确保您创建的子资源是而不是。例如:颜色和字体。你确实需要调用他们的dispose方法。最好将处理侦听器挂接到您正在使用它们的Composite上来执行此操作。例如:

public class MyComposite extends Composite 
{ 
    private final Color color; 

    public MyComposite(Composite parent, int style) 
    { 
     super(parent, style); 

     color = new Color(getShell().getDisplay(), 255, 255, 255); 

     addDisposeListener(new DisposeListener() { 
      public void widgetDisposed(DisposeEvent e) 
      { 
       color.dispose(); 
      } 
     }); 
    } 
} 

然而,必须指出,这一点很重要,你不应该处理Color是你们等使用但不创建。例如,不要处理可从Display#getSystemColor()获得的系统颜色。

+0

很好的答案,谢谢。 – Buttons840 2012-01-12 21:51:25

相关问题