Snowflake
Snowflake

Reputation: 115

Placement of a JPanel within a JPanel

I'm trying to code a simple Pong and I have the background panel which contains a Bar panel. So of course I need to be able to place the bar on the size and move it vertically at request. Now I'm just trying to put it in a starting position. If I don't disable the layout the bar gets placed in the top center regardless of location setting, but if I disable the layout and set location it just doesn't show up. I'm not sure what I missing. Here is a code snippet if it can be relevant:

public PongPanel() {
    setLayout(null);
    setPreferredSize(SIZE);
    setBackground(Color.BLACK);
    player_one_bar = new Bar();
    add(player_one_bar);
    player_one_bar.setLocation(10, getSize().height/2-3);
}

Upvotes: 0

Views: 80

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

If by "bar" you mean Pong game paddle, then it shouldn't be a component at all but rather a logical entity that represents a position, which is visually represented by a sprite that gets drawn in the JPanel's paintComponent method.

For example:

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class PongPaddle extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = 500;
   private static final int RECT_X = 20;
   private static final int RECT_W = 10;
   private static final int RECT_H = 60;
   private static final int STARTING_Y = (PREF_H - RECT_H) / 2;
   private static final int TIMER_DELAY = 15;
   private static final int DELTA_PADDLE = 3;
   private boolean paddle1GoingDown = true;
   private boolean paddle2GoingDown = false;
   private Rectangle paddle1 = new Rectangle(RECT_X, STARTING_Y, RECT_W, RECT_H);
   private Rectangle paddle2 = new Rectangle(PREF_W - RECT_X - RECT_W,
         STARTING_Y, RECT_W, RECT_H);

   public PongPaddle() {
      setBackground(Color.black);
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         int deltaPaddle1 = paddle1GoingDown ? 1 : -1;
         deltaPaddle1 *= DELTA_PADDLE;

         int x = paddle1.getLocation().x;
         int y = paddle1.getLocation().y + deltaPaddle1;

         if (y + RECT_H >= PREF_H) {
            paddle1GoingDown = false;
         }
         if (y <= 0) {
            paddle1GoingDown = true;
         }         
         paddle1.setLocation(x, y);

         int deltaPaddle2 = paddle2GoingDown ? 1 : -1;
         deltaPaddle2 *= DELTA_PADDLE;

         x = paddle2.getLocation().x;
         y = paddle2.getLocation().y + deltaPaddle2;

         if (y + RECT_H >= PREF_H) {
            paddle2GoingDown = false;
         }
         if (y <= 0) {
            paddle2GoingDown = true;
         }         
         paddle2.setLocation(x, y);

         repaint();

         if (!PongPaddle.this.isShowing()) {
            ((Timer) e.getSource()).stop();
         }
      }
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setColor(Color.white);
      if (paddle1 != null) {
         g2.fill(paddle1);
      }
      if (paddle2 != null) {
         g2.fill(paddle2);
      }
   }

   private static void createAndShowGui() {
      PongPaddle mainPanel = new PongPaddle();

      JFrame frame = new JFrame("PongPaddle");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Upvotes: 3

Amir Keren
Amir Keren

Reputation: 211

If you set the layout manager as null you'll have to specify the exact coordinates of the panel, meaning something like -

setBounds(10, 10, 20, 100);

Will put the panel at location (10,10) with Width of 20 and Height of 100.

Upvotes: 3

Related Questions