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 }
064 }
065
066 /**
067 * Uninstall CurrentLineHighligher for the given JTextComponent.
068 *
069 * @param c Uninstall highlighter here.
070 */
071 public static void uninstall(final JTextComponent c) {
072 c.putClientProperty(LINE_HIGHLIGHT, null);
073 c.putClientProperty(PREVIOUS_CARET, null);
074 c.removeCaretListener(caretListener);
075 c.removeMouseListener(mouseListener);
076 c.removeMouseMotionListener(mouseListener);
077 }
078
079 /**
080 * Caret listener.
081 */
082 private static CaretListener caretListener = new CaretListener() {
083 public void caretUpdate(final CaretEvent e) {
084 JTextComponent c = (JTextComponent) e.getSource();
085 currentLineChanged(c);
086 }
087 };
088
089 /**
090 * Mouse listener.
091 */
092 private static MouseInputAdapter mouseListener = new MouseInputAdapter() {
093 public void mousePressed(final MouseEvent e) {
094 JTextComponent c = (JTextComponent) e.getSource();
095 currentLineChanged(c);
096 }
097
098 public void mouseDragged(final MouseEvent e) {
099 JTextComponent c = (JTextComponent) e.getSource();
100 currentLineChanged(c);
101 }
102 };
103
104 /**
105 * Fetches the previous caret location, stores the current caret location. If the caret is on
106 * another line, repaint the previous line and the current line
107 *
108 * @param c the text component
109 */
110 private static void currentLineChanged(final JTextComponent c) {
111 if (null == c.getClientProperty(PREVIOUS_CARET)) {
112 return;
113 }
114 try {
115 final int previousCaret = ((Integer) c.getClientProperty(PREVIOUS_CARET)).intValue();
116 final Rectangle prev = c.modelToView(previousCaret);
117 final Rectangle r = c.modelToView(c.getCaretPosition());
118 c.putClientProperty(PREVIOUS_CARET, new Integer(c.getCaretPosition()));
119
120 if (prev.y != r.y) {
121 c.repaint(0, prev.y, c.getWidth(), r.height);
122 c.repaint(0, r.y, c.getWidth(), r.height);
123 }
124 } catch (final BadLocationException ignore) {
125 // ignore
126 }
127 }
128
129 /**
130 * Painter for the highlighted area.
131 */
132 private static Highlighter.HighlightPainter painter = new Highlighter.HighlightPainter() {
133 public void paint(final Graphics g, final int p0, final int p1, final Shape bounds,
134 final JTextComponent c) {
135 GuiHelper.paintCurrentLineBackground(g, c,
136 GuiHelper.getLineHighlighterBackgroundColor());
137 }
138 };
139 }
|