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