/** * */ package apu.scratch.converter; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; /* * Track the movement of the Caret by painting a background line at the * current caret position. */ public class LinePainter implements Highlighter.HighlightPainter, CaretListener, MouseListener, MouseMotionListener { private JTextComponent component; private Color color; private Rectangle lastView; /* * The line color will be calculated automatically by attempting to make the * current selection lighter by a factor of 1.2. * * @param component text component that requires background line painting */ public LinePainter(JTextComponent component) { this(component, null); setLighter(component.getSelectionColor()); } /* * Manually control the line color * * @param component text component that requires background line painting * * @param color the color of the background line */ public LinePainter(JTextComponent component, Color color) { this.component = component; setColor(color); // Add listeners so we know when to change highlighting component.addCaretListener(this); component.addMouseListener(this); component.addMouseMotionListener(this); // Turn highlighting on by adding a dummy highlight try { component.getHighlighter().addHighlight(0, 0, this); } catch (BadLocationException ble) { } } /* * You can reset the line color at any time * * @param color the color of the background line */ public void setColor(Color color) { this.color = color; } /* * Calculate the line color by making the selection color lighter * * @return the color of the background line */ public void setLighter(Color color) { int red = Math.min(255, (int) (color.getRed() * 1.2)); int green = Math.min(255, (int) (color.getGreen() * 1.2)); int blue = Math.min(255, (int) (color.getBlue() * 1.2)); setColor(new Color(red, green, blue)); } // Paint the background highlight public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) { try { Rectangle r = c.modelToView(c.getCaretPosition()); g.setColor(color); g.fillRect(0, r.y, c.getWidth() + 20, r.height); if (lastView == null) lastView = r; } catch (BadLocationException ble) { System.out.println(ble); } } /* * Caret position has changed, remove the highlight */ private void resetHighlight() { // Use invokeLater to make sure updates to the Document are completed, // otherwise Undo processing causes the modelToView method to loop. SwingUtilities.invokeLater(new Runnable() { public void run() { try { int offset = component.getCaretPosition(); Rectangle currentView = component.modelToView(offset); // Remove the highlighting from the previously highlighted // line if (lastView.y != currentView.y) { component.repaint(0, lastView.y, component.getWidth(), lastView.height); lastView = currentView; } } catch (BadLocationException ble) { } } }); } // Implement CaretListener public void caretUpdate(CaretEvent e) { resetHighlight(); } // Implement MouseListener public void mousePressed(MouseEvent e) { resetHighlight(); } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } // Implement MouseMotionListener public void mouseDragged(MouseEvent e) { resetHighlight(); } public void mouseMoved(MouseEvent e) { } }