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   import static javax.swing.SwingUtilities.*;
16   
17   public class AbstractGradient {
18   
19       public static void main(String[] args) {
20           invokeLater( AbstractGradient::new );
21       }
22   
23       private AbstractGradient() {
24           paintTheImage();
25       }
26   
27       private void paintTheImage(){
28           // Grab the input information
29           int width = getNumber("width");
30           int height = getNumber("height");
31           int colWidth = getNumber("column width");
32           // Establish the painter
33           SPainter painter = new SPainter("Abstract Gradient", width, height);
34           SCircle dot = new SCircle(5);
35   
36           // Move the painter to the upper left corner to get ready to paint the gradient
37           painter.mfd(height/2);
38           painter.tl(90);
39           painter.mfd(width/2 - 10);
40           painter.tl(90);
41   
42           // Paint it!
43           paintGradient(painter, dot, height, width, colWidth);
44       }
45   
46       private static int getNumber(String prompt) {
47           String nss = JOptionPane.showInputDialog(null,prompt+"?");
48           Scanner scanner = new Scanner(nss);
49           return scanner.nextInt();
50       }
51   
52       private void paintGradient(SPainter painter, SCircle dot, int height, int width, int colWidth){
53           int cols = 0;
54           // Calculate the number of columns. We want to fill the screen, but we don't want
55           // any dots only half on the canvas, so we subtract some space.
56           int nrOfCols = ( width / colWidth ) - 2;
57   
58           while (cols < nrOfCols){
59               nextCol(painter, colWidth);
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 tighter together near the bottom of the canvas.
70       private void paintColumn(SPainter painter, SCircle dot, int height) {
71           int travel = 0;
72           int totalDistanceTraveled = 0;
73   
74           // Paint a row with decreasing distance between dots.
75           while(totalDistanceTraveled < height - (dot.radius() * 3)) {
76               travel = randomDistance((height - totalDistanceTraveled) / 4);
77               totalDistanceTraveled = totalDistanceTraveled + travel;
78               painter.mfd(travel);
79               paintOneDot(painter, dot);
80           }
81   
82           // Make the method invariant with respect to painter position.
83           painter.mbk(totalDistanceTraveled);
84       }
85   
86       // Moves the painter to the next column.
87       private void nextCol(SPainter painter, int colWidth){
88           painter.tl(90);
89           painter.mfd(colWidth);
90           painter.tr(90);
91       }
92   
93       private int randomDistance(int maxDistance){
94           Random rgen = new Random();
95           return rgen.nextInt(maxDistance);
96       }
97   }