2012-01-12 8 views
8

Me han dicho y tengo read que los objetos SWT deben eliminarse explícitamente llamando a su método dispose. Sin embargo, en mis propias pruebas con el siguiente código, he notado que al menos Shell s se informan como eliminados a pesar de que el método de eliminación nunca se llama (ni aparece) en ninguna parte de mi código.¿Debo eliminar explícitamente los depósitos SWT?

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."); 
      } 
     } 
    } 
} 

¿Entonces Shell realmente tiene que eliminarse explícitamente? Si es así, ¿cómo sabe cuándo desechar un Shell y dónde debería aparecer el método de eliminación?

Respuesta

13

El paper que usted cita deja esto claro:

Reproductores mismos normalmente no necesitan ser eliminados mediante programación. Un shell y sus hijos se eliminan cuando el usuario cierra su ventana.

Así, mientras que una cáscara ¿Necesita que hay que eliminar, la carga no está en que así lo indiquen. Tampoco necesita llamar al dispose en ninguno de los niños, ya que la eliminación de uno de los padres lo hará por usted. Nuevamente, desde el enlace que cite:

Cuando desecha un Shell, sus hijos son desechados. De hecho, eliminando cualquier compuesto eliminará todos los hijos del compuesto.

Sin embargo, usted tiene que asegurarse de que se deshaga recursos que cree que son no niños. Por ejemplo: colores y fuentes. Usted explícitamente necesita llamar a su método de eliminación. Lo mejor es enganchar un oyente de eliminación al Composite en el que los está utilizando para hacer esto. Por ejemplo:

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(); 
      } 
     }); 
    } 
} 

Es importante señalar, sin embargo, que no debe deshacerse Color s que uso pero no cree. Por ejemplo, no deseche los colores del sistema disponibles en Display#getSystemColor().

+0

Gran respuesta, gracias. – Buttons840

Cuestiones relacionadas