3

Here I have some code(shortened to show the most important parts)

private Map<String, Color> hashMap = new HashMap<String, Color>();
for (int u = 0; u < people.size(); u++) {
    if (people.get(u) instanceof Boy) {
        list[u]="B";
        hashMap.put(list[u], Color.red);
        System.out.print("B");
    } else if (people.get(u) instanceof Girl) {
        System.out.print("G");
        list[e] = "G";
        hashMap.put(list[u], Color.green);
    }

}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.drawString(list, 10, 10)
    // I would like to color each value according to its key in the hashMap list looping through my array
}

I would like my g.drawString() to loop through my array called list which contains [B,G,G,B,B,B,B,G] and color each value according to its colour based on my hashMap and return this array coloured..

so my hashMap["G" = color.green, "B"=color.red]

I tried this :

public void paint(Graphics g){

    g.setColor(hashMap.get("B") 
    g.setColor(hashMap.get("G")
    g.drawString(list, 10, 10)
}

but this seems to colour the whole text green or red could some one explain how to loop the the array called list and use g.drawString to colour each value accordingly?

EDIT

 for (int u = 0; u < people.size(); u++) { 
 Person p = people.get(u); 
list[u] = p.getGenderAsChar(); colorMap.put(r.getGenderAsChar(),r.getColorRepresentation() }


public void paintComponent(Graphics g){
super.paintComponent(g);
for (int c = 0; c< list.length; c++)
Person p = people.get(u);
 g.setColor(hashMap.getColorRepresentation);
g.drawString(list[c], 10 + c*10, 20);

}
blueGOLD
  • 105
  • 3
  • 12

1 Answers1

8

First for your actual question: just check out the JavaDoc for drawString(). That method expects a single String.

So you should rather write some code like

for (i=0; i < list.length(); i++) {
  g.setColor(hashMap.get(list[i]));
  g.drawString(list[i], 10 + i*10, 10);
}

or something alike.

In other words: you can't pass the whole array into that call. You have to call it once for each string you want to display; and of course, you then have to account for the horizontal spacing.

Alternatively, you could simply concatenate your chars into a single string BBBG... but then you loose the ability to change the color for the different chars.

But then beyond that.

Your abstractions are wrong - you are not doing good "OO" here.

OO is not about "lets ask some object about its state, or in your case, its type" to then make a decision based on that. Instead, you tell the object to do the right thing.

Meaning; code like

if (people.get(u) instanceof Boy) {
  list[u]="B";
  hashMap.put(list[u], Color.red);
}

should rather be something like

Person p = people.get(u);
list[u] = p.getGenderAsChar(); // to return either 'B' or 'G'

The idea behind that: you have an (abstract) base class Person; and then you create specific sub classes, Boy extends Person and Girl extends Person.

And those to classes both implement that method getGenderAsChar() and return different values.

Similar for

hashMap.put(list[u], Color.green);

You see, your list contains only B or G strings anyway. So you just keep putting (B, red) or (G, green) into that Map. Doesn't make any sense.

Instead, you could again have an abstract base method getColorRepresentation() and the Boy class returns Color.red; and Girls return Color.green.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 1
    thanks for the clarification, does it mean i cant loop through my array in public void paint(Graphics g){} to assign colours accordingly based on what i have ? – blueGOLD Dec 14 '16 at 20:08
  • 1
    Updated my answer ... hope that helps. – GhostCat Dec 14 '16 at 20:23
  • Thanks this really helps and is more understandable.I created those two concrete methods called getColorRepresentation() and getGenderAsChar() after creating an abstract base methods each for these methods.for (int u = 0; u < people.size(); u++) { { Person p = people.get(u); list[u] = p.getGenderAsChar(); colorMap.put(r.getGenderAsChar(),r.getColorRepresentation() } – blueGOLD Dec 15 '16 at 07:32
  • This is the method and code am using in the public void paint component(Graphics g). I have added it in the above first comment to make it clearer – blueGOLD Dec 15 '16 at 07:33
  • I think i might be doing something wrong in the public void paintComponet method added to my original post but am not sure where as this throws a null pointer exception? – blueGOLD Dec 15 '16 at 07:42
  • @Xvid sorry, but we shouldnt get into ... lets ask one more question in comments, and then another and another. If you have problems with nullpointerexceptions, you should start reading here http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it – GhostCat Dec 15 '16 at 08:20
  • 1
    Thanks for the link. just one question if I want to loop through the array based on your suggestion code how can this be done based on using good object oriented approach in the public void paintComponet() method based on my code improvements? – blueGOLD Dec 15 '16 at 09:25
  • Okay, one *last* comment then: obviously your paintComponent() code is **still** asking these Person objects for details to then do something with that. I think that is OK, but if you want to further improve: one possible way would be to simply add a method paintOn(Graphics) to the Person class itself. So instead of asking p for its color, string ... you just call p.paintOn(g) or something alike. And then the person does whatever is necessary to paint itself (and that would be a method that could do into the *base class - same for all people). But as said; programming school closes now ;-) – GhostCat Dec 15 '16 at 12:22
  • Actually, putting colors or, worse, paint in a Person (clearly a data model class) goes against all clean design considerations. It would make more sense to separate drawing logic into something like PersonRenderer with a paint method that receives the graphics and the person and implements the drawing. There are many approaches for responsibility separation e.g. look for [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). While not required for toy projects, for any real life application such separation necessity is written in blood of programmer generations. – Fedor Losev Dec 27 '16 at 19:17