Java tutorial
import java.awt.BorderLayout; import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultHighlighter; import javax.swing.text.Document; import javax.swing.text.Highlighter; import javax.swing.text.JTextComponent; import javax.swing.text.LayeredHighlighter; import javax.swing.text.Position; import javax.swing.text.View; public class Main { public static void main(String[] args) { JFrame f = new JFrame(); JPanel panel = new JPanel(); JTextPane textPane = new JTextPane(); JTextField tf = new JTextField("is"); String word = ""; Highlighter highlighter = new UnderlineHighlighter(null); textPane.setHighlighter(highlighter); textPane.setText("This is a test"); panel.setLayout(new BorderLayout()); panel.add(new JLabel("Enter word, then press ENTER key: "), "West"); panel.add(tf, "Center"); final WordSearcher searcher = new WordSearcher(textPane); tf.addActionListener(e -> { String w = tf.getText().trim(); int offset = searcher.search(w); if (offset == -1) { return; } try { textPane.scrollRectToVisible(textPane.modelToView(offset)); } catch (BadLocationException ex) { } }); textPane.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent evt) { searcher.search(word); } @Override public void removeUpdate(DocumentEvent evt) { searcher.search(word); } @Override public void changedUpdate(DocumentEvent evt) { } }); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(panel, "South"); f.add(new JScrollPane(textPane), "Center"); f.setSize(400, 400); f.setVisible(true); } } class WordSearcher { protected JTextComponent comp; protected Highlighter.HighlightPainter painter; public WordSearcher(JTextComponent comp) { this.comp = comp; this.painter = new UnderlineHighlightPainter(Color.red); } public int search(String word) { int firstOffset = -1; Highlighter highlighter = comp.getHighlighter(); Highlighter.Highlight[] highlights = highlighter.getHighlights(); for (int i = 0; i < highlights.length; i++) { Highlighter.Highlight h = highlights[i]; if (h.getPainter() instanceof UnderlineHighlightPainter) { highlighter.removeHighlight(h); } } if (word == null || word.equals("")) { return -1; } String content = null; try { Document d = comp.getDocument(); content = d.getText(0, d.getLength()).toLowerCase(); } catch (BadLocationException e) { return -1; } word = word.toLowerCase(); int lastIndex = 0; int wordSize = word.length(); while ((lastIndex = content.indexOf(word, lastIndex)) != -1) { int endIndex = lastIndex + wordSize; try { highlighter.addHighlight(lastIndex, endIndex, painter); } catch (BadLocationException e) { } if (firstOffset == -1) { firstOffset = lastIndex; } lastIndex = endIndex; } return firstOffset; } } class UnderlineHighlighter extends DefaultHighlighter { protected static final Highlighter.HighlightPainter sharedPainter = new UnderlineHighlightPainter(null); protected Highlighter.HighlightPainter painter; public UnderlineHighlighter(Color c) { painter = (c == null ? sharedPainter : new UnderlineHighlightPainter(c)); } public Object addHighlight(int p0, int p1) throws BadLocationException { return addHighlight(p0, p1, painter); } @Override public void setDrawsLayeredHighlights(boolean newValue) { super.setDrawsLayeredHighlights(true); } } class UnderlineHighlightPainter extends LayeredHighlighter.LayerPainter { protected Color color; public UnderlineHighlightPainter(Color c) { color = c; } @Override public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) { } @Override public Shape paintLayer(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c, View view) { g.setColor(color == null ? c.getSelectionColor() : color); Rectangle rect = null; if (offs0 == view.getStartOffset() && offs1 == view.getEndOffset()) { if (bounds instanceof Rectangle) { rect = (Rectangle) bounds; } else { rect = bounds.getBounds(); } } else { try { Shape shape = view.modelToView(offs0, Position.Bias.Forward, offs1, Position.Bias.Backward, bounds); rect = (shape instanceof Rectangle) ? (Rectangle) shape : shape.getBounds(); } catch (BadLocationException e) { return null; } } FontMetrics fm = c.getFontMetrics(c.getFont()); int baseline = rect.y + rect.height - fm.getDescent() + 1; g.drawLine(rect.x, baseline, rect.x + rect.width, baseline); g.drawLine(rect.x, baseline + 1, rect.x + rect.width, baseline + 1); return rect; } }