1

Is it possible to achieve something like this in Swing :

enter image description here

Notice here A is colored partially.

I know may be its not possible with DefaultHighlighter class alone. (Text displayed on JTextArea)

Any solutions to achieve this in Swing's alone or have to apply CSS?

EDIT:

If that is not possible with swing, any solution with the below tags ?

joey rohan
  • 3,505
  • 5
  • 33
  • 70
  • I think it can't be done, even using CSS. Maybe you'll have to generate an image – Leo Sep 03 '14 at 14:57

1 Answers1

4

Something like this is possible with Java 2D but not with JTextArea. So you can create code which renders this in a frame but I don't think you'll find an easy way to add support for this to the text editors (well, you could always embed an image in a text editor but that's probably not what you want).

[EDIT] For a text display for a karaoke player, Java 2D is the way to go. The Java editor APIs will just get in your way.

Here is an example for rendering text with a gradient:

  public void sayWorld(Graphics2D g2D, int x, int y, boolean shear) {
      final String txt = "Hello World!";

      // gradient color from blue to red
      GradientPaint gp = new GradientPaint((float)x, (float)y, Color.blue,
                             x+100, y+20, Color.red);
      g2D.setPaint(gp); 
      if (shear) g2D.shear(-0.5,0.0);
      else       g2D.shear(+0.5, 0);
      g2D.drawString(txt, x, y);

      FontRenderContext frc = new FontRenderContext(null,false,false);

      TextLayout tl = new TextLayout(txt, font, frc);
      AffineTransform textAt = new AffineTransform();
      //textAt.translate(0, (float)tl.getBounds().getHeight());
      textAt.translate(x,y); 
      //textAt.shear(-0.5,0.0);

      Shape outline = tl.getOutline(textAt); 
      g2D.setColor(Color.yellow);
      BasicStroke wideStroke = new BasicStroke(2);
      g2D.setStroke(wideStroke); 
      g2D.draw(outline);
  }

(source)

Basically, you render get the text layout from a single line of the lyrics, then convert that into a shape (= the outline of each letter). You can then use this shape as a clip area to render the gradient.

In your case, you need an abrupt gradient which is twice as wide as the longest text line that you want to render. Shift it appropriately to get the gradient change in the place of the text where you need it.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • I already thought of 2D, but that will be way to complex for the logic.May be I should edit the tags. – joey rohan Sep 03 '14 at 15:06
  • I don't understand what you mean by "too complex for the logic." Just get a path from the text plus a color range and then fill a rectangle using the path as clip area? – Aaron Digulla Sep 03 '14 at 15:07
  • Its something like a karaoke player.If I adopt this solution, I may go out of synchronization. Timings are adjusted to nano sec precision.Also scrolling will be a pain. – joey rohan Sep 03 '14 at 15:11
  • May be you will understand better once you will see my original 'X' problem : http://stackoverflow.com/questions/15040989/issues-creating-a-very-accurate-swing-timer – joey rohan Sep 03 '14 at 15:12
  • I don't see how you can lose sync or why would would scroll at all. Just display the current (and maybe the next line of the lyrics). That way, the singer just has to move their eyes horizontally. – Aaron Digulla Sep 03 '14 at 15:52
  • By scroll I mean it does auto scroll at the end of view-able textArea.But it's a good solution.Not too complex what I was thinking.Making gradient change will be the key. Thanks :') – joey rohan Sep 03 '14 at 16:19
  • But I was thinking if I can get little spoon feeding like in JS : http://stackoverflow.com/questions/8221854/how-can-i-highlight-text-strictly-timed-a-la-karaoke-without-flash-on-a-web – joey rohan Sep 03 '14 at 16:23