2013-08-28 1 views
1

Первый, JComponent экземпляр jComponent создан. Затем он был добавлен к его родительскому элементу, как parent.add(jComponent);. Теперь я хочу знать в классе jComponent, что он был добавлен к его родительскому. Можно ли это сделать?Как узнать, когда JComponent был добавлен в его родитель?

Цель состоит в том, чтобы установить jComponent родителей, когда он уже был добавлен к его родителей, как:

Container window = getParent(); 
     while (!(window instanceof JWindow)) { 
      window = window.getParent(); 
     } 
JWindow parent = (JWindow) window; 
+0

Как насчет 'jComponent.getParent()! = Null'? – BackSlash

+0

Но, может быть, это может быть какой-то слушатель? –

+2

Вы можете переопределить метод addNotify. Но убедитесь, что вы вызываете super.addNotify. – Petr

ответ

1

Так что ответ:

public class MyComponent extends JComponent { 

    private JWindow parent; 

    //(...) 

    @Override 
    public void addNotify() { 
    parent = (JWindow) SwingUtilities.getAncestorOfClass(JWindow.class, getParent()); 
    super.addNotify(); 
    } 

} 

Или мы можем сделать:

@Override 
    public void addNotify() { 
    parent = (JWindow) SwingUtilities.getWindowAncestor(this); 
    super.addNotify(); 
    } 

Не знаю, что лучше, похоже, второй способ проще.

+1

Переопределение addNotify будет работать, но вам нужно создать подкласс, как вы делали выше. Если вы хотите использовать существующий компонент, не создавая подкласс, просто используйте интерфейс HierarchyListener. – Enwired

+0

Да, он также работает, проверен :) Но код больше по сравнению с переопределением 'addNotify()'. –

+1

Ну, это зависит от того, создаете ли вы подкласс или нет. Во всяком случае, ваш код для определения владельца JWindow может быть упрощен. Вам не нужен цикл while: parent = (JWindow) SwingUtilities.getAncestorOfClass (JWindow.class, getParent()); – Enwired

2

Использование

javax.swing.SwingUtilities.getWindowAncestor(yourComponent) 

возвращает окно, в котором ваш компонент был добавлен в или нуль, если он не был добавлен к окну.

Конечно, если вы добавите свой компонент в JPanel, который, в свою очередь, еще не добавлен в окно, метод выше вернет значение null.

В этом случае один из комментариев лучше: component.getParent() затем предоставит вам Контейнер, содержащий ваш компонент, если он существует.

2

Возможно, вы ищете AncestorListener, показаны here. Метод ancestorAdded() будет «Вызывается, когда источник или один из его предков становится видимым либо по вызову setVisible(true), либо по его добавлению в иерархию компонентов».

+0

AncestorListener позволяет вам знать каждый раз, когда компонент становится видимым из-за чего-то, что происходит в иерархии. Если он является дочерним элементом JTabbedPane, например, ancestorAdded() будет вызываться каждый раз, когда вкладка становится видимой. Если вы хотите знать, когда компонент был добавлен к его родительскому элементу, независимо от текущей видимости, HieararchyListener - это то, что нужно использовать. – Enwired

+0

Правильно, но я не уверен, что в вопросе выбора достаточно информации. Почему бы вам не расширить свой ответ, и я удалю свою. – trashgod

+1

Я пробовал также «AncestorListener», отлично работает, но «AncestorEvent» происходит только тогда, когда родительский элемент установлен видимым. При переопределении 'addNotify()' он вызывается сразу же после того, как дочерний элемент добавлен к родительскому элементу, даже если родительский элемент не отображается. Поэтому я предпочитаю 'addNotify()', потому что я могу создать экземпляр диалога до того, как он станет видимым - он открывается немного быстрее, когда пользователь нажимает на какую-то кнопку. –

4

Существует множество вариантов, в зависимости от ваших потребностей.

Если вы хотите знать, когда любой существующий компонент добавляется к родителю, вы можете добавить HierarchyListener к нему и слушать событие типа PARENT_CHANGED, который посылается после компонента добавляется к родителю.

Пример:

component.addHierarchyListener(new HierarchyListener() { 

    @Override 
    public void hierarchyChanged(HierarchyEvent e) { 
    if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) { 
     if (getParent() == e.getChangedParent()) { 
     System.out.println("*** Added to parent " + e.getChangedParent()); 
     } 
    } 
    } 
}); 

Если вы уже создаете пользовательский компонент, вы можете переопределить "addNotify()" метод:

@Override public void addNotify() { 
    super.addNotify(); 
    // do something here with getParent(); 
} 

Если вы хотите знать о родителе только после компонент был сделан видимым, вы можете использовать AncestorListener. ancestorAdded(AncestorEvent) будет называться каждые время, когда компонент становится видимым. Например, AncestorListener на JPanel внутри JTabbedPane будет получать такое событие каждый раз, когда пользователь выбирает эту вкладку для отображения.