Java Swing How to - Highlight word with timer for JTextArea








Question

We would like to know how to highlight word with timer for JTextArea.

Answer

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
//from w  ww  . ja va 2  s  .  c  o  m
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
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;

public class Main {

  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout());
    frame.add(new TestPane());
    frame.pack();
    frame.setVisible(true);
  }

}

class TestPane extends JPanel {
  JTextField findText = new JTextField(20);
  JTextArea ta = new JTextArea(20, 40);
  Timer keyTimer;

  public TestPane() {
    setLayout(new BorderLayout());
    JPanel searchPane = new JPanel();
    searchPane.add(new JLabel("Find: "));

    searchPane.add(findText);

    add(searchPane, BorderLayout.NORTH);
    add(new JScrollPane(ta));

    try (BufferedReader reader = new BufferedReader(new FileReader(new File(
        "c:/Java_Dev/run.bat")))) {
      ta.read(reader, "Text");
    } catch (Exception e) {
      e.printStackTrace();
    }
    ta.setCaretPosition(0);

    keyTimer = new Timer(250, new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        String find = findText.getText();
        Document document = ta.getDocument();
        try {
          for (int index = 0; index + find.length() < document.getLength(); index++) {
            String match = document.getText(index, find.length());
            if (find.equals(match)) {
              DefaultHighlighter.DefaultHighlightPainter highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(
                  Color.YELLOW);
              ta.getHighlighter().addHighlight(index, index + find.length(),
                  highlightPainter);
            }
          }
        } catch (BadLocationException exp) {
          exp.printStackTrace();
        }
      }
    });
    keyTimer.setRepeats(false);

    findText.getDocument().addDocumentListener(new DocumentListener() {
      @Override
      public void insertUpdate(DocumentEvent e) {
        keyTimer.restart();
      }

      @Override
      public void removeUpdate(DocumentEvent e) {
        keyTimer.restart();
      }

      @Override
      public void changedUpdate(DocumentEvent e) {
        keyTimer.restart();
      }
    });
  }
}