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