/***************************************************************** * 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; }