HirstDots.java
package npw;
import painter.SPainter;
import shapes.SCircle;
import javax.swing.*;
import java.awt.*;
import java.util.Random;
import java.util.Scanner;
import static javax.swing.SwingUtilities.invokeLater;

        public class HirstDots {
            private int width = getNumber("width");
            private int height = getNumber("height");
            private int dotSpacing = getNumber("dot spacing");

            private HirstDots() {
                paintTheImage();
            }
            public static void main(String[] args) {
                invokeLater(HirstDots::new);
            }

            private void paintTheImage(){
                SPainter painter = new SPainter("Hirst Dots", width, height);
                SCircle dot = new SCircle(5);
                painter.mfd(height/2 - 10);
                painter.tl(90);
                painter.mfd(width/2 - 10);
                painter.tl(90);
                 // Paint it!
                paintGradient(painter, dot, height, width, dotSpacing);
            }

            private static int getNumber(String prompt) {
                String nss = JOptionPane.showInputDialog(null,prompt + "?");
                Scanner scanner = new Scanner(nss);
                return scanner.nextInt();
            }

             // Supports double precision floating point numbers as spacingFactor values
             private void paintGradient(SPainter painter, SCircle dot, int height, int width, int colWidth){
                 int cols = 0;

                int nrOfCols = ( width / colWidth ) - 2;

                while (cols < nrOfCols){
                    nextCol(painter, colWidth);
                    cols = cols + 1;
                    paintColumn(painter, dot, height);
                }
            }
            private void paintOneDot(SPainter painter, SCircle dot){
                painter.setColor(randomColor());
                painter.paint(dot);
            }

            private void paintColumn(SPainter painter, SCircle dot, int height) {
                int travel = dotSpacing;
                int totalDistanceTraveled = 0;

                while(totalDistanceTraveled < height) {
                    painter.mfd(travel);
                    paintOneDot(painter, dot);
                    totalDistanceTraveled = totalDistanceTraveled + travel;
                }
                      // Make the method invariant with respect to painter position.
                painter.mbk(totalDistanceTraveled);
            }
          // Moves the painter to the next column.
            private void nextCol(SPainter painter, double colWidth){
                painter.tl(90);
                painter.mfd(colWidth);
                painter.tr(90);
            }
            private Color randomColor() {
                Random rgen = new Random();
                int r = rgen.nextInt(255);
                int g = rgen.nextInt(255);
                int b = rgen.nextInt(255);
                return new Color(r, g, b);
            }
        }