• Post Reply Bookmark Topic Watch Topic
  • New Topic

Mutable java.awt.Color

 
Oleg Shubin
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I want to paint my own image (an array of int values) to java.awt.Graphics. The procedure seems easy:

However, my question is about the paintSinglePixel point. Of course no such method exists anywhere and I'm asking about how to implement it.
I need to paint a single pixel in a Graphics object the quickest way possible. I've figured out that Graphics.fillRect is the fastest way to go (at least it seems so) but I also need to change colors. As AWT suggests, I should create a new instance of Color for each pixel:

I've tried doing that and realized painting a 500x500 area takes about a second, and I think that the problem would be solved if I could modify the Color instance instead of creating a new one each time.
So I created a class, DynamicColor, that overrides java.awt.Color. First, I overrode all the methods in order to check which ones are called by the Graphics object and thus have to be re-implemented. It appeared that only a few of them are used: getRed, getGreen, getBlue, getAlpha, getRGB and getTransparency. I created an integer field, rgb, to store the color value and overrode those methods so they return information about this field (e.g. if rgb == 0xFF0000, getRed returns 0xFF even if super.getRed would return 0x00). In the super constructor I passed 0 (like java.awt.Color(0)). Here's the resulting class:

In the paint method I set the color once before iterating and at the point where I changed the color prevoiusly I modified my color's rgb value:

However, the painted color stays the same. After a little research through the system libraries I found some int package field: java.awt.Color.value. As both Color and Graphics classes are in the same package that field may be accessed directly (I cannot override it nor I can change it). I tried placing my class in java.awt. package but ClassLoader threw an exception saying I cannot use that package.

So how do I create a Color subclass that represents a mutable value? How do I set the color of an individual pixel in Graphics? Is all this saying that Java provides no direct access to pixels?

I know that BufferedImage exists exactly for this use, but I can't use it because it takes a lot of memory and, in general terms, I need a more lightweight implementation.
Why do I bother so much with perfomance? Because my actual goal is to make a 2D-Graphics engine written completly in Java, that can provide at least 30 FPS even on slow computers. I realized I should render the screen before displaying it (before the java.awt.Component.paint()), so I store the image in my own class (myImage in the examples above).
I've asked a similar question already here but it wasn't awnsered.

Thank you a lot.
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If Color isn't mutable then you can't extend it to make it mutable.

You can try using a "Factory" to minimize the creation on new Objects.

The (untested) code might be something like:



Then you would use the class like:

 
Winston Gutkowski
Bartender
Posts: 10571
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oleg Shubin wrote:So how do I create a Color subclass that represents a mutable value?

You're asking the wrong question.

And the reason it's wrong is that it assumes that mutability (or lack of it) is the solution to (or cause of) your problem - and it isn't.

Indeed, the solution that Rob gave you (although I think I'd have called it a cache rather than a factory) only works because Color ISN'T mutable. If it was, you could end up with some very weird results.

Remember: whenever you run into a a problem, try to ask yourself "How do I do this?" - or even better "What do I need to do to do this?" - not "How do I get this implementation to work?"; the reason being that the latter question assumes that the implementation you've chosen (in your case, a mutable Color) is correct...and it may well not be.

HIH

Winston
 
Paul Clapham
Sheriff
Posts: 21872
36
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oleg Shubin wrote:I've tried doing that and realized painting a 500x500 area takes about a second, and I think that the problem would be solved if I could modify the Color instance instead of creating a new one each time.


"I think" is the important phrase here. There's a good chance that isn't the right solution, because you're only creating 250,000 Color instances there and your machine can probably create at least 100 times that many objects in one second. You could test that theory directly by writing a tiny piece of code which created one million Color instances and timed that. Or you could implement Rob's Color factory and see what difference it makes.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!