Java 我需要显式地处理SWT shell吗?

Java 我需要显式地处理SWT shell吗?,java,swt,Java,Swt,我被告知,必须通过调用SWT对象的dispose方法显式地处理SWT对象。然而,在我自己对以下代码进行的测试中,我注意到,即使dispose方法从未在我的代码中的任何地方调用(也没有出现),至少Shells会将自己报告为disposed import java.util.ArrayList; import java.util.List; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.Dispos

我被告知,必须通过调用SWT对象的
dispose
方法显式地处理SWT对象。然而,在我自己对以下代码进行的测试中,我注意到,即使dispose方法从未在我的代码中的任何地方调用(也没有出现),至少
Shell
s会将自己报告为disposed

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.");
            }
        }
    }
}
import java.util.ArrayList;
导入java.util.List;
导入org.eclipse.swt.events.DisposeEvent;
导入org.eclipse.swt.events.dispelistener;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.Shell;
公开课考试{
私有静态int numDisposals=0;
私有静态列表shell=new ArrayList();
公共静态void main(字符串[]args){
Display d=Display.getDefault();
对于(int i=0;i<3;i++){
外壳s=新外壳(d);
加上(s);;
s、 setText(String.valueOf(i));
s、 open();
s、 添加DisposeListener(新DisposeListener(){
@凌驾
公共无效widgetDisposed(DisposeeEvent未使用){
numDisposals++;
printShellStatus();
}
});
}
而(numDisposals<3){
而(!d.readAndDispatch()){
d、 睡眠();
}
}
printShellStatus();
}
公共静态void printShellStatus(){
System.out.println(“处理了哪些外壳?”);
用于(壳:壳){
if(shell.isDisposed()){
System.out.println(“我被处置了”);
}如果(!shell.isDisposed()),则为else{
System.out.println(“我不愿意”);
}
}
}
}
那么Shell真的需要被显式地处理吗?如果是这样,您如何知道何时处理Shell,以及dispose方法应出现在何处?

您引用的示例清楚地说明了这一点:

小部件本身通常不需要处理 以编程方式。当用户 关闭窗口

因此,虽然壳确实需要处置,但这样做的负担不在您身上。您也不需要对任何子项调用
dispose
,因为处置父项将为您做到这一点。同样,从您引用的链接:

处置外壳时,将处置其子对象。事实上 处置任何复合材料都将处置该复合材料的所有子项

但是,您必须确保您所创建的资源不是子资源,而是子资源。例如:颜色和字体。您确实需要显式地调用它们的dispose方法。最好将dispose侦听器挂接到您正在使用的
组合
上。例如:

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();
            }
        });
    }
}
但是,需要注意的是,您不应处置
使用的
颜色
s,而不应创建。例如,不要处理
Display#getSystemColor()
中提供的系统颜色