JLayeredPane возвращает значение null в getParent()

Моя ситуация: у меня есть класс MainScreen, который расширяет JFrame (на самом деле это просто JFrame с основным методом для запуска приложения), в котором я добавил класс GameManager, который расширяет JLayeredPane, который я использую для отображения чего-либо.

public static void main(String[] args) {
    MainScreen ms = new MainScreen();
}

public MainScreen() {
    this.initScreen();
    this.gm = new GameManager();
    this.add(gm, BorderLayout.CENTER);
    this.setVisible(true);
}       

Теперь я хочу добавить из класса GameManager кнопку JButton в основной JFrame. Я думал, что это будет легко, просто сделайте:

JButton button = new JButton("Hello");
this.getParent().add(button, BorderLayout.SOUTH);

но getParent() возвращает null, поэтому, очевидно, это не работает. Я не знаю, почему, я делал что-то подобное раньше (хотя и с JComponent и JPanel), и я думал, что каждый JComponent при добавлении в контейнер будет иметь контейнер в качестве своего родителя. Что я пропустил?


person Paul    schedule 26.06.2016    source источник
comment
Действительно ли ваш GameManager добавлен в JFrame перед вызовом getParent()?   -  person Shiro    schedule 26.06.2016
comment
Где this.getParent().add(button, BorderLayout.SOUTH); существует в GameManager.java? внутри конструктора?   -  person Sanjeev Saha    schedule 26.06.2016
comment
Да, я только что заметил это, это была глупая ошибка. Но теперь getParent() возвращает JPanel, а не JFrame, как так?   -  person Paul    schedule 26.06.2016


Ответы (1)


Если следующее утверждение:

this.getParent().add(button, BorderLayout.SOUTH);

существует в конструкторе GameManager.java, тогда getParent() is returning null является правильным. Это потому, что объект GameManager добавляется к MainScreen после вызова this.getParent().add(button, BorderLayout.SOUTH);.

Согласно https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html

Каждый контейнер верхнего уровня имеет панель содержимого, которая, вообще говоря, содержит (прямо или косвенно) видимые компоненты в графическом интерфейсе этого контейнера верхнего уровня.

В случае JFrame панель содержимого по умолчанию имеет вид JPanel. Таким образом, когда вы вызывали this.add(gm, BorderLayout.CENTER);, вы фактически добавляли экземпляр GameManager в панель содержимого по умолчанию JFrame, то есть a JPanel. Вот почему GameManager.getParent() это JPanel. Надеюсь это поможет.

person Sanjeev Saha    schedule 26.06.2016
comment
Да, я только что заметил это, это была глупая ошибка. (Это не в конструкторе, а в вызываемом им методе, поэтому я не заметил). Но теперь getParent() возвращает JPanel, а не JFrame, как так? - person Paul; 26.06.2016
comment
Я вообще не вызывал setContentPane, я просто установил заголовок, размер и операцию закрытия по умолчанию. - person Paul; 26.06.2016