Search code examples
javajframewindowjpanelscale

JAVA - creating basic 2D shapes that scale to window size


I am trying to learn Java by reading and doing examples out of a textbook I found online. I was able to do an example in the book fairly easily but want to take it one step further. When I wrote the code for a program called 'concentric circles' I noticed that my circles didn't scale to the size of the window and I think it looks horrible (If I make the window too small the circles don't scale and you only see a piece of the circles. I tweaked my code and it seems to scale a little bit but looks terrible when I make my window too small or too large. I would like my 12 circles to fit the window size no matter the size of the window. I feel like I am so close but just can't seem to wrap my head around it. Any and all help is much appreciated, thanks in advance!

import java.awt.Graphics;
import javax.swing.JPanel;

public class Circles extends JPanel
{

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        int width = getWidth();
        int height = getHeight();
        int x = width / 12;
        int y = height / 12;
        int buffersize = 0;

        for (int i = 0; i < 12; i++)
        {
            g.drawOval(width / 2 - buffersize, height / 2 - buffersize, x + buffersize * 2, y + buffersize * 2);
            buffersize += 10;
        }
    }
}

Driver class

import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 *
 * @author
 */
public class ConcentricCirclesTest 
{
    public static void main(String[] args)
    {
        //create a panel that will contain our drawing
        Circles panel = new Circles();

        //create a new frame to house the panel
        JFrame application = new JFrame();

        //set the frame to exit when closed
        application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        application.add(panel);
        application.setSize(350, 350);
        application.setVisible(true);

    }

}

Solution

  • If you want your circles to be circular (not elliptical) then first off you need to know which is narrower, the width or the height. Using the syntax shortcut for if...else you'd want something like:

    int smallest = width < height ? width : height;
    

    Next you need to think about how far apart your circles will be. It's no good trying to draw 12 circles that get bigger (or smaller) by 10 pixels if you only have 100 pixels to draw them in. Likewise if you've 500 pixels of space. So something like:

    float spacing = smallest / 12f;
    

    Note that you can get unexpected results dividing one int with another. Then in your for loop:

    g.drawOval(0 + ((spacing / 2) * i), 0 + ((spacing / 2) * i), 
               smallest - ((spacing / 2) * i), smallest - ((spacing / 2) * i));
    

    I hope thus is clear. Basically,the bounding rectangle (or square) gets smaller by spacing for each iteration.

    OK, this is going to need tweeking so it doesn't draw in the bottom left and I think the last circle would be 0 by 0 but I hope this is of some help. And good luck!