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 LayerPainter
s. 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))
.)