novar
novar

Reputation: 35

paintComponent is executing twice

This is bothering me, my code works and runs but when I went to run it, it seems to be looping my for loops twice, can anyone help me with my logic? Thanks...

package pkgcirc;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;

/*
* Notes:
* Draw 20 circles
* radius/location (x/y/r) all random
* if (circle) is between radii pt (step thru loop) of all values, if its within ,
*  draw it cyan if it overlaps, else black
*  
*/
public class Main extends JPanel {
    int[] radius = new int [3];
    int[] xArray = new int [3];
    int[] yArray = new int [3];

    public Main()
    {       
        Random g = new Random();
        setPreferredSize (new Dimension(300, 200));
        for(int i = 0; i < radius.length; i++)
        {
            radius[i] = g.nextInt(50)+1;
            xArray[i] = g.nextInt(250)+1;
            yArray[i] = g.nextInt(150)+1;
        }
    }

    public void paintComponent(Graphics page)
    {
        super.paintComponent(page);
        for(int i = 0; i < radius.length; i++)
        {
            for (int j = 0; j < radius.length; j++)
            {
                int xpoint1 = xArray[i]+radius[i];
                int ypoint1 = yArray[i]+radius[i];
                int xpoint2 = xArray[j]+radius[j];
                int ypoint2 = yArray[j]+radius[j];
                int radius1 = radius[i];
                int radius2 = radius[j];
                boolean Collide = circlesCollide(xpoint1, ypoint1, radius1, radius2, xpoint2, ypoint2);

                if (i != j && Collide == false)
                {
                    page.setColor(Color.cyan);
                    page.fillOval(xArray[i] ,yArray[i], radius[i], radius[i]);
                    System.out.println("false");
                }
                else{
                    System.out.println("true");
                    page.setColor(Color.black);
                    page.drawOval(xArray[j] ,yArray[j], radius[j], radius[j]);
                }
            }
            System.out.println("BREAK");    
        }
    }

    public boolean circlesCollide(double x1, double y1, double r1, double x2, double y2, double r2){
        return (distance(x1, y1, x2, y2) <= (r1 + r2));
    }

    public double distance(double x1, double y1, double x2, double y2) {
        return Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
    }       

    public static void main (String[] args)
    {
        JFrame frame = new JFrame ("Circles");
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add (new Main());

        frame.pack();
        frame.setVisible(true);
    }
}

Upvotes: 2

Views: 3373

Answers (2)

sarnold
sarnold

Reputation: 104110

       for(int i = 0; i < radius.length; i++)
       {
           for (int j = 0; j < radius.length; j++)
           {

Most loops where you wish to compare every pairing of two elements together is instead written like this:

       for(int i = 0; i < radius.length; i++)
       {
           for (int j = i; j < radius.length; j++)
           {

(Note the j = i in the second loop.)

This also lets you remove the i != j test. :)

EDIT: Oops; j = i means you still need to i != j test -- if you used j = i+1 then you can remove the i != j test. Sigh. :)

Upvotes: 1

limc
limc

Reputation: 40186

Calling setPreferredSize() and pack() will cause paintComponent() to be called twice because the display needs to be redrawn for each call.

Try removing pack() and move set size to the bottom, like this:-

public Main() {
    Random g = new Random();

    //setPreferredSize(...); // commented this line

    for (int i = 0; i < radius.length; i++) {
        radius[i] = g.nextInt(50) + 1;
        xArray[i] = g.nextInt(250) + 1;
        yArray[i] = g.nextInt(150) + 1;
    }
}

public void paintComponent(Graphics page) {
        ...
}

public static void main(String[] args) {
    JFrame frame = new JFrame("Circles");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.setSize(300, 200); // added this line

    frame.getContentPane().add(new Main());

    // frame.pack(); // commented this line

    frame.setVisible(true);
}

This should work properly now.

Upvotes: 5

Related Questions