001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * The main author is Santhosh Kumar T. Visit his great home page under:
004 * http://www.jroller.com/santhosh/
005 *
006 * The original source for this file is:
007 * http://www.jroller.com/santhosh/entry/currentlinehighlighter_contd
008 *
009 * It is distributed under the GNU Lesser General Public License:
010 * http://www.gnu.org/copyleft/lesser.html
011 */
012 package org.qedeq.gui.se.util;
013
014 import java.awt.Graphics;
015 import java.awt.Rectangle;
016 import java.awt.Shape;
017 import java.awt.event.MouseEvent;
018
019 import javax.swing.event.CaretEvent;
020 import javax.swing.event.CaretListener;
021 import javax.swing.event.MouseInputAdapter;
022 import javax.swing.text.BadLocationException;
023 import javax.swing.text.Highlighter;
024 import javax.swing.text.JTextComponent;
025
026 /**
027 * This class can be used to highlight the current line for any JTextComponent.
028 * To be used as a static utility
029 *
030 * @author Santhosh Kumar T
031 * @author Peter De Bruycker
032 * @author Michael Meyling (small adaption).
033 */
034 public final class CurrentLineHighlighterUtility {
035
036 /** NOI18N - used as client property. */
037 private static final String LINE_HIGHLIGHT = "lineHighLight";
038
039 /** NOI18N - used as client property. */
040 private static final String PREVIOUS_CARET = "previousCaret";
041
042 /**
043 * Constructor.
044 */
045 private CurrentLineHighlighterUtility() {
046 // nothing to do
047 }
048
049 /**
050 * Installs CurrentLineHighlighterUtility for the given JTextComponent.
051 *
052 * @param c Install highlighter here.
053 */
054 public static void install(final JTextComponent c) {
055 try {
056 final Object obj = c.getHighlighter().addHighlight(0, 0, painter);
057 c.putClientProperty(LINE_HIGHLIGHT, obj);
058 c.putClientProperty(PREVIOUS_CARET, new Integer(c.getCaretPosition()));
059 c.addCaretListener(caretListener);
060 c.addMouseListener(mouseListener);
061 c.addMouseMotionListener(mouseListener);
062 } catch (BadLocationException ignore) {
063 // ignore
064 }
065 }
066
067 /**
068 * Uninstall CurrentLineHighligher for the given JTextComponent.
069 *
070 * @param c Uninstall highlighter here.
071 */
072 public static void uninstall(final JTextComponent c) {
073 c.putClientProperty(LINE_HIGHLIGHT, null);
074 c.putClientProperty(PREVIOUS_CARET, null);
075 c.removeCaretListener(caretListener);
076 c.removeMouseListener(mouseListener);
077 c.removeMouseMotionListener(mouseListener);
078 }
079
080 /**
081 * Caret listener.
082 */
083 private static CaretListener caretListener = new CaretListener() {
084 public void caretUpdate(final CaretEvent e) {
085 JTextComponent c = (JTextComponent) e.getSource();
086 currentLineChanged(c);
087 }
088 };
089
090 /**
091 * Mouse listener.
092 */
093 private static MouseInputAdapter mouseListener = new MouseInputAdapter() {
094 public void mousePressed(final MouseEvent e) {
095 JTextComponent c = (JTextComponent) e.getSource();
096 currentLineChanged(c);
097 }
098
099 public void mouseDragged(final MouseEvent e) {
100 JTextComponent c = (JTextComponent) e.getSource();
101 currentLineChanged(c);
102 }
103 };
104
105 /**
106 * Fetches the previous caret location, stores the current caret location. If the caret is on
107 * another line, repaint the previous line and the current line
108 *
109 * @param c the text component
110 */
111 private static void currentLineChanged(final JTextComponent c) {
112 if (null == c.getClientProperty(PREVIOUS_CARET)) {
113 return;
114 }
115 try {
116 final int previousCaret = ((Integer) c.getClientProperty(PREVIOUS_CARET)).intValue();
117 final Rectangle prev = c.modelToView(previousCaret);
118 final Rectangle r = c.modelToView(c.getCaretPosition());
119 c.putClientProperty(PREVIOUS_CARET, new Integer(c.getCaretPosition()));
120
121 if (prev.y != r.y) {
122 c.repaint(0, prev.y, c.getWidth(), r.height);
123 c.repaint(0, r.y, c.getWidth(), r.height);
124 }
125 } catch (final BadLocationException ignore) {
126 // ignore
127 }
128 }
129
130 /**
131 * Painter for the highlighted area.
132 */
133 private static Highlighter.HighlightPainter painter = new Highlighter.HighlightPainter() {
134 public void paint(final Graphics g, final int p0, final int p1, final Shape bounds,
135 final JTextComponent c) {
136 GuiHelper.paintCurrentLineBackground(g, c,
137 GuiHelper.getLineHighlighterBackgroundColor());
138 }
139 };
140 }
|