2012-06-04 21 views
19

ci sono alcune regole, o buone esperienze negative/con AncestorListener, ComponentListener o HierarchyListener di ascolto per la visibilità delle modifiche con JPanel e JComponents?JPanel cui uno degli ascoltatori è appropriato per la visibilità è cambiato

Uno di questi è migliore o più sicuro degli altri? Vorrei soprattutto sapere quando e come JPanel/JComponent è nascosto.

Avviso il seguente codice contiene norme Altalena non corretti, come l'utilizzo di Thread.sleep(int), in questo caso, per permettere a me di stampare-out corretto ordine di Listeners in Swing GUI

import java.awt.BorderLayout; 
import java.awt.CardLayout; 
import java.awt.event.ComponentEvent; 
import java.awt.event.ComponentListener; 
import java.awt.event.HierarchyEvent; 
import java.awt.event.HierarchyListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.event.AncestorEvent; 
import javax.swing.event.AncestorListener; 

public class CardlayoutTest extends JFrame { 

    private static final long serialVersionUID = 1L; 
    public CardLayout card = new CardLayout(); 

    public CardlayoutTest() { 
     JPanel pnlA = new JPanel(new BorderLayout()); 
     pnlA.add(new JButton("A"), BorderLayout.CENTER); 
     JPanel pnlB = new JPanel(new BorderLayout()); 
     pnlB.add(new JButton("B"), BorderLayout.CENTER); 
     JPanel pnlC = new JPanel(new BorderLayout()); 
     pnlC.add(new JButton("C"), BorderLayout.CENTER); 

     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setLayout(card); 
     add(pnlA, "A"); 
     add(pnlB, "B"); 
     add(pnlC, "C"); 

     pnlA.addAncestorListener(new EventHandler()); 
     pnlB.addAncestorListener(new EventHandler()); 
     pnlC.addAncestorListener(new EventHandler()); 

     pnlA.addHierarchyListener(new EventHandler()); 
     pnlB.addHierarchyListener(new EventHandler()); 
     pnlB.addHierarchyListener(new EventHandler()); 

     pnlA.addComponentListener(new EventHandler()); 
     pnlB.addComponentListener(new EventHandler()); 
     pnlB.addComponentListener(new EventHandler()); 
    } 

    class EventHandler implements AncestorListener, ComponentListener, HierarchyListener { 

     @Override 
     public void ancestorAdded(AncestorEvent event) { 
      System.out.println("CardlayoutTest.EventHandler.ancestorAdded()"); 
     } 

     @Override 
     public void ancestorMoved(AncestorEvent event) { 
      System.out.println("CardlayoutTest.EventHandler.ancestorMoved()"); 
     } 

     @Override 
     public void ancestorRemoved(AncestorEvent event) { 
      System.out.println("CardlayoutTest.EventHandler.ancestorRemoved()"); 
     } 

     @Override 
     public void hierarchyChanged(HierarchyEvent e) { 
      System.out.println("Components Change: " + e.getChanged()); 
      if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { 
       if (e.getComponent().isDisplayable()) { 
        System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged()); 
       } else { 
        System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged()); 
       } 
      } 
      if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { 
       if (e.getComponent().isDisplayable()) { 
        System.out.println("Components SHOWING_CHANGED : " + e.getChanged()); 
       } else { 
        System.out.println("Components SHOWING_CHANGED : " + e.getChanged()); 
       } 
      } 
     } 

     public void componentHidden(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Hidden"); 
     } 

     public void componentMoved(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Moved"); 
     } 

     public void componentResized(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Resized "); 
     } 

     public void componentShown(ComponentEvent e) { 
      System.out.println(e.getComponent().getClass().getName() + " --- Shown"); 
     } 
    } 

    public static void main(String[] args) { 
     CardlayoutTest t = new CardlayoutTest(); 
     t.setSize(500, 500); 
     System.out.println("CardlayoutTest.main()------------------------ FIRST"); 
     t.card.show(t.getContentPane(), "A"); 
     t.setVisible(true); 
     System.out.print("\n"); 
     try { 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
     } 
     System.out.println("CardlayoutTest.main()------------------------ SECOND"); 
     t.card.show(t.getContentPane(), "B"); 
     System.out.print("\n"); 
     try { 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
     } 
     System.out.println("CardlayoutTest.main()------------------------ THIRD"); 
     t.card.show(t.getContentPane(), "C"); 
     System.out.print("\n"); 
    } 
} 

risposta

31

Se si desidera ascoltare ESATTAMENTE la visibilità variazioni - usano ComponentListener o ComponentAdapter:

JPanel panel = new JPanel(); 
    panel.addComponentListener (new ComponentAdapter() 
    { 
     public void componentShown (ComponentEvent e) 
     { 
      System.out.println ("Component shown"); 
     } 

     public void componentHidden (ComponentEvent e) 
     { 
      System.out.println ("Component hidden"); 
     } 
    }); 

Ma che la visibilità potrebbe non essere quello che si pensi. Il flag isVisible() sarà true anche se lo Component non viene aggiunto a nessuno Container e quindi non viene visualizzato affatto!

Questa visibilità ha uno scopo leggermente diverso. Puoi usarlo per nascondere manualmente lo Component che è già stato aggiunto e mostrato da qualche parte nella tua applicazione. In tal caso, (se si utilizza setVisible(false)) verrà nascosto e ogni ComponentListener di quello Component verrà informato su tale modifica.

Così, parlando di visibilità reale ...

Questo è ciò che si dovrebbe usare per ascoltare attuale apparizione componente/scomparsa:

JPanel panel = new JPanel(); 
    panel.addAncestorListener (new AncestorListener() 
    { 
     public void ancestorAdded (AncestorEvent event) 
     { 
      // Component added somewhere 
     } 

     public void ancestorRemoved (AncestorEvent event) 
     { 
      // Component removed from container 
     } 

     public void ancestorMoved (AncestorEvent event) 
     { 
      // Component container moved 
     } 
    }); 

Io uso sempre che chi ascolta per determinare quando il Component viene aggiunto da qualche parte e anche da ascoltare quando viene spostato/rimosso.

Inoltre, è sempre possibile controllare se la Component è in realtà visibile per utente dell'applicazione chiamando isShowing() metodo:

boolean userCanSeeThePanel = panel.isShowing(); 

Ciò restituirà true SOLO se quel pannello viene aggiunto al Visibile a telaio utente e isVisible() bandiera è anche vero (di solito è true, a meno che non lo si imposti su false).

Immagino che sia tutto ciò che posso dire sulla visibilità. Potrei aver frainteso la tua domanda. Correggimi se sbaglio in quel caso.

+0

@mKorbel Sentiti libero di chiedere di più se ancora non capisci qualche parte della visibilità. È una parte piuttosto complessa di Swing in realtà –

+0

fondamentalmente mi interessa vedere gli eventi appropriati quando sono già visibili. JComponent è (cambia in) nascosto – mKorbel

+0

Se la modifica è fatta dal metodo "setVisible (false)" - usa ComponentListener o ComponentAdapter. In "componentHidden" riceverai una notifica quando il componente è nascosto ("setVisible (false)" chiamato) e in "componentShown" quando viene mostrato ("setVisible (true)" chiamato) –