Java mutator method on something that was constructed with a loop
-
09-02-2021 - |
Domanda
So I have a class that I constructed with a loop. In the constructor I have two while loops which make "grid" of circles. It's supposed to be a scarf for class but I'm calling it chainmail because that sounds cooler. Anyways we're supposed to be able to change the color of the scarf with a different (client) class. I obviously need to add a mutator method to change the color. Luckily there is a mutator for this in objectdraw called setColor(). It works just fine, except when I try to add it to this class it only changes the last circle in the grid. I know why this happens, but I don't know how to fix it. I've commented out the "typical" mutator we've been using in class.
EDIT: Sorry for the confusion guys... this is just the class, I have a client that calls a new ChainMail() and then does a .setColor() on it but it only changes the last framedoval instead of all of them. That's the problem
import objectdraw.*;
import java.awt.*;
public class ChainMail {
private FramedOval link;
public ChainMail(int rows,int links,
Location p,Color rgb,
DrawingCanvas c) {
double numRows = 0;
// create the number of rows specified
while (numRows < rows) {
double numLinks = 0;
// create the number of links specified
while (numLinks < links) {
link = new FramedOval(p,12,12,c);
link.setColor(rgb);
// update the position
p.translate(8,0);
numLinks++;
}
// move position back to front col and down one row
p.translate(-8*links,8);
numRows++;
}
}
public ChainMail(int rows,int links,Location p,DrawingCanvas c) {
this(rows,links,p,Color.BLACK,c);
}
/* this doesn't work, only changes last circle
* public void setColor(Color c) {
* link.setColor(c);
* }
*/
}
Soluzione
If you move it to class (as shown in commented code) then from where do you call this function ? I think this is what making the difference. Suppose you are doing following :
- remove "link.setColor(rgb);" from inside the while loop
- Uncomment public void setColor(Color c) function
- Create instance of ChainMail (say myChainMail)
- Call myChainMail.setColor(c)
This scenario will give the result which you have reported i.e. only last circled gets colored. There are 2 ways to solve the issue :
- First is what you are already doing
- Instead of "private FramedOval link;" create "private ArrayList linkList = new ArrayList; Now before while create link variable of type FramedOval. Then after you do link = new FramedOval(p,12,12,c); in while loop add this to above created ArrayList. Now in setColor method of your class iterate over all the items in arraylist and set color on those items
Altri suggerimenti
I say you're throwing them away because you do this:
while (numLinks < links) {
link = new FramedOval(p,12,12,c);
link.setColor(rgb);
// update the position
p.translate(8,0);
numLinks++;
}
But where do you do anything with the FramedOval that you've created? Every time you create a new FramedOval object and have link refer to it, the previous reference gets lost and is likely garbage collected; it's discarded, which doesn't make sense.
Usually you'd do something like:
List<FramedOval> framedOvalList = new LinkedList<FramedOval>(); // or ArrayList
while (numLinks < links) {
link = new FramedOval(p,12,12,c);
link.setColor(rgb);
// *** here add the created object to some collection
framedOvalList.add(link);
// update the position
p.translate(8,0);
numLinks++;
}
But I don't see you doing anything of the kind.