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