2010-04-28 11 views
19

Supponiamo di avere la seguente applicazione swing:rilevare se componente Java Swing è stata nascosta

final JFrame frame = new JFrame(); 

    final JPanel outer = new JPanel(); 
    frame.add(outer); 

    JComponent inner = new SomeSpecialComponent(); 
    outer.add(inner); 

Quindi in questo esempio dobbiamo semplicemente un pannello esterno nel telaio e uno speciale componente nel pannello. Questo componente speciale deve fare qualcosa quando è nascosto e mostrato. Ma il problema è che setVisible() viene chiamato sul pannello esterno e non sul componente speciale. Quindi non posso sovrascrivere il metodo setVisible nel componente speciale e non posso nemmeno usare un listener di componenti su di esso. Potrei registrare il listener sul componente genitore, ma cosa succede se il pannello esterno si trova anche in un altro pannello e questo pannello esterno esterno è nascosto?

Esiste una soluzione più semplice rispetto all'aggiunta ricorsiva di listener di componenti a tutti i componenti principali per rilevare una modifica della visibilità in SomeSpecialComponent?

risposta

13

Per ascoltare questo tipo di eventi che si verificano nella gerarchia, è possibile effettuare quanto segue.

class SomeSpecialComponent extends JComponent implements HierarchyListener { 

    private boolean amIVisible() { 
     Container c = getParent(); 
     while (c != null) 
      if (!c.isVisible()) 
       return false; 
      else 
       c = c.getParent(); 
     return true; 
    } 

    public void addNotify() { 
     super.addNotify(); 
     addHierarchyListener(this); 
    } 

    public void removeNotify() { 
     removeHierarchyListener(this); 
     super.removeNotify(); 
    } 

    public void hierarchyChanged(HierarchyEvent e) { 
     System.out.println("Am I visible? " + amIVisible()); 
    } 

} 

Si potrebbe anche essere più precisi nel trattamento di HierarchyEvents. Date un'occhiata a

http://java.sun.com/javase/6/docs/api/java/awt/event/HierarchyEvent.html

3

Date un'occhiata al ComponentListener (o ComponentAdapter)

http://java.sun.com/docs/books/tutorial/uiswing/events/componentlistener.html

http://docs.oracle.com/javase/8/docs/api/java/awt/event/ComponentListener.html

E in particolare il metodo:

void componentHidden(ComponentEvent e) 
    Invoked when the component has been made invisible. 

Una soluzione completa sarebbe un aspetto simile:

inner.addComponentListener(new ComponentAdapter() { 
    public void componentHidden(ComponentEvent ce) { 
     System.out.println("Component hidden!"); 
    } 
}); 

Se le azioni che devono essere eseguite al momento del nascondimento sono strettamente associate a SomeSpecialCompnent, suggerisco di consentire a SomeSpecialComponent di implementare ComponentListener e aggiungersi come listener per ComponentEvents nel suo costruttore.

Un altro modo utile (più relativo alle operazioni di aggiunta/rimozione e forse non adatto per il proprio scenario specifico) è di ignorare addNotify() e removeNotify().

+3

Questo evento non viene attivato quando il genitore il componente è nascosto, viene attivato solo quando viene chiamato il metodo setVisible() del componente speciale stesso. Come ho detto, sono alla ricerca di una soluzione EASIER che si collega in modo ricorsivo agli eventi componentListener di tutti i componenti principali. – kayahr

+0

Ora vedo il problema :-) nuova risposta in arrivo ... – aioobe

22

Grazie per la vostra aioobe answer - sono arrivato qui tramite Google, cercando la stessa cosa. :-) Vale la pena notare che Component.isShowing() fa lo stesso lavoro come il vostro amIVisible() però, in modo un frammento di codice rivisto (tra cui un controllo sulla natura del HierarchyEvent) potrebbe essere:

class SomeSpecialComponent extends JComponent implements HierarchyListener { 

    public void addNotify() { 
     super.addNotify(); 
     addHierarchyListener(this); 
    } 

    public void removeNotify() { 
     removeHierarchyListener(this); 
     super.removeNotify(); 
    } 

    public void hierarchyChanged(HierarchyEvent e) { 
     if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) 
      System.out.println("Am I visible? " + isShowing()); 
    } 
} 
Problemi correlati