FileDocCategorySizeDatePackage
DefaultHighlighter.javaAPI DocJava SE 5 API18801Fri Aug 26 14:58:14 BST 2005javax.swing.text

DefaultHighlighter

public class DefaultHighlighter extends LayeredHighlighter
Implements the Highlighter interfaces. Implements a simple highlight painter that renders in a solid color.
author
Timothy Prinzing
version
1.39 12/19/03
see
Highlighter

Fields Summary
private static final Highlighter$Highlight[]
noHighlights
private Vector
highlights
private JTextComponent
component
private boolean
drawsLayeredHighlights
private SafeDamager
safeDamager
public static final LayeredHighlighter$LayerPainter
DefaultPainter
Default implementation of LayeredHighlighter.LayerPainter that can be used for painting highlights.

As of 1.4 this field is final.

Constructors Summary
public DefaultHighlighter()
Creates a new DefaultHighlighther object.

	drawsLayeredHighlights = true;
    
Methods Summary
public java.lang.ObjectaddHighlight(int p0, int p1, javax.swing.text.Highlighter$HighlightPainter p)
Adds a highlight to the view. Returns a tag that can be used to refer to the highlight.

param
p0 the start offset of the range to highlight >= 0
param
p1 the end offset of the range to highlight >= p0
param
p the painter to use to actually render the highlight
return
an object that can be used as a tag to refer to the highlight
exception
BadLocationException if the specified location is invalid

	Document doc = component.getDocument();
	HighlightInfo i = (getDrawsLayeredHighlights() &&
			   (p instanceof LayeredHighlighter.LayerPainter)) ?
	                  new LayeredHighlightInfo() : new HighlightInfo();
	i.painter = p;
	i.p0 = doc.createPosition(p0);
	i.p1 = doc.createPosition(p1);
	highlights.addElement(i);
        safeDamageRange(p0, p1);
        return i;
    
public voidchangeHighlight(java.lang.Object tag, int p0, int p1)
Changes a highlight.

param
tag the highlight tag
param
p0 the beginning of the range >= 0
param
p1 the end of the range >= p0
exception
BadLocationException if the specified location is invalid

	Document doc = component.getDocument();
	if (tag instanceof LayeredHighlightInfo) {
	    LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag;
	    if (lhi.width > 0 && lhi.height > 0) {
		component.repaint(lhi.x, lhi.y, lhi.width, lhi.height);
	    }
	    // Mark the highlights region as invalid, it will reset itself
	    // next time asked to paint.
	    lhi.width = lhi.height = 0;
	    lhi.p0 = doc.createPosition(p0);
	    lhi.p1 = doc.createPosition(p1);
            safeDamageRange(Math.min(p0, p1), Math.max(p0, p1));
	}
	else {
	    HighlightInfo info = (HighlightInfo) tag;
	    int oldP0 = info.p0.getOffset();
	    int oldP1 = info.p1.getOffset();
	    if (p0 == oldP0) {
                safeDamageRange(Math.min(oldP1, p1),
				   Math.max(oldP1, p1));
	    } else if (p1 == oldP1) {
                safeDamageRange(Math.min(p0, oldP0),
				   Math.max(p0, oldP0));
	    } else {
                safeDamageRange(oldP0, oldP1);
                safeDamageRange(p0, p1);
	    }
	    info.p0 = doc.createPosition(p0);
	    info.p1 = doc.createPosition(p1);
	}
    
public voiddeinstall(javax.swing.text.JTextComponent c)
Called when the UI is being removed from the interface of a JTextComponent.

param
c the component
see
Highlighter#deinstall

	component = null;
    
public booleangetDrawsLayeredHighlights()

	return drawsLayeredHighlights;
    
public javax.swing.text.Highlighter$Highlight[]getHighlights()
Makes a copy of the highlights. Does not actually clone each highlight, but only makes references to them.

return
the copy
see
Highlighter#getHighlights

        int size = highlights.size();
        if (size == 0) {
            return noHighlights;
        }
	Highlighter.Highlight[] h = new Highlighter.Highlight[size];
	highlights.copyInto(h);
	return h;
    
public voidinstall(javax.swing.text.JTextComponent c)
Called when the UI is being installed into the interface of a JTextComponent. Installs the editor, and removes any existing highlights.

param
c the editor component
see
Highlighter#install

	component = c;
	removeAllHighlights();
    
public voidpaint(java.awt.Graphics g)
Renders the highlights.

param
g the graphics context

        // PENDING(prinz) - should cull ranges not visible
        int len = highlights.size();
        for (int i = 0; i < len; i++) {
	    HighlightInfo info = (HighlightInfo) highlights.elementAt(i);
	    if (!(info instanceof LayeredHighlightInfo)) {
		// Avoid allocing unless we need it.
		Rectangle a = component.getBounds();
		Insets insets = component.getInsets();
		a.x = insets.left;
		a.y = insets.top;
		a.width -= insets.left + insets.right;
		a.height -= insets.top + insets.bottom;
		for (; i < len; i++) {
		    info = (HighlightInfo)highlights.elementAt(i);
		    if (!(info instanceof LayeredHighlightInfo)) {
			Highlighter.HighlightPainter p = info.getPainter();
			p.paint(g, info.getStartOffset(), info.getEndOffset(),
				a, component);
		    }
		}
	    }
	}
    
public voidpaintLayeredHighlights(java.awt.Graphics g, int p0, int p1, java.awt.Shape viewBounds, javax.swing.text.JTextComponent editor, javax.swing.text.View view)
When leaf Views (such as LabelView) are rendering they should call into this method. If a highlight is in the given region it will be drawn immediately.

param
g Graphics used to draw
param
p0 starting offset of view
param
p1 ending offset of view
param
viewBounds Bounds of View
param
editor JTextComponent
param
view View instance being rendered

	for (int counter = highlights.size() - 1; counter >= 0; counter--) {
	    Object tag = highlights.elementAt(counter);
	    if (tag instanceof LayeredHighlightInfo) {
		LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag;
		int start = lhi.getStartOffset();
		int end = lhi.getEndOffset();
		if ((p0 < start && p1 > start) ||
		    (p0 >= start && p0 < end)) {
		    lhi.paintLayeredHighlights(g, p0, p1, viewBounds,
					       editor, view);
		}
	    }
	}
    
public voidremoveAllHighlights()
Removes all highlights.

	TextUI mapper = component.getUI();
	if (getDrawsLayeredHighlights()) {
	    int len = highlights.size();
	    if (len != 0) {
		int minX = 0;
		int minY = 0;
		int maxX = 0;
		int maxY = 0;
		int p0 = -1;
		int p1 = -1;
		for (int i = 0; i < len; i++) {
                    HighlightInfo hi = (HighlightInfo)highlights.elementAt(i);
                    if (hi instanceof LayeredHighlightInfo) {
                        LayeredHighlightInfo info = (LayeredHighlightInfo)hi;
                        minX = Math.min(minX, info.x);
                        minY = Math.min(minY, info.y);
                        maxX = Math.max(maxX, info.x + info.width);
                        maxY = Math.max(maxY, info.y + info.height);
                    }
                    else {
                        if (p0 == -1) {
                            p0 = hi.p0.getOffset();
                            p1 = hi.p1.getOffset();
                        }
                        else {
                            p0 = Math.min(p0, hi.p0.getOffset());
                            p1 = Math.max(p1, hi.p1.getOffset());
                        }
                    }
                }
		if (minX != maxX && minY != maxY) {
		    component.repaint(minX, minY, maxX - minX, maxY - minY);
		}
                if (p0 != -1) {
                    try {
                        safeDamageRange(p0, p1);
                    } catch (BadLocationException e) {}
                }
		highlights.removeAllElements();
	    }
	}
	else if (mapper != null) {
	    int len = highlights.size();
	    if (len != 0) {
		int p0 = Integer.MAX_VALUE;
		int p1 = 0;
		for (int i = 0; i < len; i++) {
		    HighlightInfo info = (HighlightInfo) highlights.elementAt(i);
		    p0 = Math.min(p0, info.p0.getOffset());
		    p1 = Math.max(p1, info.p1.getOffset());
		}
                try {
                    safeDamageRange(p0, p1);
                } catch (BadLocationException e) {}

		highlights.removeAllElements();
	    }
	}
    
public voidremoveHighlight(java.lang.Object tag)
Removes a highlight from the view.

param
tag the reference to the highlight

	if (tag instanceof LayeredHighlightInfo) {
	    LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag;
	    if (lhi.width > 0 && lhi.height > 0) {
		component.repaint(lhi.x, lhi.y, lhi.width, lhi.height);
	    }
	}
	else {
	    HighlightInfo info = (HighlightInfo) tag;
            safeDamageRange(info.p0, info.p1);
	}
	highlights.removeElement(tag);
    
private voidsafeDamageRange(javax.swing.text.Position p0, javax.swing.text.Position p1)
Queues damageRange() call into event dispatch thread to be sure that views are in consistent state.

        safeDamager.damageRange(p0, p1);
    
private voidsafeDamageRange(int a0, int a1)
Queues damageRange() call into event dispatch thread to be sure that views are in consistent state.

        Document doc = component.getDocument();
        safeDamageRange(doc.createPosition(a0), doc.createPosition(a1));
    
public voidsetDrawsLayeredHighlights(boolean newValue)
If true, highlights are drawn as the Views draw the text. That is the Views will call into paintLayeredHighlight which will result in a rectangle being drawn before the text is drawn (if the offsets are in a highlighted region that is). For this to work the painter supplied must be an instance of LayeredHighlightPainter.

	drawsLayeredHighlights = newValue;