Search code examples
javaswingjlayeredpane

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?


Solution

  • 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.