听众之一适合可见性的JPanel被改变

AncestorListenerComponentListenerHierarchyListener监听JPanelJComponents更改的可见性是否存在一些规则或好的/不好的体验?

他们中的一个比其他人更好还是更安全? 我特别想知道何时以及如何隐藏JPanel / JComponent

注意下面的代码包含不正确的Swing规则,比如在这种情况下使用Thread.sleep(int) ,以允许我在Swing GUI中打印正确的Listeners顺序

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

如果你想听取可见性更改 – 使用ComponentListener或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" ); } } ); 

但是这个可见度可能不是你想象的那个(我猜是这样)。 isVisible标志将是“真实的”,即使组件没有被添加到任何容器而根本不显示!

这种可见性有一个稍微不同的目的 – 您可以使用它来手动隐藏已经添加和显示在您的应用程序的某个地方的组件。 在这种情况下(如果使用setVisible(false))它将被隐藏,并且该组件的每个ComponentListener将被通知有关该更改。

所以,谈论实际的可见性…

这是你应该用来听取实际的组件外观/消失:

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

我总是使用这个监听器来确定什么时候该组件被添加到某个地方,并且还要监听它何时被移动/移除。

另外,您可以通过调用isShowing方法来始终检查组件是否对应用程序用户实际可见:

 boolean userCanSeeThePanel = panel.isShowing (); 

只有该面板被添加到VISIBLE到用户框架,并且isVisible标志也是真的(这通常是正确的,除非你设置为false),这将返回真。

我想这就是所有我可以告诉你的可见性。 我可能会误解你的问题 – 纠正我,如果我在这种情况下是错的。