tags:

views:

377

answers:

5

I would like to know the recommended library or procedure for dealing with multi-coloured text within Java. My current usage of java.awt.Graphics, while function, appears to be a bit more complex than necessary.

The main issue involves the frequent change of colour, creating a new java.awt.Colour() object whenever a new colour is needed (and it's usually not one of the predefined values.) I already keep track of the previously used rgb value, but it's possible that the colour can potentially change to unique values for each character I draw:

java.awt.Color colorRender = new java.awt.Color(rgb);
g.setColor(colorRender);

I also ran a profiler on my code, and identified a secondary bottleneck in an extreme case. I suspect that it may be the method used for drawing a single character, but there may be overhead in determining said character:

char[] c = new char[1]; // Created once for many uses
/* ... */
g.drawChars(charRender, 0, 1, x, y);

I have looked at the BufferedImage class - while it's great for pixel-level graphics, it doesn't directly support drawing characters.

A: 

I found this: How to add colored text to the document.

eed3si9n
+1  A: 

Not a real answer, but if you think/measure that creating lots of Color objects is a performance bottleneck you can replace the calls to new Color(rgb) by your own factory method that caches already created colors. (I'm assuming the Colors class is immutable - it looks like it is)

So add a ColorsFactory class with a (static) method getColor(rgb) method that caches colors that have already been created. You could simply put all colors in a map rgb -> Color(rgb) and keep them around forever or you could try and create cache that removes colors that are not used frequently (lots of libraries to do that) -- depends a bit on the way your program is used.

Simon Groenewolt
http://en.wikipedia.org/wiki/Flyweight_pattern
eed3si9n
ah - it has a name, forgot about that :-)
Simon Groenewolt
The library is being used in this fashion: http://en.wikipedia.org/wiki/Roguelike
Raymond Martineau
A: 

Try the open source part of the JIDE components. This includes a class called StyledLabel which is a Swing JLabel that supports multicolored fonts.

frankodwyer
A: 

Update for the readers:

  • The actual problem was caused by a frequently called method throwing a runtime exception, and using that exception to return a default value. I changed the code of this method to avoid the exception ahead of time, and should it still occur, lets the calling function(s) handle them.
  • Since the default value isn't that useful, I added code to skip past rendering most of those characters.
Raymond Martineau
+5  A: 

I'm assuming you're rendering text to an arbitrary component (via paintComponent()) rather than trying to modify the color of text in a JTextPane, JLabel, or other pre-existing widget.

If this is the case, you should look into using an AttributedString along with TextAttribute. These allow you to assign different styles (color, font, etc.) to various ranges of characters within a string and then render the whole string using Graphics.drawString(...). This way, the underlying graphics subsystem will handle any necessary changes to the graphics state during rendering making your code much more readable, and probably faster.

Here is an example usage.

Of course, as other have mentioned, you should also be caching your Color objects rather than recreating them over and over.

Dave Ray