ColorfulAbstractGradient.java
1    package npw;
2    
3    import painter.SPainter;
4    import shapes.SCircle;
5    
6    import javax.swing.*;
7    import java.awt.*;
8    import java.util.Random;
9    import java.util.Scanner;
10   
11   public class ColorfulAbstractGradient {
12       public static void main(String[] args) {
13           SwingUtilities.invokeLater(ColorfulAbstractGradient::new);
14       }
15       public ColorfulAbstractGradient() {
16           paintTheImage();
17       }
18       private void paintTheImage(){
19           // Grab the input information
20           int width = getNumber("width");
21           int height = getNumber("height");
22           int dotSpace = getNumber("horizontal space between dots");
23           // Establish the painter
24           SPainter painter = new SPainter("Abstract Gradient", width, height);
25           SCircle dot = new SCircle(5);
26           // Move the painter to the upper left corner to get ready to paint the gradient
27           painter.mfd(height/2.0);
28           painter.tl();
29           painter.mfd(width/2.0);
30           painter.tl();
31           // Paint it!
32           paintGradient(painter, dot, height, width, dotSpace);
33       }
34       private static int getNumber(String prompt) {
35           String nss = JOptionPane.showInputDialog(null,prompt+"?");
36           Scanner scanner = new Scanner(nss);
37           return  scanner.nextInt();
38       }
39       private void paintGradient(SPainter painter, SCircle dot, int height, int width, int dotSpace){
40           // Calculate the number of columns. We want to fill the screen, but don't want any columns half on the canvas.
41           // A column takes up the horizontal space of a dot's diameter plus the space between it and a neighbor.
42           double colWidth = dot.diameter() + dotSpace;
43           // We don't want a column all the way on the edge on the right side, so subtract 1.
44           int nrOfCols = (int) Math.floor((width / colWidth)) - 1;
45           int cols = 0;
46           while (cols < nrOfCols){
47               nextCol(painter, dot, dotSpace);
48               paintColumn(painter, dot, height);
49               cols = cols + 1;
50           }
51       }
52       private void  paintOneDot(SPainter painter, SCircle dot){
53           painter.setColor(randomColor());
54           painter.paint(dot);
55       }
56       // Dots are spaced more tightly together near the bottom of the canvas.
57       private void paintColumn(SPainter painter, SCircle dot, int height) {
58           int totalDistanceTraveled = 0;
59           // Paint a column with decreasing distance between dots.
60           while (totalDistanceTraveled < height - (dot.radius()*3)){
61               int travel = randomDistance((height-totalDistanceTraveled) / 4);
62               totalDistanceTraveled = totalDistanceTraveled + travel;
63               painter.mfd(travel);
64               paintOneDot(painter, dot);
65           }
66           // Make the method invariant with respect to painter position.
67           painter.mbk(totalDistanceTraveled);
68       }
69       // Moves the painter to the next column.
70       private void nextCol(SPainter painter, SCircle dot, int dotSpace){
71           painter.tl();
72           painter.mfd(dot.diameter() + dotSpace);
73           painter.tr();
74       }
75       private  int randomDistance(int maxDistance){
76           Random rgen = new Random();
77           return  rgen.nextInt(maxDistance);
78       }
79       private static Color randomColor() {
80           Random rgen = new Random();
81           int r = rgen.nextInt(256);
82           int g = rgen.nextInt(256);
83           int b = rgen.nextInt(256);
84           return new Color( r, g, b);
85       }
86   }
87