Jaja
Jaja

Reputation: 3

Array Creation Stack overflow

I'm getting an error where it would keep giving me a stack overflow. What I basically wanna do is create an Array List of objects that have rectangles. However, if any of the object overlap one another then, I would call the method again and create an array till it creates an array of objects that do not overlap. Can anyone tell me whats wrong?

public  class TokenArrayCreator {
public final int TOKEN_WIDTH= 35;

private GameToken token1;
private ArrayList<GameToken> tokenarr;
public  TokenArrayCreator()
{}


public ArrayList<GameToken> ArrayCreator()
{
    ArrayList<GameToken> tokenArray = new ArrayList<GameToken>();
    Random random = new Random();
    for(int i =0; i<=10 ;i++)
    {
 GameToken token= new GameToken(random.nextInt(300),random.nextInt(300),35,35);
tokenArray.add(token);
    }


    for(int i =0 ; i<=10 ; i++) // make two list i and j && if i != j
    { 
    for(int j= 0; j<=10 ; j++)
    {
    if(i!=j)
    {
        if(tokenArray.get(i).overlaps(tokenArray.get(j)))
        {
            TokenArrayCreator t1= new TokenArrayCreator();
            t1.ArrayCreator();
        }



    }
    else break;
    }

    }


    return tokenArray;
}  

Above is my array creator class. Below is my overlap method that is in another class.

public  boolean overlaps(VisibleShape other) 
{

GameToken other1 = (GameToken) other;
if(this.bbox.intersects(other1.bbox))
{
    return true;
}
else return false;


}

Here is the stack trace

Exception in thread "main" java.lang.StackOverflowError
at java.util.Hashtable.hash(Unknown Source)
at java.util.Hashtable.get(Unknown Source)
at javax.swing.UIDefaults.getFromHashtable(Unknown Source)
at javax.swing.UIDefaults.get(Unknown Source)
at javax.swing.MultiUIDefaults.get(Unknown Source)
at javax.swing.UIDefaults.getFont(Unknown Source)
at javax.swing.UIManager.getFont(Unknown Source)
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
at javax.swing.JComponent.setUI(Unknown Source)
at javax.swing.JPanel.setUI(Unknown Source)
at javax.swing.JPanel.updateUI(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at CircPattern.<init>(CircPattern.java:25)
at Pattern.<init>(Pattern.java:40)
at GameToken.<init>(GameToken.java:18)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:26)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)

Upvotes: 0

Views: 94

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

Basically, what you are doing, each time you find two intersecting objects, you are creating a brand new instance of TokenArrayCreator and then call it's ArrayCreator method.

This creates a brand new ArrayList and attempts to fill it again, when it finds intersecting objects, it creates a brand new instance of TokenArrayCreator and calls it's ArrayCreator....over and over again...

Apart from the fact that none of these instance have any relationship to each other (none of them knows what the other have created), it's very rare that any one would be able to create a full array of non-overlapping objects, hence your problem.

Instead, consider removing one of the offending objects from the ArrayList and continue trying to create objects until it reaches it's desired size, for example...

public class TokenArrayCreator {

    public final int TOKEN_WIDTH = 35;

    private ArrayList<Rectangle> tokenarr;

    public TokenArrayCreator() {
    }

    public void ArrayCreator() {

        tokenarr = new ArrayList<Rectangle>();
        Random random = new Random();

        int requiredObjectCount = 11;

        while (tokenarr.size() < requiredObjectCount) {

            for (int i = 0; i < requiredObjectCount - tokenarr.size(); i++) {
                Rectangle token = new Rectangle(random.nextInt(300), random.nextInt(300), 35, 35);
                tokenarr.add(token);
            }

            for (int i = 0; i < tokenarr.size(); i++) // make two list i and j && if i != j
            {
                for (int j = 0; j < tokenarr.size(); j++) {
                    if (i != j) {
                        if (tokenarr.get(i).intersects(tokenarr.get(j))) {
                            tokenarr.remove(j);
                        }
                    }
                }
            }

        }

    }

    public ArrayList<Rectangle> getList() {
        return tokenarr;
    }

}

Now, from my persepective, this probably isn't the "fastest" solution, in that you will need to loop multiple times to get the ArrayList to fill properly and the it's not time consistent (each time you run it, it will take a different time to run) and there is a very small chance that it will never return (depending on the available size and the number of objects you create), but it will solve your immeditate problem

Upvotes: 2

Related Questions