CS 161 - Intro to Computer Science
Lab: Circle Drawer
This assignment is all about conditionals and object references! We’ll work with the CircleDrawer
class that is given to you. Along the way you’ll write code that uses and manipulates object references, and requires more complex boolean expressions than you’ve written previously.
Student Outcomes
- Practice object interaction (puppeteering)
- Practice using object references
- Practice returning values across objects
- Working with null reference testing
Required Files
The following file(s) have been provided for this homework.
Instructions
-
Download the
CircleDrawer
project from the link above and extract its contents, then start BlueJ and open the project. See how aCircleDrawer
contains two instance variables of type Circles (namedfirst
andsecond
). This demonstrates that classes likeCircle
can serve as a variable’s data type! -
Notice that the
CircleDrawer
class has two constructors. The default constructor just sets both instance variables tonull
. The secondary constructor takes to twoCircle
objects as arguments, and it sets both instance variables appropriately.- Using the menus in BlueJ, instantiate two
Circle
s. You can name themc1
andc2
. - Change
c1
to green, change size to50
. - Change
c2
to red, change size to75
. Then move it down by50
pixels. - Now create a new
CircleDrawer
using its secondary constructor . Inputc1
andc2
to be your arguments. The newCircleDrawer
will now “control” the two circles. -
Inspect the
CircleDrawer
object, and you see thatfirst
andsecond
store references (see those arrows?). Double-clicking on one of the arrows, and it opens the inspector to the Circle you just created! -
Call the
drawCircles()
method on the drawer, and notice that both Circles appear. (If you calleraseCircles()
both disappear.) -
This gives us some idea about what a
CircleDrawer
does. It’s basically a “puppet master” that bosses around one or two assigned Circles. - That’s an example of Object Aliasing that we talked so much about in class!
first
is aliased toc1
andsecond
is aliased toc2
.
- Using the menus in BlueJ, instantiate two
-
Now go back in the
CircleDrawer
source code and take a look atdrawCircles()
anderaseCircles()
. Calling them will make both circles visible or invisible, but that’s assuming thatfirst
andsecond
actually refer to actualCircle
objects, and not anull
reference.- Create a
CircleDrawer
object using its default constructor (that’s the one with no input arguments). - Inspect it, and see how
first
andsecond
both point tonull
. - Try calling
drawCircles()
oreraseCircles()
. The program should crash with aNullPointerException
. That’s bad news – it means our code isn’t robust.
- Create a
- Add necessary changes to
drawCircles()
so that you only draw the circle(s) when it’s notnull
.- To do this, use an if-statement to check if each field is
==
or!=
to the keywordnull
. - Make sure you test these out after you’re done by creating a default CircleDrawer object, and calling
drawCircles()
– if the program doesn’t crash with aNullPointerException
, you’ve done your job! - Now make the same changes to
eraseCircles()
- To do this, use an if-statement to check if each field is
-
Add a new method called
strictDrawCircles()
method so that it only draws circles with radii strictly greater than20
and strictly less than50
.- Recall that the radius is half of a circle’s diameter. But how do you get a
Circle
’s diameter? You can’t access that field from this class!- Try it: What if you tried to print
first.diameter
from thisstrictDrawCircles()
method?
- Try it: What if you tried to print
- Ah, this is why we write “getters.” Add a method in the
Circle
class that simply returns itsdiameter
. - After you’ve done that, you need to go back to the
strictDrawCircles
method and call your new “get diameter” method onfirst
andsecond
using “dot notation!” Use some if statements to ensure that each of your circles diameters are within the specified range, and make them visible! - Test this out. Ahem – if your Circle’s diameter is say, 41, it should be drawn. If you just can’t get yours to draw, write some code to print out the calculated radius. Are you falling victim to integer divide?
- Recall that the radius is half of a circle’s diameter. But how do you get a
- Go back in the
CircleDrawer
class. Add a method calleddrawLarger()
that draws only the larger of the two circles. The smaller one should be hidden. If there’s a tie, then you should draw both of them.- Beware of null pointer exceptions!
-
Add a method in
CircleDrawer
calledsizeRatio()
that returns the ratio of the two circle’s diameters as adouble
. If one circle has a diameter of 9 and another has a diameter of 3, then this method returns 0.333… You should always divide the smaller diameter by the larger.- Now, if either circle is
null
then you can simply return 1 in this method. - Are you always getting a 0 when you’re expecting to get a fraction? It could be due to integer divide, which means you are going to need to type cast.
- Now, if either circle is
- Add a method in
CircleDrawer
calledaddCircle()
that inputs aCircle
object, and it doesn’t return. This method must first erase bothCircles
(Yep, just calleraseCircles()
instead re-writing all that code). Now:- If either of the two circles are
null
, then simply assign the newCircle
to that field. - If neither of the two are pointing to
null
, then promote the secondCircle
to thefirst
, then set the newly-inputCircle
to be thesecond
. - After you’re done with all that, make both Circles visible.
- To test this method, I would create 3 circles in BlueJ. Then create a CircleDrawer using the default constructor so that both
first
andsecond
arenull
. Then calladdCircle()
3 consecutive times (on the 3 circles you created). - Here, we see another example of object aliasing! The new Circle that you input is now also referenced by your input parameter!
- If either of the two circles are
-
Add a method called
swapCircles()
that inputs and returns nothing. Calling this method will causefirst
to now point to whatsecond
held, and vice versa. They exchange whatever they’re pointing at (even if they’re pointing tonull
). - Add a method called
replaceSmallest()
that takes aCircle
as input.- If either of the two circles are
null
, simply add the new circle into the empty slot. - If neither of the two are pointing to
null
, this method must replace the smaller circle with the new, given one. We need to respect seniority, though:- If
first
is smaller, we’ll first promotesecond
to take its place, and assign the new circle insecond
’s place. - If
second
is smaller, we’ll just replace it with the new circle. In the case of a tie, replace second.
- If
- This method seems to have quite a bit of similarities to
addCircle()
. You don’t need to, but kudos if you can figure out how to utilizeaddCircle()
andswapCircles()
to simplify writing this method.
- If either of the two circles are
Grading
1
2
3
This assignment will be graded out of 2 points, provided that:
- You were in attendance and on-time.
- Completed all required methods.
Submitting Your Assignment
Follow these instructions to submit your work. You may submit as often as you’d like before the deadline. I will grade the most recent copy.
-
Navigate to our course page on Canvas and click on the assignment to which you are submitting. Click on “Submit Assignment.”
-
Upload all files ending in
.java
from your project folder. -
Click “Submit Assignment” again to upload it.
Credits
Written by Brad Richards with modifications.
Lab Attendance Policies
Attendance is required for lab. Unexcused absence = no credit even if you turned in the lab. Unexcused tardiness = half credit.