0

I'm making a program that has circles bounce around inside of a frame, I have done this before in python, but I did not encounter the weird issue I'm getting right now.

I have tried setting my JFrame size in several different ways and no matter what it is always inconsistent. I have it currently set to (600, 600) and when I call getSize() it returns (578, 544) which I assume is due to the bordering of the window, but even when I hardcode in those numbers, it still has a bizarre bounds. each circle seems to create its own bounds, and I cannot figure out why.

public Circle(Color fillColor, Color borderColor, int x, int y, int radius, String direction)
{
    super(fillColor, borderColor, x, y, (2*radius), (2*radius));
    this.radius = radius;
    this.direction = direction;
    rectShell=getBounds();
    switch(direction)
    {
        case "N" : dx = 0; dy = -1;
                   break;
        case "NW": dx = -1; dy = -1;
                   break;
        case "W" : dx = -1; dy = 0;
                   break;
        case "SW": dx = -1; dy = 1;
                   break;
        case "S" : dx = 0; dy = 1;
                   break;
        case "SE": dx = 1; dy = 1;
                   break;
        case "E" : dx = 1; dy = 0;
                   break;
        case "NE": dx = 1; dy = -1;
                   break;
    }
}


public void wallCollision(int width, int height)
{
    int x = getX();
    int y = getY();

    if(x <= 0 && (direction.equals("W") || direction.equals("NW") || direction.equals("SW")))
    {
        if(direction.equals("W"))
        {
            direction = "E";
        }
        else if(direction.equals("NW"))
        {
            direction = "NE";
        }
        else
        {
            direction = "SE";
        }
        switchDx();
    }
    if(y <= 0 && (direction.equals("N") || direction.equals("NE") || direction.equals("NW")))
    {
        if(direction.equals("N"))
        {
            direction = "S";
        }
        else if(direction.equals("NE"))
        {
            direction = "SE";
        }
        else
        {
            direction = "SW";
        }
        switchDy();
    }
    if(x+getWidths() >= 578 && (direction.equals("E") || direction.equals("NE") || direction.equals("SE")))
    {
        System.out.println("Collision");
        if(direction.equals("E"))
        {
            direction = "W";
        }
        else if(direction.equals("NE"))
        {
            direction = "NW";
        }
        else
        {
            direction = "SW";
        }
        switchDx();
    }
    if(y+getHeights() >= 544 && (direction.equals("S") || direction.equals("SW") || direction.equals("SE")))
    {
        if(direction.equals("S"))
        {
            direction = "N";
        }
        else if(direction.equals("SE"))
        {
            direction = "NE";
        }
        else
        {
            direction = "NW";
        }
        switchDy();
    }

}

Here is the JFrame class

public ShapeGenerator2()
{
    setSize(600,600);
    setTitle("Random Shapes");
    getContentPane().setBackground(Color.ORANGE);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    addKeyListener(new Key());

    timer = new Timer(20, this);
    timer.start();


}


@Override
public void actionPerformed(ActionEvent e)
{
    for(Circle c: circles)
    {
        System.out.println("("+c.getX()+","+c.getY()+") Moving "+c.getDirection()+" ("+(c.getX()+c.getRadius())+", "+(c.getY()+c.getRadius())+")");
        c.wallCollision(getWidth(), getHeight());
        if(circles.size()>1)
        {
            for(Circle i: circles)
            {
                if(i!=c)
                c.hitCircle(i, false);
            }
        }
        c.move();
        System.out.println(getSize());
        System.out.println("("+getContentPane().getWidth()+", "+getContentPane().getHeight()+")");
    }
}

public class Key implements KeyListener
{
    @Override
    public void keyPressed(KeyEvent e)
    {
        Random r = new Random();
        Color fillColor = new Color(r.nextFloat(), r.nextFloat(), r.nextFloat());
        Color borderColor = new Color(r.nextFloat(), r.nextFloat(), r.nextFloat());
        switch(e.getKeyCode())
        {
            case KeyEvent.VK_C: boolean goodCircle = false;
                                Circle ci = null;
                                while(!goodCircle)
                                {
                                    ci = new Circle(fillColor, borderColor, r.nextInt(200), r.nextInt(200), r.nextInt(150), directions[r.nextInt(directions.length)]);
                                    goodCircle = true;
                                    for(Circle c: circles)
                                    {
                                        if(ci.hitCircle(c,true))
                                        {
                                            goodCircle = false;
                                            break;
                                        }
                                    }
                                    //goodCircle = true;
                                }
                                add(ci);
                                circles.add(ci);
                                break;
        }


        setVisible(true);
    }

Ellipse, which is the super class of Circle

public class Ellipse extends Shape
{
private int width;
private int height;
private Color fillColor;

public Ellipse(Color fillColor, Color borderColor, int x, int y, int width, int height)
{
    super(fillColor, borderColor, x, y);
    this.width = width;
    this.height = height;
}

public Ellipse(int x, int y, int width, int height)
{
    super(Color.WHITE, Color.BLACK, x, y);
    this.width = width;
    this.height = height;
}

public int getWidths()
{
    return width;
}

public int getHeights()
{
    return height;
}
    @Override
void draw(Graphics g)
{
    g.setColor(getFillColor());
    g.fillOval(getX(), getY(), width, height);
    g.setColor(getBorderColor());
    g.drawOval(getX(), getY(), width, height);
    g.setColor(Color.BLACK);
    g.drawRect(getBounds().x,getBounds().y,getBounds().width, getBounds().height/*getX(), getY(), width, height*/);
}

public Rectangle getBounds()
{
    return new Rectangle(getX(), getY(), width, height);
}

}

Sorry for all the code. I have never been more lost on something that seems so trivial. Thanks for any help.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    You basic problem comes down to a misunderstanding in how the frame and content size information works. I would recommend having a look at [How to get the EXACT middle of a screen, even when re-sized](https://stackoverflow.com/questions/13457237/how-to-get-the-exact-middle-of-a-screen-even-when-re-sized/13460914#13460914) as it explains the basic difference. This is just one of the many reasons why we discourage extending directly from `JFrame` and instead work with components like `JPanel` – MadProgrammer Mar 20 '18 at 00:26
  • 1
    Before anyone suggests it - DON'T try and "guess" at the frame borders, they change - better to start with a `JPanel` and use it's `width` and `height` properties appropriately – MadProgrammer Mar 20 '18 at 00:29
  • 1
    If, none of this helps, consider providing a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) which will provide us with a better idea of what you're doing and improve the chances of getting a quality answer - rather then just a bunch of rep-guessing – MadProgrammer Mar 20 '18 at 00:32
  • Okay so if I go with the `JPanel` route, should I extend `JPanel` with a new class and use a separate main class and use `JFrame` There? – Jimmy Conway Mar 20 '18 at 01:45
  • As a general preference, yes. I prefer to not to extend from `JFrame` or most top level containers and instead, simply create an instance of them as I need to – MadProgrammer Mar 20 '18 at 01:51
  • Okay, thank you! I don't know `JPanel` very well, for whatever reason we were told `JFrame` would be easier but I think I'm going to rework all of it. – Jimmy Conway Mar 20 '18 at 01:54

0 Answers0