/** * Copyright (c) 2001-2017 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html */ package net.sf.robocode.ui.editor; import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseMotionListener; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.BadLocationException; import javax.swing.text.Highlighter; import javax.swing.text.JTextComponent; import net.sf.robocode.ui.editor.theme.EditorThemePropertiesManager; import net.sf.robocode.ui.editor.theme.EditorThemePropertyChangeAdapter; /** * Class used for highlighting the current line for a JTextComponent. * * @author Santhosh Kumar T (original) * @author Peter De Bruycker (contributor) * @author Flemming N. Larsen (contributor) */ public final class LineHighlighter { private static final String LINE_HIGHLIGHT = "line-highlight"; private static final String PREVIOUS_CARET = "previous-caret"; private static Color color; // Color used for highlighting the line private LineHighlighter() {} /** * Installs CurrentLineHilighter for the given JTextComponent. * @param c is the text component */ public static void install(JTextComponent c) { try { Object obj = c.getHighlighter().addHighlight(0, 0, painter); c.putClientProperty(LINE_HIGHLIGHT, obj); c.putClientProperty(PREVIOUS_CARET, new Integer(c.getCaretPosition())); c.addCaretListener(caretListener); c.addMouseListener(mouseListener); c.addMouseMotionListener(mouseMotionListener); color = EditorThemePropertiesManager.getCurrentEditorThemeProperties().getHighlightedLineColor(); EditorThemePropertiesManager.addListener(editorThemePropertyChangeListener); } catch (BadLocationException ex) {} } /** * Uninstalls CurrentLineHighligher for the given JTextComponent. * @param c is the text component */ public static void uninstall(JTextComponent c) { c.putClientProperty(LINE_HIGHLIGHT, null); c.putClientProperty(PREVIOUS_CARET, null); c.removeCaretListener(caretListener); c.removeMouseListener(mouseListener); c.removeMouseMotionListener(mouseMotionListener); EditorThemePropertiesManager.removeListener(editorThemePropertyChangeListener); } /** * Fetches the previous caret location, stores the current caret location, * If the caret is on another line, repaint the previous line and the current line * @param c is the text component */ private static void caretUpdate(JTextComponent c) { try { int previousCaret = ((Integer) c.getClientProperty(PREVIOUS_CARET)).intValue(); final int actualCaretPosition = c.getCaretPosition(); c.putClientProperty(PREVIOUS_CARET, new Integer(actualCaretPosition)); Rectangle prev = c.modelToView(previousCaret); Rectangle r = c.modelToView(actualCaretPosition); // c.putClientProperty(PREVIOUS_CARET, new Integer(actualCaretPosition)); if (prev != null && prev.y != r.y) { c.repaint(0, prev.y, c.getWidth(), r.height); c.repaint(0, r.y, c.getWidth(), r.height); } } catch (BadLocationException ignore) {} } private static CaretListener caretListener = new CaretListener() { @Override public void caretUpdate(CaretEvent e) { JTextComponent c = (JTextComponent) e.getSource(); LineHighlighter.caretUpdate(c); } }; private static MouseListener mouseListener = new MouseAdapter() { // highlight the line the user clicks on @Override public void mousePressed(MouseEvent e) { JTextComponent c = (JTextComponent) e.getSource(); caretUpdate(c); } }; private static MouseMotionListener mouseMotionListener = new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { JTextComponent c = (JTextComponent) e.getSource(); caretUpdate(c); } }; private static EditorThemePropertyChangeAdapter editorThemePropertyChangeListener = new EditorThemePropertyChangeAdapter() { public void onHighlightedLineColorChanged(Color newColor) { if (!color.equals(newColor)) { color = newColor; } } }; private static Highlighter.HighlightPainter painter = new Highlighter.HighlightPainter() { @Override 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(), r.height); } catch (BadLocationException ignore) {} } }; }