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

时间:2012-01-12 21:22:15

标签: java swt

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

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,以及dispose方法应该出现在哪里?

1 个答案:

答案 0 :(得分:14)

您引用的paper明确指出:

  

小部件本身通常不需要处理   编程。当用户使用外壳及其子代   关闭它的窗口。

因此,虽然需要处理shell ,但您不必担心。你也不需要给任何一个孩子打电话dispose,因为处理父母会为你做这件事。再次,从您引用的链接:

  

当您处置壳牌时,其子女将被处置。事实上,   处置任何复合材料将处置所有复合材料的子女。

但是,您必须确保处置您创建的子项的资源。例如:颜色和字体。你明确需要调用他们的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();
            }
        });
    }
}

但请务必注意,您不应处置使用但不创建Color。例如,请勿处置Display#getSystemColor()中可用的系统颜色。