Why SWT CTabItem doesn't dispose child widget recursively?

699 views Asked by At

The javadoc of SWT CTabItem.dispose() mentioned that:

This method is not called recursively on the descendants of the receiver

What is the reason behind that? If the CTabItem is disposed, the child widgets are not displayed anymore. Why they are not disposed recursively?

Would there be any problem if I override the CTabItem.dispose() method to dispose the child widgets recursively?

Thanks

1

There are 1 answers

4
greg-449 On BEST ANSWER

That comment is actually in the JavaDoc for the Widget class which CTabItem is derived from, it applies to all controls.

When you call dispose the children of the control are destroyed, but not by calling the child controls dispose method.

The JavaDoc is telling you that overriding the dispose method won't work if you want to know when the control is disposed, instead you must listen for the SWT.Disposed event.

The code for Widget.dispose is:

public void dispose () {
    /*
    * Note:  It is valid to attempt to dispose a widget
    * more than once.  If this happens, fail silently.
    */
    if (isDisposed ()) return;
    if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
    release (true);
}

and release:

void release (boolean destroy) {
    if ((state & DISPOSE_SENT) == 0) {
        state |= DISPOSE_SENT;
        sendEvent (SWT.Dispose);
    }
    if ((state & DISPOSED) == 0) {
        releaseChildren (destroy);
    }
    if ((state & RELEASED) == 0) {
        state |= RELEASED;
        if (destroy) {
            releaseParent ();
            releaseWidget ();
            destroyWidget ();
        } else {
            releaseWidget ();
            releaseHandle ();
        }
    }
}

So it is the release method that calls releaseChildren to destroy the children.

releaseChildren for the Composite control is:

void releaseChildren (boolean destroy) {
    Control [] children = _getChildren ();
    for (int i=0; i<children.length; i++) {
        Control child = children [i];
        if (child != null && !child.isDisposed ()) {
            child.release (false);
        }
    }
    super.releaseChildren (destroy);
}

So this calls release on the child control (not dispose)