JPanel que um dos ouvintes é adequado para a visibilidade é alterado

Existem algumas regras, ou boas / más experiências com AncestorListener , ComponentListener ou HierarchyListener escutando a visibilidade das mudanças com JPanel e JComponents ?

Um deles é melhor ou mais seguro que os outros? Eu gostaria especialmente de saber quando e como o JPanel / JComponent está oculto.

Observe que o código a seguir contém regras Swing incorretas, como o uso de Thread.sleep(int) , nesse caso, para permitir que eu imprima a ordem correta de Listeners na GUI do Swing

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

Se você quiser ouvir EXATAMENTE a visibilidade muda – use ComponentListener ou 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" ); } } ); 

Mas essa visibilidade pode não ser aquela em que você pensa. isVisible() sinalizador isVisible() será true mesmo que o Component não seja adicionado a nenhum Container e, portanto, não seja exibido.

Essa visibilidade tem um propósito ligeiramente diferente. Você pode usá-lo para ocultar manualmente o Component que já está adicionado e exibido em algum lugar do seu aplicativo. Nesse caso, (se você usar setVisible(false) ) ele ficará oculto e todos os ComponentListener desse Component serão informados sobre essa mudança.

Então, falando sobre a visibilidade real …

Isto é o que você deve usar para ouvir a aparência / desaparecimento real do componente:

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

Eu sempre uso esse ouvinte para determinar quando o Component é adicionado em algum lugar e também para ouvir quando ele é movido / removido.

Além disso, você sempre pode verificar se o Component está realmente visível para o usuário do aplicativo chamando o método isShowing() :

 boolean userCanSeeThePanel = panel.isShowing(); 

Isso retornará true SOMENTE se esse painel for adicionado ao VISIBLE ao frame do usuário e o sinalizador isVisible() também for true (geralmente é true , a menos que você o defina como false ).

Eu acho que é tudo que posso te dizer sobre visibilidade. Eu poderia ter entendido mal sua pergunta. Corrija-me se estiver errado nesse caso.