• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Change icon color dinamically

 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, guys!
I'm trying to create a JFrame with 3 circles inside it and make it work like a traffic light. I've created a separate class for lights, but I can't make them change colors dinamically, because once the icon has been drawn, I can't change it's color anymore Should I give up this idea or there is a way to get it done?



And one more question: if you look into Icon interface, you'll see this:



I can't get few things...
When any class implements this interface, what is the connection between a regular method (this one: void paintIcon(Component c, Graphics g, int x, int y)), which was overriden from interface and the constructor of my class? I mean, why this method executes once new instance of object of my class was created (I do not call it explicitely)? And how does my class know what object has been drawn in this method?

Sorry, if the questions are stupid, but I really want to understand
 
Tim McGuire
Ranch Hand
Posts: 820
IntelliJ IDE Tomcat Server VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
can you post the code you use to start this one up?
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim McGuire wrote:can you post the code you use to start this one up?

Sure, here it is:


 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Probably I could have made a collection of JLabels, which would've contained icons of 4 different colors (red, orange, green and black) and change these icons for each element in a loop, but I thought it would've been a bad solution...
 
Paul Clapham
Sheriff
Posts: 21416
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, that is the right solution.

The wrong solution is to try to change the icon's colour. That's because there is a hidden assumption in that solution, namely the assumption that an icon has "a" colour. Obviously that isn't the case, an icon is an image which can consist of many colours. Which means that there isn't going to be a method to change an icon's colour.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:No, that is the right solution.

The wrong solution is to try to change the icon's colour. That's because there is a hidden assumption in that solution, namely the assumption that an icon has "a" colour. Obviously that isn't the case, an icon is an image which can consist of many colours. Which means that there isn't going to be a method to change an icon's colour.

I'm just trying to look at this class not as at an icon, but as at entity of a traffic light (lamp). Stoplight's lamp can be in different states - on and off, exactly the same I want to do in the code (to follow OOP style). Maybe, if it's not possible to change icon's color, I should create a separate class for stoplight's lamp, which will extend JLabel and have fields "int delay" (after removing this one from class "Light"), "Light lightOn" and "Light lightOff" and change its icon dinamically, what do you think?
 
Paul Clapham
Sheriff
Posts: 21416
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Changing the icon at run-time sounds like a better idea. After all if you look at real traffic lights, they have more than just colours. Sometimes they have green arrows as well as green circles, at least where I live they do. And sometimes they flash on and off.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:Changing the icon at run-time sounds like a better idea. After all if you look at real traffic lights, they have more than just colours. Sometimes they have green arrows as well as green circles, at least where I live they do. And sometimes they flash on and off.

Yes, you have a point there! I totally forgot about arrows, people and stuff on them... Thanks!
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Guys, could you please answer the second question from my first post? I mean this one:
Aleksey Vladimirovich wrote:I can't get few things...
When any class implements this interface, what is the connection between a regular method (this one: void paintIcon(Component c, Graphics g, int x, int y)), which was overriden from interface and the constructor of my class? I mean, why this method executes once new instance of object of my class was created (I do not call it explicitely)? And how does my class know what object has been drawn in this method?

Sorry, if the questions are stupid, but I really want to understand
 
Darryl Burke
Bartender
Posts: 5148
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aleksey Vladimirovich wrote:Guys, could you please answer the second question from my first post? I mean this one:
Aleksey Vladimirovich wrote:I can't get few things...
When any class implements this interface, what is the connection between a regular method (this one: void paintIcon(Component c, Graphics g, int x, int y)), which was overriden from interface and the constructor of my class? I mean, why this method executes once new instance of object of my class was created (I do not call it explicitely)? And how does my class know what object has been drawn in this method?

Sorry, if the questions are stupid, but I really want to understand

Read through the source of javax.swing.plaf.basic.BasicLabelUI. The part you're interested in is on line 150 in my version of the sources. (Just in case you don't already know, you can find that in the src.zip file in your JDK folder.)

An Icon can have several states, but setting a different Icon isn't noticeably more expensive. Also, if an Icon implementation changes its appearance, it will still be necessary to call repaint() on the Component that displays the Icon as the new appearance will only be seen after repainting.
 
Darryl Burke
Bartender
Posts: 5148
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:No, that is the right solution.

The wrong solution is to try to change the icon's colour. That's because there is a hidden assumption in that solution, namely the assumption that an icon has "a" colour. Obviously that isn't the case, an icon is an image which can consist of many colours. Which means that there isn't going to be a method to change an icon's colour.

I beg to differ. An Icon is a set of painting instructions, not an image. (ImageIcon does hold an image though.)

An Icon implementation can be written that includes a field of type Color and a setColor(...) method. As noted above, the Component displaying the Icon will need to be repaint()ed any time the Color is changed.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Darryl Burke wrote:Read through the source of javax.swing.plaf.basic.BasicLabelUI. The part you're interested in is on line 150 in my version of the sources. (Just in case you don't already know, you can find that in the src.zip file in your JDK folder.)

An Icon can have several states, but setting a different Icon isn't noticeably more expensive. Also, if an Icon implementation changes its appearance, it will still be necessary to call repaint() on the Component that displays the Icon as the new appearance will only be seen after repainting.

Now it's clear to me! Thanks a lot :thumbup:
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I finally found the time to finish my traffic light, everything works perfectly, but one thing... Here is the code of main class:


Somehow method blink() doesn't work properly - it just sets black icon to the lamp and doesn't set green one back. So the lamp doesn't blink at all, although switchLight() vethod does work - my traffic light changes lights in a separate thread as it supposed to. Guys, maybe you can give me some tips what I am doing wrong? I ran out of ideas
 
Darryl Burke
Bartender
Posts: 5148
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't ever call Thread.sleep(...) on the EDT. Use a Swing Timer.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried to modifiy my blink() method this way:

Value of periodicity is 3000, but it doesn't make any delay Documentation says that I can put null as a second argument, while creating a timer. What's wrong with it? Or you meant something else?
 
Darryl Burke
Bartender
Posts: 5148
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A Timer without an ActionListener is like a car without an engine. There's a tutorial linked from the API for javax.swing.Timer. Go through it.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Darryl Burke wrote:A Timer without an ActionListener is like a car without an engine. There's a tutorial linked from the API for javax.swing.Timer. Go through it.

Thanks for advice, Darryl! I did as you suggested to and now it works, here is the code:

As far as I got, EDT is a separate thread, wich processes all events of AWT library, but I'm not sure if I was making this thread sleep by calling Thread.sleep(). I put console output method in strings 66, 85 and 100 to see if it was EDT, but I got three messages in console, that say it's not EDT, here:
startSwitchingLights method is in EDT: false
startBlinking method is in EDT: false
separate thread in startSwitchingLights() method is in EDT: false

Darryl, could you please point out my mistakes? And shouldn't I use Thread.sleep() in startSwitchingLights() method (strings #74 and #81) in the separate thread?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic