2010-04-28 66 views
19

假设我们有以下的Swing应用程序:如果检测的Java Swing组件已经被隐藏

final JFrame frame = new JFrame(); 

    final JPanel outer = new JPanel(); 
    frame.add(outer); 

    JComponent inner = new SomeSpecialComponent(); 
    outer.add(inner); 

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

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

回答

13

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

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

3

有看看的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()

+3

则不会触发此事件时,父组件是隐藏的,只有在调用特殊组件本身的setVisible()方法时才触发它。正如我所说我正在寻找一个解决方案,它是EASIER然后递归地附加到所有父组件的componentListener事件。 – kayahr 2010-04-28 08:58:47

+0

我现在看到问题了:-)新的答案即将到来... – aioobe 2010-04-28 10:46:33

22

感谢aioobe您answer - 我来到这里通过谷歌,寻找同样的事情。 :-)值得一提的是,Component.isShowing()做相同的工作作为您amIVisible()不过,这样一个修订后的代码片段(包括对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()); 
    } 
}