0

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);
}
Snowflake
  • 115
  • 4

2 Answers2

3

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.

Amir Keren
  • 201
  • 2
  • 7
  • 3
    *"Will put the panel at location (10,10) with Width of 20 and Height of 100.."* ..and create the next 3 bugs in the process. Java GUIs have to work on different OS', screen size, screen resolution etc. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Dec 21 '14 at 14:01
  • I agree with Andrew, this is a "last resort" kind of way. You can set the dimensions to be relative to the screen's width and height but you could have issues when moving between different screen sizes. – Amir Keren Dec 21 '14 at 14:04
  • 1
    *"I agree with Andrew, this is a "last resort" kind of way."* No, the 'last resort' is a custom layout manager that still respects the preferred, smallest and largest size of the child components.. See [`setLayout(null)` is *never* necessary. **Ever!**](https://community.oracle.com/thread/1353374?tstart=0) at the Oracle forums. It was started by yours truly, and no argument presented was able to sway me to think differently. – Andrew Thompson Dec 21 '14 at 14:09
3

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();
         }
      });
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373