Предположите, что у нас есть следующее приложение Swing:
final JFrame frame = new JFrame();
final JPanel outer = new JPanel();
frame.add(outer);
JComponent inner = new SomeSpecialComponent();
outer.add(inner);
Таким образом в этом примере у нас просто есть внешняя панель в кадре и специальный компонент в панели. Этот специальный компонент должен сделать что-то, когда он скрыт и показан. Но проблема состоит в том, что setVisible () называют на внешней панели а не на специальном компоненте. Таким образом, я не могу переопределить setVisible метод в специальном компоненте, и я также не могу использовать слушателя компонента на нем. Я мог зарегистрировать слушателя на родительском компоненте, но что, если внешняя панель находится также в другой панели и этой внешней внешней панели, скрыт?
Существует ли более легкое решение, чем рекурсивное добавление слушателей компонента всех родительских компонентов для обнаружения изменения видимости в SomeSpecialComponent?
Чтобы отслеживать события такого рода, происходящие в иерархии, вы можете сделать следующее.
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
Взгляните на 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 ()
.