/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
****************************************************************/
package org.apache.cayenne.swing.components.textpane;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.LayeredHighlighter;
import javax.swing.text.Position;
import javax.swing.text.View;
public class UnderlineHighlighterForText extends DefaultHighlighter {
public UnderlineHighlighterForText(Color c) {
painter = (c == null ? sharedPainter : new UnderlineHighlightPainter(c));
}
// Convenience method to add a highlight with
// the default painter.
public Object addHighlight(int p0, int p1) throws BadLocationException {
return addHighlight(p0, p1, painter);
}
public void setDrawsLayeredHighlights(boolean newValue) {
// Illegal if false - we only support layered highlights
if (newValue == false) {
throw new IllegalArgumentException(
"UnderlineHighlighterForArea only draws layered highlights");
}
super.setDrawsLayeredHighlights(true);
}
// Painter for underlined highlights
public static class UnderlineHighlightPainter extends LayeredHighlighter.LayerPainter {
public UnderlineHighlightPainter(Color c) {
color = c;
}
public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
// Do nothing: this method will never be called
}
public Shape paintLayer(
Graphics g,
int offs0,
int offs1,
Shape bounds,
JTextComponent c,
View view) {
g.setColor(color == null ? c.getSelectionColor() : color);
Rectangle alloc = null;
if (offs0 == view.getStartOffset() && offs1 == view.getEndOffset()) {
if (bounds instanceof Rectangle) {
alloc = (Rectangle) bounds;
}
else {
alloc = bounds.getBounds();
}
}
else {
try {
Shape shape = view.modelToView(
offs0,
Position.Bias.Forward,
offs1,
Position.Bias.Backward,
bounds);
alloc = (shape instanceof Rectangle) ? (Rectangle) shape : shape
.getBounds();
}
catch (BadLocationException e) {
return null;
}
}
FontMetrics fm = c.getFontMetrics(c.getFont());
int baseline = alloc.y + alloc.height - fm.getDescent() + 1;
int i = alloc.x;
int end = alloc.x + alloc.width - 1;
while (i < end) {
g.drawLine(i, baseline, i + 2, baseline);
g.drawLine(i, baseline + 1, i + 2, baseline + 1);
i += 4;
}
return alloc;
}
protected Color color; // The color for the underline
}
// Shared painter used for default highlighting
protected static final Highlighter.HighlightPainter sharedPainter = new UnderlineHighlightPainter(
null);
// Painter used for this highlighter
protected Highlighter.HighlightPainter painter;
}