检测 Java Swing 组件是否被隐藏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2727849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:32:52  来源:igfitidea点击:

Detect if Java Swing component has been hidden

javaswing

提问by kayahr

Assume we have the following Swing application:

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

    final JFrame frame = new JFrame();

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

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

So in this example we simply have an outer panel in the frame and a special component in the panel. This special component must do something when it is hidden and shown. But the problem is that setVisible() is called on the outer panel and not on the special component. So I can't override the setVisible method in the special component and I also can't use a component listener on it. I could register the listener on the parent component but what if the outer panel is also in another panel and this outer outer panel is hidden?

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

Is there an easier solution than recursively adding component listeners to all parent components to detect a visibility change in SomeSpecialComponent?

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

采纳答案by aioobe

To listen for this kind of events occuring in the hierarchy, you could do the following.

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

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

}

You could even be more precise in the treatement of HierarchyEvents. Have a look at

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

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

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

回答by cooperised

Thanks aioobe for your answer- I got here via Google, looking for the same thing. :-) It's worth noting that Component.isShowing()does the same job as your amIVisible()though, so a revised code snippet (including a check on the nature of the HierarchyEvent) might be:

感谢 aioobe 的回答- 我是通过 Google 来到这里的,正在寻找同样的东西。:-) 值得注意的是,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());
    }
}

回答by aioobe

Have a look at the ComponentListener (or ComponentAdapter)

看看 ComponentListener(或 ComponentAdapter)

http://java.sun.com/docs/books/tutorial/uiswing/events/componentlistener.html

http://java.sun.com/docs/books/tutorial/uiswing/events/componentlistener.html

http://docs.oracle.com/javase/8/docs/api/java/awt/event/ComponentListener.html

http://docs.oracle.com/javase/8/docs/api/java/awt/event/ComponentListener.html

And specifically the method:

特别是方法:

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

A complete solution would look something like:

完整的解决方案如下所示:

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

If the actions that should be carried out upon hiding is tightly coupled with the SomeSpecialCompnent, I would suggest to let SomeSpecialComponent implement ComponentListener, and add itself as a listener for the ComponentEvents in its constructor.

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

Another useful way (more related to add/remove operations and perhaps not suitable for your specific scenario) is to override addNotify()and removeNotify().

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