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