Develop NumberDisplay
Based on BlueJ ClockDisplay progressively develop NumberDisplay class to display a pair of digits to represent hours and minutes using the existing BlueJ class Clock to drive the ClockDisplay.
To get a flavour of this lab:
We shall now build a clock project, step-by-step with functionality matching that in both clock-display and clock-display-with-GUI.
Observe the Clock in Figure 1.
Instances of NumberDisplay objects are used to represent both hours and minutes.
We shall now implement this class.
Assume we are designing a 24 hour clock.
In the case of the hour display, therefore,
In the case of the minutes display
The NumberDisplay class, therefore, requires 2 fields
Here is the NumberDisplay class.
public class NumberDisplay
{
private int limit;
private int value;
}
Create a new class, NumberDisplay, in the BlueJ: clock project window (Figure 2):
Add each piece of code as it is developed below and compile as you go, attending to any syntactic errors that may be introduced.
We now write a constructor in which we will initialize the fields.
Here is the code for the constructor:
public NumberDisplay(int limit)
{
this.limit = limit;
value = 0;
}
We will also require a getter for value:
public int getValue()
{
return value;
}
We require a method to increment value.
/**
* Use modular arithmetic to increment value
* thus ensuring it's always within legal range
*/
public void incrementValue()
{
value = (value + 1) % limit;
}
Finally, here is a method to display the current value:
public String display()
{
//add a leading zero where necessary
if(value < 10)
{
return "0" + value;
}
else
{
return Integer.toString(value);
}
}
Observe that we are using the Integer class toString method to convert the integer to a string with the expression:
Alternatively we could have used this expression:
with similar effect.
We require a ClockDisplay containing two NumberDisplays, one representing hours, the other minutes.
We also require a field representing the text to display:
Here is the class skeletion:
public class ClockDisplay
{
private NumberDisplay hours;
private NumberDisplay minutes;
private String displayTime;
}
Create a new class in the BlueJ: clock project window named ClockDisplay and replace the autogenerated code with that above.
Compile the class. The result should match that shown in Figure 1.
Next we shall develop the constructor in which we will instantiate the NumberDisplay objects.
public ClockDisplay()
{
hours = new NumberDisplay(24);
minutes = new NumberDisplay(60);
}
We require a method to update the displayTime field, that is, to
public void updateDisplay()
{
this.displayTime = hours.display() + ":" + minutes.display();
}
We shall now add a method named timeTick to
public void timeTick()
{
minutes.incrementValue();
//when minutes value is zero it means time to increment hours
if(minutes.getValue() == 0)
{
hours.incrementValue();
}
updateDisplay();
}
We can obtain the time from a Clock object by invoking a getter:
public String getTime()
{
return displayTime;
}
Here, as a check, is the complete source code for NumberDisplay:
public class NumberDisplay
{
private int limit;
private int value;
public NumberDisplay(int limit)
{
this.limit = limit;
value = 0;
}
public int getValue()
{
return value;
}
/**
* Use modular arithmetic to increment value
* thus ensuring it's always within legal range
*/
public void incrementValue()
{
value = (value + 1) % limit;
}
public String display()
{
//add a leading zero where necessary
if(value < 10)
{
return "0" + value;
}
else
{
return Integer.toString(value);
}
}
}
Here, as a check, is the complete source code for ClockDisplay:
public class ClockDisplay
{
private NumberDisplay hours;
private NumberDisplay minutes;
private String displayTime;
public ClockDisplay()
{
hours = new NumberDisplay(24);
minutes = new NumberDisplay(60);
updateDisplay();
}
public void timeTick()
{
minutes.incrementValue();
//when minutes value is zero it means time to increment hours
if(minutes.getValue() == 0)
{
hours.incrementValue();
}
updateDisplay();
}
public void updateDisplay()
{
displayTime = hours.display() + ":" + minutes.display();
}
public String getTime()
{
return displayTime;
}
}
The BlueJ: clock project window should look something like that illustrated in Figure 1.
We shall now import a BlueJ component to enable us to test the ClockDisplay and view its output in a GUI.
Close BlueJ.
Download an archive clockBJ.zip, available here.
Create a NumberDisplay object and exercise its methods:
Use the inspector to observe changes in state that you bring about.
Here is the code for the NumberDisplay increment method:
/**
* Use modular arithmetic to increment value
* thus ensuring it always within legal range
*/
public void incrementValue()
{
value = (value + 1) % limit;
}
Refactor this code as follows:
Here is the code for the NumberDisplay setValue method:
/**
* We check parameter value is in range
* If not in range, do nothing
* @param value is the new value
*/
public void setValue(int value)
{
if(value >= 0 && value < this.limit)
{
this.value = value;
}
}
What would the consequences be were you to replace the line
with the following:
if(value >= 0 || value < this.limit)
Test the edge cases in the case of both lines of code.
By edge case is meant the situation that arises at the extreme values, for example here where:
List all possible results of the expression n % 10 where n is an integer variable and % is the modulus operator.
You will find the definition of an integer here
Here's a simple example that may help those unfamiliar with this operator:
Evaluation:
Here's the method NumberDisplay display()
public String display()
{
// add a leading zero where necessary
if(value < 10)
{
return "0" + value;
}
else
{
return Integer.toString(value);
}
}
Check what the result of substituting the following for return Integer.toString(value):
Explain any differences in behaviour.
What is the value of each of the boolean variables?
Provide a short explanation in each case.
Test your answers with the class LogicalOperator:
public class LogicalOperator
{
public boolean a()
{
return 8 < 9;
}
//Note the internal method call to methods a() & b()
public boolean g()
{
return (a() && b()) == true;
}
}
Complete the method bodies in TestStrings
Satisfy yourself that your answers are correct.
public class TestStrings
{
String s0;
String s1;
public TestStrings()
{
s0 = new String("ICTSkills Group");
s1 = new String("ICTSkills group");
}
/*
* Check if s0 and s1 are equal
* @return true if s0 and s1 equal else false
*/
public boolean equals()
{
return false;
}
/*
* Check if s0 and s1 equal ignoring case
* @return true if s0 and s1 equal else false
*/
public boolean equalsIgnoreCase()
{
return false;
}
/*
* Return concatenation of s0, s1 and s
* @param s string to be concatenated with instance variable strings
* @return the composite string
*/
public String stringConcat(String s)
{
return "";
}
/*
* @param sDouble is String representation of a primitive double e.g. "100.345"
* @return param converted to double
*/
public double convertToDouble(String sDouble)
{
return 0.0;
}
/*
* @param sInteger is String representation of a primitive int e.g. "100"
* @return param converted to int
*/
public int convertToInteger(String sInteger)
{
return 0;
}
/*
* @param number to be converted to a String
* @return param converted to String
*/
public String convertToString(int number)
{
return "";
}
}