Paul Paul - 5 months ago 20
Java Question

JLayeredPane returning null on getParent()

My situation: I have a class MainScreen that extends JFrame (it really is just a JFrame with a main method to start the application) on which I added a class GameManager that extends JLayeredPane, that I'm using to display something.

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


Now, what I want to do is, from the GameManager class I want to add a JButton to the main JFrame. I thought it would be easy, just do:

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


but getParent() is returning null, so obviously it doesn't work. I don't know why though, I did something similar before (with a JComponent and a JPanel though), and I thought that every JComponent when added to a container would have the container as its parent. What did I miss?

Answer

If the following statement:

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

exists within constructor of GameManager.java, then getParent() is returning null is correct. It is because the object of GameManager is added to MainScreen after the call to this.getParent().add(button, BorderLayout.SOUTH);.

As per https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html

Each top-level container has a content pane that, generally speaking, contains (directly or indirectly) the visible components in that top-level container's GUI.

In case of JFrame the default content pane is a JPanel. So when you made a call to this.add(gm, BorderLayout.CENTER);, you actually added the instance of GameManager to the default content pane of JFrame i.e. a JPanel. That is why GameManager.getParent() is a JPanel. Hope, this helps.