检测Java Swing组件是否已隐藏

检测Java Swing组件是否已隐藏,java,swing,Java,Swing,假设我们有以下Swing应用程序: final JFrame frame = new JFrame(); final JPanel outer = new JPanel(); frame.add(outer); JComponent inner = new SomeSpecialComponent(); outer.add(inner); 所以在这个例子中,我们只是在框架中有一个外部面板,在面板中有一个特殊的组件。此特殊组件在隐藏和显示时必须执行某些

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

    final JFrame frame = new JFrame();

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

    JComponent inner = new SomeSpecialComponent();
    outer.add(inner);
所以在这个例子中,我们只是在框架中有一个外部面板,在面板中有一个特殊的组件。此特殊组件在隐藏和显示时必须执行某些操作。但问题是setVisible()是在外部面板上调用的,而不是在特殊组件上调用的。因此,我不能重写特殊组件中的setVisible方法,也不能在其上使用组件侦听器。我可以在父组件上注册侦听器,但是如果外部面板也在另一个面板中,而这个外部面板是隐藏的呢


有没有比向所有父组件递归添加组件侦听器更容易的解决方案来检测某些特殊组件中的可见性更改?

查看一下ComponentListener(或ComponentAdapter)

特别是方法:

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!");
    }
});
如果隐藏时应该执行的操作与SomeSpecialComponent紧密耦合,我建议让SomeSpecialComponent实现ComponentListener,并将自己添加为其构造函数中ComponentEvents的侦听器


另一种有用的方法(与添加/删除操作更相关,可能不适合您的特定场景)是重写
addNotify()
removeNotify()
要侦听层次结构中发生的此类事件,可以执行以下操作

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

}
你甚至可以更精确地处理等级事件。看看

谢谢你的帮助-我是通过谷歌来到这里的,寻找同样的东西。:-)值得注意的是,
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());
    }
}

隐藏父组件时不会触发此事件,仅在调用特殊组件本身的setVisible()方法时才会触发此事件。正如我所说,我正在寻找一种解决方案,它比递归地附加到所有父组件的componentListener事件更容易。