Нужно ли явно уничтожать SWT Shell? - PullRequest
10 голосов
/ 13 января 2012

Мне сказали и прочитали , что объекты SWT должны быть явно удалены путем вызова их метода dispose. Тем не менее, в моем собственном тестировании с использованием следующего кода я заметил, что по крайней мере Shell s сообщают о том, что они удалены, хотя метод 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 должна быть явно удалена? Если да, то как узнать, когда утилизировать оболочку и где должен появиться метод утилизации?

1 Ответ

14 голосов
/ 13 января 2012

Бумага , на которую вы ссылаетесь, ясно дает понять:

Сами виджеты обычно не нужно утилизировать программно. Оболочка и ее дочерние элементы располагаются, когда пользователь закрывает окно.

Таким образом, в то время как оболочка нуждается в , необходимо избавиться, бремя это не на вас. Вам также не нужно звонить dispose по любому из детей, так как избавление от родителей сделает это за вас. Опять же, по ссылке, которую вы цитируете:

Когда вы утилизируете Shell, его дочерние элементы располагаются. По факту, утилизация любого Композита уничтожит всех его детей.

Однако вы должны убедиться, что вы распоряжаетесь созданными вами ресурсами, которые не дочерние. Например: цвета и шрифты. Вам явно нужно вызвать их метод 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 s, которые вы используете , но не create . Например, не удаляйте системные цвета, доступные в Display#getSystemColor().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...