2012-01-12 5 views
8

Mi è stato detto e ho read che gli oggetti SWT devono essere eliminati esplicitamente chiamando il loro metodo dispose. Tuttavia, nei miei test con il seguente codice, ho notato che almeno Shell s si segnalano come disposti anche se il metodo di smaltimento non viene mai chiamato (né visualizzato) in nessun punto del mio codice.Devo disporre esplicitamente di casse 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."); 
      } 
     } 
    } 
} 

Così Shell ha davvero bisogno di essere esplicitamente smaltito? In tal caso, come fai a sapere quando smaltire una Shell e dove dovrebbe apparire il metodo di smaltimento?

risposta

13

Il paper che lei cita chiarisce questo punto:

Widget stessi di solito non hanno bisogno di essere smaltiti di programmazione. Una shell e i suoi figli sono disposti quando l'utente chiude la sua finestra.

Così, mentre una conchiglia fa bisogno da smaltire, l'onere non è su di voi per farlo. Né devi chiamare lo dispose su nessuno dei bambini, poiché lo smaltimento di un genitore lo farà per te. Di nuovo, dal link cita:

Quando si smaltisce una Shell, i suoi figli vengono eliminati. Infatti, lo smaltire qualsiasi Composito disporrà di tutti i figli del Composito.

Tuttavia, è necessario assicurarsi che smaltire le risorse create che sono non bambini. Ad esempio: colori e caratteri. Devi esplicitamente chiamare il loro metodo di smaltimento. È meglio collegare un ascoltatore di dispose allo Composite in cui li stai utilizzando per farlo. Per esempio:

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

E 'importante notare, tuttavia, che non si deve smaltire Color s che si uso ma non creati. Ad esempio, non smaltire i colori di sistema disponibili da Display#getSystemColor().

+0

Ottima risposta, grazie. – Buttons840