Search code examples
javalocationjpanelsizepong

JPanel Location and Size changing weird


I'm about to program a little version of "Pong". But I've already got a problem with my JPanels. The size of the Shields is changing pretty weird to 10 from 100. And there is no method that changes the size of it! Also the Shields jump to the upper middle of the JPanel. They aren't expect to do that. Seen on the two screenshots at the ent of the post. (Puu.sh)

Sorry if I'm just missing something obvious, but as I said, I'm training.

Main with psvm()

public class Main {

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

}

Field (Frame with the Game in it)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;

public class Field extends JFrame {

private Room room = new Room();

public Field() {

    this.setSize((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 1.5), (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 1.5));
    this.setLayout(null);
    this.setLocation((int) ((Toolkit.getDefaultToolkit().getScreenSize().getWidth() - (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 1.5)) / 2), (int) ((Toolkit.getDefaultToolkit().getScreenSize().getHeight() - (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 1.5)) / 2));
    this.getContentPane().setBackground(Color.GRAY);
    this.setResizable(true);
    this.setEnabled(true);
    this.setMinimumSize(new Dimension(1000, 455));
    if (getHeight() < 455) {
        this.setSize(getWidth(), 455);
    } else if (getWidth() < 1000) {
        this.setSize(1000, getHeight());
    }

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    this.add(room);

    this.setVisible(true);
    addMouseListener(this);

    this.addComponentListener(new ComponentAdapter() {
        public void componentResized(ComponentEvent evt) {
            room.updateLocation(getSize());
        }
    });


}

}

Room

import javax.swing.*;
import java.awt.*;
public class Room extends JPanel {


private Shield shieldL = new Shield(0); // LEFT side
private Shield shieldR = new Shield(1); // RIGHT side

public Room() {

    this.setBackground(new Color(122, 197, 205));

    this.add(shieldL);
    this.add(shieldR);
}

public void updateLocation(Dimension d) {
    this.setSize((int) d.getWidth(), (int) (d.getHeight() - (d.getHeight() / 5)));
    this.setLocation(0, (int) (d.getHeight() / 10));
    shieldL.updateLocation(getSize());
    shieldR.updateLocation(getSize());
    this.setVisible(true);

}
}

Shield

import javax.swing.*;
import java.awt.*;

public class Shield extends JPanel {

private int side = 0;

public Shield(int s) { //0 = Left  |  1 = Right

    side = s;
    this.setSize(10, 100);
    this.setBackground(Color.white);

}

public void updateLocation(Dimension d) {   //Bug found here
    System.out.println(getSize());          //Bug seems not to be created here?
    int xPos;
    if (side == 0) {
        xPos = (int) (d.getWidth() / 8);
    } else {
        xPos = (int) (d.getWidth() / 8 * 7 - this.getWidth() / 2);
    }
    this.setLocation(xPos, (int) (d.getHeight() / 2 - (getHeight() / 2)));
    this.setVisible(true);
}

}

They end up like this:, switching the location at randome framesize changings.

http://puu.sh/ceyE0/ef15ee1748.png

http://puu.sh/ceyFN/122174db48.png

Thanks! Julian :)


Solution

  • In Shield, change the line

    setSize(10, 100);
    

    to

    setPreferredSize(new Dimension(10, 100));
    

    Do not use setSize methods, they are called internally.

    Edit:

    Try only these 2 classes:

    public class Field extends JFrame {
    
        private Room room = new Room();
    
        public Field() {
    
            //Mock panel
            JPanel filler = new JPanel();
            filler.setOpaque(false);
    
            getContentPane().setBackground(Color.GRAY);
            getContentPane().add(filler, BorderLayout.PAGE_START);
            getContentPane().add(room);
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setMinimumSize(new Dimension(1000, 455));
            setLocationRelativeTo(null);
            pack();
            room.init();
            setVisible(true);
        }
    }
    

    public class Room extends JPanel {
    
        private static int leftWidth = 100;
        private static int leftHeight = 100;
        private static int leftX;
        private static int leftY;
    
        private static int rightWidth = 100;
        private static int rightHeight = 100;
        private static int rightX;
        private static int rightY;
    
        public Room() {
    
            setBackground(new Color(122, 197, 205));
        }
    
        void init() {
    
            leftX = getWidth() / 8;
            leftY = getHeight() / 2 - leftHeight / 2;
            rightX = getWidth() * 7 / 8;
            rightY = getHeight() / 2 - rightHeight / 2;
        }
    
        @Override
        protected void paintComponent(Graphics g) {
    
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.WHITE);
            g2d.fillRect(leftX, leftY, leftWidth, leftHeight);
            g2d.fillRect(rightX, rightY, rightWidth, rightHeight);
        }
    }