Corey
Corey

Reputation: 152

Using multiple JPanels in a single JFrame

I've basically been trying to make a menu for a game by using a JFrame and switching out 2 JPanels (one for the menu and one for the actual game). I'm trying to implement the most basic format I can think of but can't seem to get it to work. If anybody could explain what's wrong with the code I would appreciate it.

Here's my JFrame, menu panel, and ActionListener

package buttonMenu;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Skeleton extends JFrame implements ActionListener{

JPanel menu;
JButton button;

public Skeleton(){

setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 400);
setVisible(true);

menu = new JPanel();
button = new JButton("button");

menu.setSize(400, 400);
menu.setBackground(Color.BLACK);
menu.setVisible(true);
menu.add(button);

button.setLocation(200, 200);
button.addActionListener(this);

add(menu, BorderLayout.CENTER);

}

public void actionPerformed(ActionEvent a){
    JPanel panel = Game.Game();
    this.remove(menu);
    this.add(panel);   
}

public static void main(String args[]){
    new Skeleton();
}
}

The actionPerformed calls the panel created in this class

package buttonMenu;
import java.awt.Color;
import javax.swing.JPanel;
public class Game{

public static JPanel Game(){
    JPanel panel = new JPanel();
    panel.setSize(400, 400);
    panel.setBackground(Color.WHITE);
    return panel;       
}

}

Again, if anybody could explain to me what's wrong with this code I would appreciate it. Thanks

Upvotes: 0

Views: 4285

Answers (3)

afsantos
afsantos

Reputation: 5206

What's wrong with my code may be kind of a vague question, but I'll sort some points:

  • extends JFrame: You're not really extending JFrame, you're just using one, as part of your GUI.
  • As other answers mention, you should revalidate() after adding/removing components.
  • menu.setVisible(true), usually this isn't needed.
  • Maybe not wrong, but I usually build all my interface first (ie, creating and adding the initial components), and only then set the dimensions and visibility of the frame.
  • You're running all that code in the main thread; Swing components aren't thread-safe. See Concurrency in Swing for more information on that.
  • I know this is for a game, but is absolute positioning in your panels really needed? Use Layout managers if possible (with an exception for your game panel, which will probably do only custom painting).

Upvotes: 1

Masudul
Masudul

Reputation: 21981

Use validate() method to see the changes.

public void actionPerformed(ActionEvent a){
    JPanel panel = Game.Game();
    this.remove(menu);
    this.add(panel);   
    this.validate();
}

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347334

When adding/removing components, you will need to revalidate the parent container to force it to relay itself out...

public void actionPerformed(ActionEvent a){
    JPanel panel = Game.Game();
    this.remove(menu);
    this.add(panel);   
    this.revalidate();
}

A better solution would be to use something like a CardLayout

Take a look at How to use CardLayout for more details

ps- I should add. You should avoid extending directly from JFrame, instead create your application entire on a base component, like a JPanel. When you need to display it, create an instance of JFrame and add the application component to it. This way your application becomes more flexible in terms of deployment and re-use

Upvotes: 2

Related Questions