2

I'm struggling to understand the LayeredHighlighter. I have two highlights. One I highlight text when the textarea area is created. The other highlighter is the highlight you get when you scroll over text.

The problem I'm having is that the highlighting I use with the mouse does not overlap the highlight on the text that was set when the textarea was created.

Below is the text being highlighted when the textarea is created

Original highlight

When I use the mouse to highlight the whole text it does not go on top

With selection

I think I need to use the LayeredHighlighter. I tried to use it by using painter.paintLayer(...) I used this when I created the grey coloured highlight.

Is there anyway to set my grey highlight to the back so that my mouse blue highlight will go ontop of it when I select the whole line? So the whole line should be blue

Thanks :)

Evgeni Sergeev
  • 22,495
  • 17
  • 107
  • 124
Decrypter
  • 2,784
  • 12
  • 38
  • 57

4 Answers4

3

In the Core Swing book, page 262, there is some documentation about the semantics (unlike in the API reference). It seems to boil down to a system with just two layers. There isn't much control over the z-order other than using a Highlighter.HighlightPainter that is not a LayeredHighlighter.LayerPainter (somewhat counter-intuitive design pattern), vs using one that is. Highlight painters of the first type will get to go first (in an arbitrary order). Then all the LayerPainters. Also in arbitrary order, but we could guess that the selection highlight gets painted first (it uses a LayerPainter), and then other LayerPainter highlights on top.

So the solution (that works for me) is to add highlights using a Highlighter.HighlightPainter. Make sure it is not a LayeredHighlighter.LayerPainter; i.e. probably use an anonymous class deriving straight from Highlighter.HighlightPainter. Don't use DefaultHighlighter.DefaultHighlightPainter, because that is a subclass of LayeredHighlighter.LayerPainter. But perhaps your Highlighter.HighlightPainter implementation could keep a reference to an instance of DefaultHighlighter.DefaultHighlightPainter, and relay paint(..) requests to it — thus avoiding having to write the painting code from scratch. This will solve the problem illustrated, as whenever a part of the view is repainted, this HighlightPainter-not-LayerPainter is going to fill its part of the background before the selection's HighlightPainter-yes-LayerPainter. (Note that it doesn't matter what Highlighter is used, Layered or not, only the HighlightPainter of a particular highlight.)

(Now, in my case, I was also interested in having the underlying highlights showing through the selection highlight. I did this by using a semi-transparent selection colour: jtextpane.setSelectionColor(Color(80, 120, 255, 100)).)

Evgeni Sergeev
  • 22,495
  • 17
  • 107
  • 124
2

never used J/XLayer, but there are another way painting to the JViewport or Glass/RootPane, then theoretically it could be able to create 3_layer painting

EDIT

by using J/XLayer is there another issue that you have to simulating MouseEvent for example this way

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
1

@Evgeni answer is correct. It took me some time to find this post on how to simultaneously render Highlights and Selections for my JEditorPane.

final Highlighter highlighter = new DefaultHighlighter();
editorPane.setHighlighter(highlighter);
editorPane.setSelectionColor(new Color(80, 120, 255, 100));

final HighlightPainter matchPainter = new Highlighter.HighlightPainter() {

    final DefaultHighlightPainter helper = newDefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
                    @Override
                    public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) 
    {
        helper.paint(g, p0, p1, bounds, c);
    }
};

highlighter.addHighlight(iIndexToTradeId, iIndexToTradeId+sTradeId.length(), matchPainter);
chris
  • 11
  • 1
0

My hat is off to @Evgeni Sergeev, as I put to good use his observation that HighlightPainter draws under LayerPainter as shown here:

Referring to this image Black Bar at the top of a Brown Box, with a Blue Box to the right of the Brown Box, the black line just inside the top of the brown box is drawn by:

class LineHighlightPainter extends DefaultHighlightPainter

This gives me a free implementation of LayerPainter, which is only an interface.

The brown and blue boxes are drawn by:

class RVMHighlightPainter implements Highlighter.HighlightPainter

I copied the code for both of these from UnderlineHighlightPainter, which I found here.

Community
  • 1
  • 1
NeuroDuck
  • 81
  • 1
  • 2