我是否需要明确处理SWT Shell?

But*_*840 12 java swt

我被告知并且已经读过必须通过调用他们的dispose方法明确处理SWT对象.但是,在我自己使用以下代码进行的测试中,我注意到,Shell即使在我的代码中的任何地方都没有调用(也不会出现)dispose方法,至少s会将自己报告为已处理.

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.");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

那么壳牌真的需要明确处理吗?如果是这样,你怎么知道何时处置Shell,以及dispose方法应该出现在哪里?

Edw*_*son 16

你引用的论文清楚地说明了这一点:

小部件本身通常不需要以编程方式处理.当用户关闭窗口时,将释放shell及其子项.

因此,尽管外壳需要处理,负担不上你这样做.你也不需要打电话dispose给任何一个孩子,因为处理父母会为你做这件事.再次,从您引用的链接:

当您处置Shell时,其子项将被处置.实际上,处置任何Composite都会处理所有Composite的子节点.

但是,您必须确保处置您创建的儿童资源.例如:颜色和字体.你明确需要调用他们的dispose方法.最好将一个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();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

但是要注意,这一点很重要,你不应该处理Color的是英语新使用,但不创造.例如,不要处置可用的系统颜色Display#getSystemColor().