1

I'm working on this basic Pong-style game for fun but I'm having some difficulty with the GUI aspect of it. Essentially I have a JFrame called window which houses everything, and a JPanel called content. content is supposed to refer to the ContentPanel I have. Here's my source code so far (sorry it's so long, a lot of it pertains exclusively to the game and not this question but I'm not sure which parts of the source code I need for my question to make sense):

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;

public class Pong extends JApplet {


   public static void main(String[] args) {
      JFrame window = new JFrame("Pong: The Game of Champions");
      JPanel content = new JPanel();
      window.setContentPane(content);
      window.setSize(1000,600);
      window.setLocation(100,100);
      window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      window.setVisible(true);
      window.setResizable(false);

      JMenuBar settings = new JMenuBar();
      ButtonHandler listener = new ButtonHandler();
      window.setJMenuBar(settings);
      JMenu toolsMenu = new JMenu("Settings");
      settings.add(toolsMenu);
      JMenuItem preferences = new JMenuItem("Preferences");
      JMenuItem about = new JMenuItem("About");
      toolsMenu.add(preferences);
      toolsMenu.add(about);      
      about.addActionListener(listener);
      preferences.addActionListener(listener);

   }

   public void init() {
      setContentPane( new ContentPanel() );
   }

   public static class ButtonHandler implements ActionListener {
       public void actionPerformed(ActionEvent evt) {

           String command = evt.getActionCommand();

           if (command.equals("About")) {
               JOptionPane.showMessageDialog(null, "Made by Kyle Evans for Mr. Richardson's AP Computer Science class. Aww yeah.");
           }

           else if (command.equals("Preferences")) {

           }
       }
   }

   public static class ContentPanel extends JPanel implements KeyListener, FocusListener, MouseListener, ActionListener {

      private Timer timer = new Timer(10, this);
      private static final int PADDLE_WIDTH = 10;  // Length of side of square.
      private static final int PADDLE_HEIGHT = 100;
      private static final int BALL_WIDTH = 10;
      private static final int UP = 1, DOWN = 2;

      private Color squareColor;  // The color of the square.

      private int paddleOneDirection = -1;
      private int paddleTwoDirection = -1;

      private int paddleOneTop, paddleOneLeft, paddleTwoTop, paddleTwoLeft, paddleSpeed, 
                            ballTop, ballLeft, ballSpeedHorizontal, ballSpeedVertical;



      public ContentPanel() {

         paddleOneTop = 230;  // Initial position of top-left corner of square.
         paddleOneLeft = 900;
         paddleTwoTop = 230;
         paddleTwoLeft = 90;
         paddleSpeed = 4;
         ballTop = 270;
         ballLeft = 490;
         ballSpeedHorizontal = (int)(Math.random()*2);
            if (ballSpeedHorizontal == 0) {
                ballSpeedHorizontal = -1;
            }
         ballSpeedVertical = (int)(Math.random()*6) - 3;
         squareColor = Color.WHITE;  // Initial color of square.

         setBackground(Color.BLACK);

         addKeyListener(this);     // Set up event listening.
         addFocusListener(this);
         addMouseListener(this);

      } // end init();

      public void paintComponent(Graphics g) {

         super.paintComponent(g);  // Fills the panel with its
                                   // background color, which is white.

         g.setColor(squareColor);
         g.fillRect(paddleOneLeft, paddleOneTop, PADDLE_WIDTH, PADDLE_HEIGHT);
         g.fillRect(paddleTwoLeft, paddleTwoTop, PADDLE_WIDTH, PADDLE_HEIGHT);
         g.fillRect(ballLeft, ballTop, BALL_WIDTH, BALL_WIDTH);
         String messageH = "false";
         String messageV1 = "false";
         String messageV2 = "false";
         if (isHittingPaddleHorizontal()) {
             messageH = "true";
         }
         if (!isHittingPaddleHorizontal()) {
             messageH = "false";
         }
         if (isHittingPaddleOneVertical()) {
             messageV1 = "true";
         }
         if (!isHittingPaddleOneVertical()) {
             messageV1 = "false";
         }
         if (isHittingPaddleTwoVertical()) {
             messageV2 = "true";
         }
         if (!isHittingPaddleTwoVertical()) {
             messageV2 = "false";
         }
         g.drawString("Is hitting horizontal: " + messageH,7,20);
         g.drawString("Is hitting vertical right: " + messageV1,7,40);
         g.drawString("Is hitting vertical left: " + messageV2,7,60);

      }  // end paintComponent()

      // ------------------- Game controlling methods -------------------------

      public void moveBall() {

          ballLeft -= ballSpeedHorizontal;
          ballTop -= ballSpeedVertical;

          if (isHittingPaddleHorizontal()) {
              if (isHittingPaddleOneVertical()) {
                      ballSpeedHorizontal = -ballSpeedHorizontal;
                     // ballSpeedHorizontal++;
              } 
              else if (isHittingPaddleTwoVertical()) {
                     // ballSpeedHorizontal++;
                      ballSpeedHorizontal = -ballSpeedHorizontal;
              }
          }

          if ((ballTop <= 0) || (ballTop >= 565))     // Sets the vertical boundaries so the ball bounces off the top and bottom.
              ballSpeedVertical = -ballSpeedVertical;

          if ((ballLeft > 1000) || ballLeft < 0) {
              gameOver();
          }
      }

      public boolean isHittingPaddleOneVertical() {
          for (int i = 0; i < PADDLE_HEIGHT + (2 * BALL_WIDTH); i++) {
              if (ballTop == (paddleOneTop - BALL_WIDTH + i)) {
                  return true;
              }
          }
          return false;
      }

      public boolean isHittingPaddleTwoVertical() {
          for (int i = 0; i < PADDLE_HEIGHT + (2 * BALL_WIDTH); i++) {
              if (ballTop == (paddleTwoTop - BALL_WIDTH + i)) {
                  return true;
              }
          }
          return false;
      }

      public boolean isHittingPaddleHorizontal() {
          for (int i = 0; i < 50; i++) {
              if ((ballLeft == paddleOneLeft + i) || (ballLeft == paddleTwoLeft + PADDLE_WIDTH - i)) { 
                  return true;
              }
          }
          return false;
      }

      public void robotControl() {
          paddleTwoTop = ballTop - 45;
      }

      public void gameOver() {
          paddleOneTop = 230;
          paddleTwoTop = 230;
          ballTop = 270;
          ballLeft = 490;
          ballSpeedHorizontal = (int)(Math.random()*2);
            if (ballSpeedHorizontal == 0) {
                ballSpeedHorizontal = -1;
            }
          ballSpeedVertical = (int)(Math.random()*6) - 3;
      }

      // ------------------- Event handling methods ----------------------

      public void focusGained(FocusEvent evt) {
         repaint();  // redraw with cyan border
      }

      public void focusLost(FocusEvent evt) {
         repaint();  // redraw without cyan border
      }

      public void keyTyped(KeyEvent evt) {

         char ch = evt.getKeyChar();  // The character typed.

      }  // end keyTyped()

      public void keyPressed(KeyEvent evt) { 

         int key = evt.getKeyCode();  // keyboard code for the pressed key

         timer.start();

         if (key == KeyEvent.VK_UP) {  // up arrow key
             paddleOneDirection = UP;
         }
         else if (key == KeyEvent.VK_DOWN) {  // down arrow key
             paddleOneDirection = DOWN;
         }
         else {
             paddleOneDirection = -1; // This prevents other keys from interfering with the paddle movement.
         }
         if (key == KeyEvent.VK_W) {
             paddleTwoDirection = UP;
         }
         else if (key == KeyEvent.VK_S) {
             paddleTwoDirection = DOWN;
         }
         else {
             paddleTwoDirection = -1;
         }

      if ((paddleOneTop > 1000 - PADDLE_HEIGHT))
          paddleOneTop = 1000 - PADDLE_HEIGHT;
      if (paddleTwoTop > 1000 - PADDLE_HEIGHT)
          paddleTwoTop = 1000 - PADDLE_HEIGHT;


      }  // end keyPressed()

      public void keyReleased(KeyEvent evt) {
          paddleOneDirection = -1;
          paddleTwoDirection = -1;
      }

      public void mousePressed(MouseEvent evt) {
         requestFocus();
      }   

      public void mouseEntered(MouseEvent evt) { }  // Required by the
      public void mouseExited(MouseEvent evt) { }   //    MouseListener
      public void mouseReleased(MouseEvent evt) { } //       interface.
      public void mouseClicked(MouseEvent evt) { }
      public void actionPerformed(ActionEvent evt) {


          switch (paddleOneDirection) {
          case UP:
              paddleOneTop -= paddleSpeed;
              break;
          case DOWN:
              paddleOneTop += paddleSpeed;
              break;
          }
          switch (paddleTwoDirection) {
          case UP:
              paddleTwoTop -= paddleSpeed;
              break;
          case DOWN:
              paddleTwoTop += paddleSpeed;
              break;
          }
          robotControl();
          moveBall();
          repaint();
      }
   } // end nested class ContentPanel


} // end class

(The code is a bit messy, I apologize, I'm pretty new to Java and programming in general.)

Here are my questions:

  1. How do I initialize the JFrame to display the JPanel content by default?

  2. How do I begin creating a separate JPanel that I can switch between? My ultimate goal is to have a separate JPanel appear when the user clicks on "Preferences" and then be able to switch back and forth between the preferences JPanel and the content JPanel.

I would greatly appreciate any help.

Amarnath
  • 8,736
  • 10
  • 54
  • 81
Kyle Evans
  • 149
  • 1
  • 6
  • Hmmm because I see its a game, unless you must use Java only... have a look at [`Slick2D`](http://www.slick2d.org/) you will have a great game with the benefits of OpenGL (thus you need [LWGL](http://www.lwjgl.org) too but thats just a simple additional library), and a easy to use library with most needed game functions built in i.e music, game loop, sprite animation etc. This also makes it easier to incorporate physics engines which wont slow down the game like [JBox2D](http://www.jbox2d.org/) or [Dyn4j](http://www.dyn4j.org/) - I prefer the latter. – David Kroukamp Jan 24 '13 at 08:27

1 Answers1

7

Initialize as many panels with different content on JFrame creation and place them in CardLayout. Switch cards to show required panel when necessary.

StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • 3
    E.G. [this answer](http://stackoverflow.com/a/14493395/418556). It can 'deal' 150+ cards per second. ;) – Andrew Thompson Jan 24 '13 at 06:57
  • Hmm, okay. So, in the instance of my program, if I have the JPanel called content, how do I initialize the JFrame to show that JPanel by default? – Kyle Evans Jan 24 '13 at 07:07