检测是否已隐藏Java Swing组件

假设我们有以下Swing应用程序:

final JFrame frame = new JFrame(); final JPanel outer = new JPanel(); frame.add(outer); JComponent inner = new SomeSpecialComponent(); outer.add(inner); 

因此,在这个例子中,我们只在框架中有一个外部面板,在面板中有一个特殊组件。 隐藏和显示此特殊组件时必须执行某些操作。 但问题是setVisible()在外部面板上调用而不是在特殊组件上调用。 所以我不能覆盖特殊组件中的setVisible方法,我也不能在其上使用组件监听器。 我可以在父组件上注册监听器但是如果外部面板也在另一个面板中并且这个外部外部面板被隐藏了怎么办?

有没有比向所有父组件递归添加组件侦听器以检测SomeSpecialComponent中的可见性更改更简单的解决方案?

要侦听层次结构中发生的此类事件,您可以执行以下操作。

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

您甚至可以更精确地处理HierarchyEvents。 看一下

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

感谢aioobe的回答 – 我通过Google来到这里,寻找同样的事情。 :-)值得注意的是, Component.isShowing()与你的amIVisible() Component.isShowing()做同样的工作,所以修改后的代码片段(包括检查HierarchyEvent的性质)可能是:

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

看看ComponentListener(或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

特别是方法:

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

一个完整的解决方案看起来像:

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

如果隐藏时应该执行的操作与SomeSpecialCompnent紧密结合,我建议让SomeSpecialComponent实现ComponentListener,并将其自身添加为其构造函数中ComponentEvents的侦听器。

另一种有用的方法(更多与添加/删除操作有关,可能不适合您的特定方案)是覆盖addNotify()removeNotify()