Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if Java Swing component has been hidden

Tags:

java

swing

Assume we have the following Swing application:

    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?

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

like image 989
kayahr Avatar asked Apr 28 '10 08:04

kayahr


2 Answers

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:

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());
    }
}
like image 163
cooperised Avatar answered Oct 12 '22 01:10

cooperised


Have a look at the ComponentListener (or 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

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.

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

like image 22
aioobe Avatar answered Oct 12 '22 02:10

aioobe