1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48:
49: import ;
50: import ;
51:
52:
56: public class DefaultHighlighter extends LayeredHighlighter
57: {
58: public static class DefaultHighlightPainter
59: extends LayerPainter
60: {
61: private Color color;
62:
63: public DefaultHighlightPainter(Color c)
64: {
65: super();
66: color = c;
67: }
68:
69: public Color getColor()
70: {
71: return color;
72: }
73:
74: public void paint(Graphics g, int p0, int p1, Shape bounds,
75: JTextComponent t)
76: {
77: if (p0 == p1)
78: return;
79:
80: Rectangle rect = bounds.getBounds();
81:
82: Color col = getColor();
83: if (col == null)
84: col = t.getSelectionColor();
85: g.setColor(col);
86:
87: TextUI ui = t.getUI();
88:
89: try
90: {
91:
92: Rectangle l0 = ui.modelToView(t, p0, null);
93: Rectangle l1 = ui.modelToView(t, p1, null);
94:
95:
96:
97:
98: if (l0.y == l1.y)
99: {
100: SwingUtilities.computeUnion(l0.x, l0.y, l0.width, l0.height, l1);
101:
102:
103: SwingUtilities.computeIntersection(rect.x, rect.y, rect.width,
104: rect.height, l1);
105:
106: g.fillRect(l1.x, l1.y, l1.width, l1.height);
107: }
108: else
109: {
110:
111:
112:
113:
114:
115:
116:
117:
118: int firstLineWidth = rect.x + rect.width - l0.x;
119: g.fillRect(l0.x, l0.y, firstLineWidth, l0.height);
120: if (l0.y + l0.height != l1.y)
121: {
122: g.fillRect(rect.x, l0.y + l0.height, rect.width,
123: l1.y - l0.y - l0.height);
124: }
125: g.fillRect(rect.x, l1.y, l1.x - rect.x, l1.height);
126: }
127: }
128: catch (BadLocationException ex)
129: {
130:
131:
132: }
133: }
134:
135: public Shape paintLayer(Graphics g, int p0, int p1, Shape bounds,
136: JTextComponent c, View view)
137: {
138: Color col = getColor();
139: if (col == null)
140: col = c.getSelectionColor();
141: g.setColor(col);
142:
143: Rectangle rect = null;
144: if (p0 == view.getStartOffset() && p1 == view.getEndOffset())
145: {
146:
147: rect = bounds instanceof Rectangle ? (Rectangle) bounds
148: : bounds.getBounds();
149: }
150: else
151: {
152:
153: try
154: {
155: Shape s = view.modelToView(p0, Position.Bias.Forward,
156: p1, Position.Bias.Backward,
157: bounds);
158: rect = s instanceof Rectangle ? (Rectangle) s : s.getBounds();
159: }
160: catch (BadLocationException ex)
161: {
162:
163: }
164: }
165:
166: if (rect != null)
167: {
168: g.fillRect(rect.x, rect.y, rect.width, rect.height);
169: }
170: return rect;
171: }
172: }
173:
174: private class HighlightEntry implements Highlighter.Highlight
175: {
176: Position p0;
177: Position p1;
178: Highlighter.HighlightPainter painter;
179:
180: public HighlightEntry(Position p0, Position p1,
181: Highlighter.HighlightPainter painter)
182: {
183: this.p0 = p0;
184: this.p1 = p1;
185: this.painter = painter;
186: }
187:
188: public int getStartOffset()
189: {
190: return p0.getOffset();
191: }
192:
193: public int getEndOffset()
194: {
195: return p1.getOffset();
196: }
197:
198: public Highlighter.HighlightPainter getPainter()
199: {
200: return painter;
201: }
202: }
203:
204:
210: private class LayerHighlightEntry
211: extends HighlightEntry
212: {
213:
214:
217: Rectangle paintRect = new Rectangle();
218:
219: LayerHighlightEntry(Position p0, Position p1,
220: Highlighter.HighlightPainter p)
221: {
222: super(p0, p1, p);
223: }
224:
225:
230: void paintLayeredHighlight(Graphics g, int p0, int p1, Shape bounds,
231: JTextComponent tc, View view)
232: {
233: p0 = Math.max(getStartOffset(), p0);
234: p1 = Math.min(getEndOffset(), p1);
235:
236: Highlighter.HighlightPainter painter = getPainter();
237: if (painter instanceof LayerPainter)
238: {
239: LayerPainter layerPainter = (LayerPainter) painter;
240: Shape area = layerPainter.paintLayer(g, p0, p1, bounds, tc, view);
241: Rectangle rect;
242: if (area instanceof Rectangle && paintRect != null)
243: rect = (Rectangle) area;
244: else
245: rect = area.getBounds();
246:
247: if (paintRect.width == 0 || paintRect.height == 0)
248: paintRect = rect.getBounds();
249: else
250: paintRect = SwingUtilities.computeUnion(rect.x, rect.y, rect.width,
251: rect.height, paintRect);
252: }
253: }
254: }
255:
256:
259: public static final LayeredHighlighter.LayerPainter DefaultPainter =
260: new DefaultHighlightPainter(null);
261:
262: private JTextComponent textComponent;
263: private ArrayList highlights = new ArrayList();
264: private boolean drawsLayeredHighlights = true;
265:
266: public DefaultHighlighter()
267: {
268:
269: }
270:
271: public boolean getDrawsLayeredHighlights()
272: {
273: return drawsLayeredHighlights;
274: }
275:
276: public void setDrawsLayeredHighlights(boolean newValue)
277: {
278: drawsLayeredHighlights = newValue;
279: }
280:
281: private void checkPositions(int p0, int p1)
282: throws BadLocationException
283: {
284: if (p0 < 0)
285: throw new BadLocationException("DefaultHighlighter", p0);
286:
287: if (p1 < p0)
288: throw new BadLocationException("DefaultHighlighter", p1);
289: }
290:
291: public void install(JTextComponent c)
292: {
293: textComponent = c;
294: removeAllHighlights();
295: }
296:
297: public void deinstall(JTextComponent c)
298: {
299: textComponent = null;
300: }
301:
302: public Object addHighlight(int p0, int p1,
303: Highlighter.HighlightPainter painter)
304: throws BadLocationException
305: {
306: checkPositions(p0, p1);
307: HighlightEntry entry;
308: Document doc = textComponent.getDocument();
309: Position pos0 = doc.createPosition(p0);
310: Position pos1 = doc.createPosition(p1);
311: if (getDrawsLayeredHighlights() && painter instanceof LayerPainter)
312: entry = new LayerHighlightEntry(pos0, pos1, painter);
313: else
314: entry = new HighlightEntry(pos0, pos1, painter);
315: highlights.add(entry);
316:
317: textComponent.getUI().damageRange(textComponent, p0, p1);
318:
319: return entry;
320: }
321:
322: public void removeHighlight(Object tag)
323: {
324: HighlightEntry entry = (HighlightEntry) tag;
325: if (entry instanceof LayerHighlightEntry)
326: {
327: LayerHighlightEntry lEntry = (LayerHighlightEntry) entry;
328: Rectangle paintRect = lEntry.paintRect;
329: textComponent.repaint(paintRect.x, paintRect.y, paintRect.width,
330: paintRect.height);
331: }
332: else
333: {
334: textComponent.getUI().damageRange(textComponent,
335: entry.getStartOffset(),
336: entry.getEndOffset());
337: }
338: highlights.remove(tag);
339:
340: }
341:
342: public void removeAllHighlights()
343: {
344:
345: int minX = 0;
346: int maxX = 0;
347: int minY = 0;
348: int maxY = 0;
349: int p0 = -1;
350: int p1 = -1;
351: for (Iterator i = highlights.iterator(); i.hasNext();)
352: {
353: HighlightEntry e = (HighlightEntry) i.next();
354: if (e instanceof LayerHighlightEntry)
355: {
356: LayerHighlightEntry le = (LayerHighlightEntry) e;
357: Rectangle r = le.paintRect;
358: minX = Math.min(r.x, minX);
359: maxX = Math.max(r.x + r.width, maxX);
360: minY = Math.min(r.y, minY);
361: maxY = Math.max(r.y + r.height, maxY);
362: }
363: else
364: {
365: if (p0 == -1 || p1 == -1)
366: {
367: p0 = e.getStartOffset();
368: p1 = e.getEndOffset();
369: }
370: else
371: {
372: p0 = Math.min(p0, e.getStartOffset());
373: p1 = Math.max(p1, e.getEndOffset());
374: }
375: }
376: if (minX != maxX && minY != maxY)
377: textComponent.repaint(minX, minY, maxX - minX, maxY - minY);
378: if (p0 != -1 && p1 != -1)
379: {
380: TextUI ui = textComponent.getUI();
381: ui.damageRange(textComponent, p0, p1);
382: }
383:
384: }
385: highlights.clear();
386: }
387:
388: public Highlighter.Highlight[] getHighlights()
389: {
390: return (Highlighter.Highlight[])
391: highlights.toArray(new Highlighter.Highlight[highlights.size()]);
392: }
393:
394: public void changeHighlight(Object tag, int n0, int n1)
395: throws BadLocationException
396: {
397: Document doc = textComponent.getDocument();
398: TextUI ui = textComponent.getUI();
399: if (tag instanceof LayerHighlightEntry)
400: {
401: LayerHighlightEntry le = (LayerHighlightEntry) tag;
402: Rectangle r = le.paintRect;
403: if (r.width > 0 && r.height > 0)
404: textComponent.repaint(r.x, r.y, r.width, r.height);
405: r.width = 0;
406: r.height = 0;
407: le.p0 = doc.createPosition(n0);
408: le.p1 = doc.createPosition(n1);
409: ui.damageRange(textComponent, Math.min(n0, n1), Math.max(n0, n1));
410: }
411: else if (tag instanceof HighlightEntry)
412: {
413: HighlightEntry e = (HighlightEntry) tag;
414: int p0 = e.getStartOffset();
415: int p1 = e.getEndOffset();
416: if (p0 == n0)
417: {
418: ui.damageRange(textComponent, Math.min(p1, n1),
419: Math.max(p1, n1));
420: }
421: else if (n1 == p1)
422: {
423: ui.damageRange(textComponent, Math.min(p0, n0),
424: Math.max(p0, n0));
425: }
426: else
427: {
428: ui.damageRange(textComponent, p0, p1);
429: ui.damageRange(textComponent, n0, n1);
430: }
431: e.p0 = doc.createPosition(n0);
432: e.p1 = doc.createPosition(n1);
433: }
434: }
435:
436: public void paintLayeredHighlights(Graphics g, int p0, int p1,
437: Shape viewBounds, JTextComponent editor,
438: View view)
439: {
440: for (Iterator i = highlights.iterator(); i.hasNext();)
441: {
442: Object o = i.next();
443: if (o instanceof LayerHighlightEntry)
444: {
445: LayerHighlightEntry entry = (LayerHighlightEntry) o;
446: int start = entry.getStartOffset();
447: int end = entry.getEndOffset();
448: if ((p0 < start && p1 > start) || (p0 >= start && p0 < end))
449: entry.paintLayeredHighlight(g, p0, p1, viewBounds, editor, view);
450: }
451: }
452: }
453:
454: public void paint(Graphics g)
455: {
456: int size = highlights.size();
457:
458:
459: if (size == 0)
460: return;
461:
462:
463: Insets insets = textComponent.getInsets();
464: Shape bounds =
465: new Rectangle(insets.left,
466: insets.top,
467: textComponent.getWidth() - insets.left - insets.right,
468: textComponent.getHeight() - insets.top - insets.bottom);
469:
470: for (int index = 0; index < size; ++index)
471: {
472: HighlightEntry entry = (HighlightEntry) highlights.get(index);
473: if (! (entry instanceof LayerHighlightEntry))
474: entry.painter.paint(g, entry.getStartOffset(), entry.getEndOffset(),
475: bounds, textComponent);
476: }
477: }
478: }