samedi 3 octobre 2015

Why would random.nextInt(500)+1 yield negative int?

Language: Java

Aim: generate frames with a (partially) random amount of random images.

Problem: reoccurring error: Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: bound must be positive. This error occurs, but not every time I run the program. Apparently the use of random integers is somehow allowed to produce interfering numbers.

Question: I'm using random.nextInt(n)+1 in most of the parameters. If I recall correctly, this yields a random integer between 0 and n. Why would I get an error stating that a bound must be positive? or: Why would I be required to give positive bounds and where can I fix that?

Reviewing: I've looked at every random-int generator in my code and followed the path of its use, but I can't find anything that would be disrupted by a random integer between 0 and the usual 500.

Here are the first lines of the error I keep getting:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: bound must be positive at java.util.Random.nextInt(Unknown Source) at RandomTree.(RandomTree.java:20) at Cara.initializeShapes(Cara.java:64) at Cara.regenerate(Cara.java:54) at Cara.actionPerformed(Cara.java:45) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)

code:

The part of my code that I think is relevant.

public class Cara extends JPanel implements ActionListener {
Random random = new Random();
ArrayList<RandomShape> shapes = new ArrayList<RandomShape>(); //initialize the arraylist    
//initialize shapes in arraylist
PondBackground pond;
RandomLily randomLily, randomLily2, randomLily3, randomLily4;
RandomTree randomTree, randomTree2; 
RandomPiearc randompiearc, randompiearc2;

public Cara() {

    setPreferredSize(new Dimension(1000,800)); // make panel x by y pixels
    initializeShapes(); 
    addshapes();
}

@Override
protected void paintComponent(Graphics g) { 
    super.paintComponent(g);     // clears the background
    // draw all shapes       

    for(int i = 0; i < shapes.size(); i++){
        shapes.get(i).draw(g);
    } 
}


void initializeShapes(){
    pond = new PondBackground(10,10);
    randomLily = new RandomLily(random.nextInt(100)+101, random.nextInt(100)+101);
    randomLily2 = new RandomLily(random.nextInt(100)+601, random.nextInt(100)+201);
    randomLily3 = new RandomLily(random.nextInt(100)+401, random.nextInt(100)+401);
    randomLily4 = new RandomLily(random.nextInt(100)+201, random.nextInt(100)+601);
    randomTree = new RandomTree(random.nextInt(500)+1,   random.nextInt(500)+1);
    randomTree2 = new RandomTree(random.nextInt(500)+1, random.nextInt(500)+1);
    randompiearc = new RandomPiearc(random.nextInt(500)+1, random.nextInt(500)+1);
    randompiearc2 = new RandomPiearc(random.nextInt(500)+1, random.nextInt(500)+1);
}

I'll also include the one of the classes which objects are added to the ArrayList, but I wouldn't know what would be wrong there. superclass:

abstract class RandomShape {  
static Random random = new Random();

/** color used for drawing this shape **/
protected Color color;  
/** position of the shape (upper left corner) **/
protected int x, y;  

/**
 * initializes color and position to random values
 * 
 * @param maxX, maxY give maximum values for the position
 */
public RandomShape( int maxX, int maxY ) {
    // initialize to a random position
    x = random.nextInt(maxX);
    y = random.nextInt(maxY);
    // initialize to a random color
    //...
}

abstract void draw(Graphics g);
 }

Example subclass:

class RandomTree extends RandomShape {
private int crownRadius;   
private int trunkHeight;
private int trunkWidth;
private boolean fill; // filled or not?

public RandomTree(int maxX, int maxY) {
    super(maxX, maxY);

    crownRadius = random.nextInt(maxX/4); // or something more sophisticated
    trunkHeight = random.nextInt((maxY-2*crownRadius)/2);
    trunkWidth = crownRadius/3 + 1;
    fill = random.nextBoolean();
    color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
}

@Override
void draw(Graphics g) {
    // draw crown
    g.setColor(color);
    if (fill) {
        // more general way to draw an oval
        g.fillArc(x, y, 2*crownRadius, 2*crownRadius, 0, 360);
    } else { 
        g.drawArc(x, y, 2*crownRadius, 2*crownRadius, 0, 360);
    }

    // draw trunk
    g.setColor(color);
    int xx = x + crownRadius - trunkWidth/2;
    int yy = y + 2*crownRadius;
    if (fill) {
        g.fillRect(xx, yy, trunkWidth, trunkHeight);
    } else { 
        g.fillRect(xx, yy, trunkWidth, trunkHeight);
    }
}    
}




Aucun commentaire:

Enregistrer un commentaire