My assignment is to draw horizontal lines random in width and random line thickness. When I run my program the thickness changes part way through. I don't understand how that is possible since I am setting the width then drawing the line. I don't update so I am not redrawing the line as far as I am aware. The only other code in the program is a init() as we have to do it in an applet.
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
int increment = 70; // space between lines
int linesNum = 5; // number of lines were drawing
Random rand = new Random();
int randW;
Line2D.Float[] lines = new Line2D.Float[linesNum];
for (int y = 0; y < linesNum; y++) {
// where we are at on they axis
int yoffset = (increment * y) + increment;
// random width of line max 499 min 50
randW = rand.nextInt((499 - 5) + 1) + 5;
// random thick line
g2.setStroke(new BasicStroke(rand.nextInt((increment - 10) + 1) + 5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
lines[y] = new Line2D.Float(1, yoffset, randW, yoffset);
g2.draw(lines[y]);
}
}
}
Every time the applet is repainted, which could happen due to the window moving, being minimized and restored, or being obscured by another window and then revealed, the paint
method will be called again, and thus will create a new Random()
and will redraw the lines at new random thicknesses. If you don't want that to happen, there are a few approaches you can take.
You can use the createImage
method to create a buffer to draw lines on. Use its getGraphics
method to get the Graphics
object, draw the lines, and then in your paint
method just draw this buffer on the screen using the drawImage
method of the Graphics
object that is passed into paint
. Declare the off-screen buffer as a field of your applet class. Since you'll only be drawing on the buffer once, it won't matter how many times your applet gets repainted.
There are two places in your paint
method where you call rand.nextInt
; you could create two int[]
arrays of size linesNum
, declare them as fields of your applet, and populate them in your init
method using a Random
object. Then, in your paint
method, instead of generating random numbers, just re-use the ones you had previously stored in these arrays. That way, no matter how many times your applet is repainted, you'll get the same result.
In your paint
method you create a new Random()
object. You can seed the random number generator (RNG), either by calling the constructor that takes a seed as a parameter or by calling the setSeed
method on it. If you use the same seed, you'll always get the same sequence of pseudorandom numbers. If you want each run of your applet to have different random line widths (but not for them to change on each repaint), you could create a Random
object and use its nextLong
method to pick a random seed when your applet starts, store that seed in a field of your applet class, and then use it to seed the RNG in your paint
method. In this way, you'll get the same sequence of random numbers every time paint
is called.