// Counter.java // Solution to CS 5 Short Assignment #6 by THC. // Implementation of the class Counter. // Define a class of Counter objects. A counter holds a single integer // in the range 0..(myLimit - 1). Each time tick() is called the // counter increases, wrapping back to 0 when it reaches myLimit. // This version allows us to specify how many digits a Counter displays. // It overloads the constructor, so that we can create different kinds // of Counters. It also provides a method to return the value in the // Counter and a method to reset the Counter to a particular value. // This version is more efficient because it doesn't create a // DecimalFormat object upon each call of show, instead creating a // DecimalFormat object in the constructors. It also adds a toString // method and a constructor that makes a copy of a Counter. import java.text.DecimalFormat; public class Counter { private int myLimit; // Upper limit on the counter private int myValue; // Current value private DecimalFormat myFormatter; // Formatter for displaying // Constructors for the Counter class. // Create a Counter with myLimit 10, myValue 0, and 1 digit to display. public Counter() { myLimit = 10; myValue = 0; myFormatter = createFormat(digitsToDisplay()); } // Create a Counter with myLimit set to limit, myValue set to 0, and // exactly as many digits as we'll need to display the largest value // that will be displayed. public Counter(int limit) { myLimit = limit; myValue = 0; myFormatter = createFormat(digitsToDisplay()); } // Create a Counter with myLimit set to limit, myValue set to 0, and // the number of digits given as a parameter, but always at least as // many as necessary for the largest value displayed. public Counter(int limit, int digits) { myLimit = limit; myValue = 0; // Determine the least number of digits we can use for the display. int minDisplaySize = digitsToDisplay(); // Complain if too few digits were requested. if (minDisplaySize > digits) System.out.println("You asked to display " + digits + (digits > 1 ? " digits, " : " digit, ") + "but you need at least " + minDisplaySize + "."); // Use the better value. myFormatter = createFormat(Math.max(minDisplaySize, digits)); } // Create a Counter that is a copy of another Counter. public Counter(Counter other) { myLimit = other.myLimit; myValue = other.myValue; myFormatter = other.myFormatter; } // Display the value of a Counter, padding with as many leading zeros // as necessary. public void show() { System.out.print(toString()); } // Return a String that gives the value of a Counter, padding with as // many leading zeros as necessary. public String toString() { return myFormatter.format(myValue); } // Increment the value of a Counter, wrapping around if it // hits the limit. public void tick() { myValue++; if (myValue == myLimit) // Has it hit the limit? myValue = 0; // Wrap if it has } // Return the value of a Counter. public int getValue() { return myValue; } // Reset a Counter to a given value, as long as it's legal. public void reset(int value) { if (0 <= value && value < myLimit) myValue = value; } // Here's a helper method. It is called only by methods in this class, // so it is private. It returns how many digits are needed to display // the largest value that the Counter may have, assuming that myLimit // has already been set. // That number, by the way, is the number of digits in limit-1. private int digitsToDisplay() { return (Integer.toString(myLimit - 1)).length(); } // Another helper method, which creates a DecimalFormat object for // formatting the value. private DecimalFormat createFormat(int digits) { // Create a String that is all 0's, and the length is a given number // of digits. String zeros = ""; for (int digit = 1; digit <= digits; digit++) zeros += "0"; // Now use that to create a DecimalFormat object. return new DecimalFormat(zeros); } }