我被告知并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方法应该出现在哪里?
答案 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()
中可用的系统颜色。