Reputation: 570
I'm a beginner trying to create a game. The game is empty, I didn't start to write it.
My problem: when I click in the start button I want to start the game in the same frame, but with this code when I'll click on start the program opens another frame with the menu, and in the original frame will delete the panel.
How can I do this simple menu?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import panelimage.Image;
public class Project0 extends JFrame{
private static final long serialVersionUID = 1L;
private Game JPanelGame;
private Image MainMenu = new Image(new File("src/img/menu_background.jpg"));
JButton start = new JButton("START GAME"), exit = new JButton ("LEAVE GAME");
public Project0() {
super();
initFrame();
initMenu();
this.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
JPanelGame.keyPressed(evt);
}
public void keyReleased(KeyEvent evt) {
JPanelGame.keyReleased(evt);
}
});
}
private void initFrame() {
setResizable(false);
setBounds(new Rectangle(400, 400, 600, 400));
MainMenu.setLayout(new BorderLayout());
}
private void initMenu() {
initButtons();
MainMenu.setLayout(null);
MainMenu.add(start);
MainMenu.add(exit);
add(MainMenu);
setContentPane(MainMenu);
setTitle("Project0");
}
private void initButtons() {
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
JPanelGame = new Game();
remove(MainMenu);
add(JPanelGame, BorderLayout.CENTER);
setContentPane(JPanelGame);
invalidate(); validate();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Project0 Game = new Project0();
Game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game.setVisible(true);
}
});
}
});
start.setLocation(225,100);
start.setSize(150,50);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
exit.setLocation(225,200);
exit.setSize(150,50);
}
public static void main(String[] args) {
Project0 Game = new Project0();
Game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game.setVisible(true);
}
}
and this frame will start
import java.awt.*;
import java.awt.event.KeyEvent;
import javax.swing.*;
import java.io.File;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import highscores.*;
public class Game extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
Thread game;
BufferedImage background;
HighscoreManager scores = new HighscoreManager();
public Game(){
super(true);
try{
background = ImageIO.read(new File(""));
}catch(Exception e) {}
game=new Thread(this);
game.start();
}
public void paintComponent(Graphics graphic2d){
setOpaque(false);
super.paintComponent(graphic2d);
graphic2d.drawImage(background, 0, 0, null);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
}
if (key == KeyEvent.VK_RIGHT) {
}
if (key == KeyEvent.VK_UP) {
}
if (key == KeyEvent.VK_DOWN) {
}
if (key == KeyEvent.VK_A) {
}
if (key == KeyEvent.VK_D) {
}
if (key == KeyEvent.VK_W) {
}
if (key == KeyEvent.VK_S) {
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
}
if (key == KeyEvent.VK_RIGHT) {
}
if (key == KeyEvent.VK_UP) {
}
if (key == KeyEvent.VK_DOWN) {
}
if (key == KeyEvent.VK_A) {
}
if (key == KeyEvent.VK_D) {
}
if (key == KeyEvent.VK_W) {
}
if (key == KeyEvent.VK_S) {
}
}
public void run(){
try {Thread.sleep(50);}catch(InterruptedException ex){}
}
}
Upvotes: 1
Views: 9300
Reputation: 36601
I see two options, depending on your needs. Either you just remove all components from the frame and add the new contents. But by doing so, you loose your 'menu-frame'. The other option (and IMO the best of the two) is to opt for a CardLayout
, where one card is your menu and the other your game. The 'start' button would then simply switch from the 'menu-card' to the 'game-card' (and if needed start the game). In your game, you can have a button/key/... which does the inverse (switching from the game card to the menu card)
I was going through your code but I gave up (certainly since @orzechowskid already pointed out what you need to adjust). A few tips in case you are going to post more code on this site:
panelimage.Image
class which has nothing to do with the java.awt.Image
class And then a few Swing related tips based on what I saw of your code:
LayoutManager
s and get rid of the null
layouts. The Visual guide to layout managers might be a good starting pointThread.sleep
usage and running multiple Thread
s in combination with a Swing UI. Make sure you are aware of the Swing threading rulesUpvotes: 2
Reputation: 6090
when you call SwingUtilities.invokeLater()
inside your button's action listener, you're creating a second Project0
object. And whenever you create a Project0
, you get a JFrame drawn on screen with a main menu inside of it. Remove the call to SwingUtilities.invokeLater()
and you should be left with a single frame.
Upvotes: 1