aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Change icon color dinamically Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Change icon color dinamically" Watch "Change icon color dinamically" New topic
Author

Change icon color dinamically

Aleksey Vladimirovich
Ranch Hand

Joined: Sep 05, 2012
Posts: 56
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

Joined: Apr 30, 2003
Posts: 820

can you post the code you use to start this one up?
Aleksey Vladimirovich
Ranch Hand

Joined: Sep 05, 2012
Posts: 56
Tim McGuire wrote:can you post the code you use to start this one up?

Sure, here it is:


Aleksey Vladimirovich
Ranch Hand

Joined: Sep 05, 2012
Posts: 56
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
Bartender

Joined: Oct 14, 2005
Posts: 18887
    
    8

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

Joined: Sep 05, 2012
Posts: 56
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
Bartender

Joined: Oct 14, 2005
Posts: 18887
    
    8

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

Joined: Sep 05, 2012
Posts: 56
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

Joined: Sep 05, 2012
Posts: 56
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

Joined: May 03, 2008
Posts: 4658
    
    5

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.


luck, db
There are no new questions, but there may be new answers.
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4658
    
    5

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

Joined: Sep 05, 2012
Posts: 56
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

Joined: Sep 05, 2012
Posts: 56
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

Joined: May 03, 2008
Posts: 4658
    
    5

Don't ever call Thread.sleep(...) on the EDT. Use a Swing Timer.
Aleksey Vladimirovich
Ranch Hand

Joined: Sep 05, 2012
Posts: 56
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

Joined: May 03, 2008
Posts: 4658
    
    5

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

Joined: Sep 05, 2012
Posts: 56
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?
 
Consider Paul's rocket mass heater.
 
subject: Change icon color dinamically