Определить, был ли компонент Java Swing скрыт - PullRequest
19 голосов
/ 28 апреля 2010

Предположим, у нас есть следующее приложение Swing:

    final JFrame frame = new JFrame();

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

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

Так что в этом примере у нас просто есть внешняя панель в рамке и специальный компонент на панели. Этот специальный компонент должен что-то делать, когда он скрыт и показан. Но проблема в том, что setVisible () вызывается на внешней панели, а не на специальном компоненте. Поэтому я не могу переопределить метод setVisible в специальном компоненте, и я также не могу использовать компонентный слушатель для него. Я мог бы зарегистрировать слушателя на родительском компоненте, но что, если внешняя панель также находится на другой панели и эта внешняя внешняя панель скрыта?

Существует ли более простое решение, чем рекурсивное добавление слушателей компонентов ко всем родительским компонентам для обнаружения изменения видимости в SomeSpecialComponent?

Ответы [ 3 ]

23 голосов
/ 06 февраля 2011

Спасибо 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());
    }
}
13 голосов
/ 28 апреля 2010

Чтобы прослушать события такого рода, происходящие в иерархии, вы можете сделать следующее.

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

}

Вы могли бы даже быть более точным в рассмотрении событий Иерархии. Посмотрите на

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

3 голосов
/ 28 апреля 2010

Посмотрите на 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().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...