CurrentLineHighlighterUtility.java
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(00, 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 = (JTextComponente.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 = (JTextComponente.getSource();
096             currentLineChanged(c);
097         }
098 
099         public void mouseDragged(final MouseEvent e) {
100             JTextComponent c = (JTextComponente.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 = ((Integerc.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 }