JPanel que uno de los oyentes es apropiado para la visibilidad cambia

¿Hay algunas reglas, o buenas / malas experiencias con AncestorListener , ComponentListener o HierarchyListener escuchando la visibilidad de los cambios con JPanel y JComponents ?

¿Es uno de ellos mejor o más seguro que los demás? Especialmente me gustaría saber cuándo y cómo está oculto JPanel / JComponent .

Tenga en cuenta que el siguiente código contiene reglas de Swing incorrectas, como el uso de Thread.sleep(int) , en este caso, para permitirme imprimir el orden correcto de Listeners en 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"); } } 

Si desea escuchar EXACTAMENTE la visibilidad cambia – use 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" ); } } ); 

Pero esa visibilidad podría no ser la que piensas. isVisible() bandera isVisible() será true incluso si el Component no se agrega a ningún Container y por lo tanto no se muestra en absoluto!

Esa visibilidad tiene un propósito ligeramente diferente. Puede usarlo para ocultar manualmente el Component que ya está agregado y que se muestra en algún lugar de su aplicación. En ese caso, (si usa setVisible(false) ) se setVisible(false) y cada ComponentListener de ese Component será informado sobre ese cambio.

Entonces, hablando de visibilidad real …

Esto es lo que debe usar para escuchar la apariencia / desaparición del componente real :

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

Siempre uso ese oyente para determinar cuándo se agrega el Component algún lugar y también para escuchar cuándo se mueve o quita.

Además, siempre puede verificar si el Component es realmente visible para el usuario de la aplicación llamando isShowing() método isShowing() :

 boolean userCanSeeThePanel = panel.isShowing(); 

Esto regresará true SOLO si ese panel se agrega a VISIBLE en el marco de usuario y el isVisible() también es verdadero (generalmente es true , a menos que lo establezca en false ).

Supongo que eso es todo lo que puedo decirte sobre la visibilidad. Podría haber entendido mal tu pregunta. Corrígeme si me equivoco en ese caso.