All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsoar.debugger.util.IncrementalSearch Maven / Gradle / Ivy

/*
 * Copyright (c) 2009 Dave Ray 
 *
 * Created on Jul 17, 2009
 */
package org.jsoar.debugger.util;

import com.google.re2j.Matcher;
import com.google.re2j.Pattern;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;

public class IncrementalSearch implements DocumentListener, ActionListener
{
    protected JEditorPane content;

    protected Matcher matcher;

    private boolean useRegex = false;
    private boolean matchCase = false;
    private ArrayList matches = new ArrayList<>();
    private int currentMatch = -1;
    private Color highlightColor = Color.DARK_GRAY;


    public IncrementalSearch(JTextComponent comp)
    {
        this.content = (JEditorPane) comp;
    }

    /* DocumentListener implementation */
    public void insertUpdate(DocumentEvent evt)
    {
        Document query_doc = evt.getDocument();
        try {
            runNewSearch(query_doc.getText(0, query_doc.getLength()));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    public void removeUpdate(DocumentEvent evt)
    {
        Document query_doc = evt.getDocument();
        try {
            runNewSearch(query_doc.getText(0, query_doc.getLength()));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    public void changedUpdate(DocumentEvent evt)
    {
        Document query_doc = evt.getDocument();
        try {
            runNewSearch(query_doc.getText(0, query_doc.getLength()));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    /* ActionListener implementation */
    public void actionPerformed(ActionEvent evt)
    {
        continueSearch();
    }

    public void runNewSearch(String query)
    {
        try {

            if (query.length() > 0) {
                matches.clear();
                currentMatch = -1;

                final Document content_doc = content.getDocument();
                String body = content_doc.getText(0, content_doc.getLength());
                if (useRegex) {
                    final Pattern pattern = Pattern.compile(query);
                    matcher = pattern.matcher(body);
                    findAllMatches();
                } else {
                    matcher = null;
                    if (!matchCase) {
                        body = body.toLowerCase();
                        query = query.toLowerCase();
                    }
                    findAllStringMatches(query, body);
                }
                continueSearch();
            } else {
                onNoMatch();
                matcher = null;
            }
        } catch (BadLocationException e) {
            onError();
        }
    }
    
    protected void removeTextHighlights()
    {
        content.getHighlighter().removeAllHighlights();
    }

    private void findAllStringMatches(String query, String body)
    {
        Highlighter h = content.getHighlighter();

        LayeredHighlighter.LayerPainter painter = new DefaultHighlighter.DefaultHighlightPainter(highlightColor.brighter());
        h.removeAllHighlights();

        int i = 0;
        while (i < body.length() + query.length()) {
            int start = body.indexOf(query, i);
            int end = start + query.length();
            if (start < 0 || end > body.length()) {
                break;
            }
            try {
                Object highlight = h.addHighlight(start, end, painter);
                matches.add(new Match(start,end,highlight));
                i = end;
            } catch (BadLocationException e) {
                e.printStackTrace();
                break;
            }
        }
    }

    private void findAllMatches()
    {

        if (matcher != null) {

            Highlighter h = content.getHighlighter();
            LayeredHighlighter.LayerPainter painter = new DefaultHighlighter.DefaultHighlightPainter(highlightColor.brighter());
            h.removeAllHighlights();
            while (matcher.find()) {
                try {
                    Object highlight = h.addHighlight(matcher.start(), matcher.end(), painter);
                    matches.add(new Match(matcher.start(), matcher.end(), highlight));
                } catch (BadLocationException e) {
                    e.printStackTrace();
                }
            }
        } else {
            onError();
        }
    }

    protected void onError()
    {
    }

    protected void onNoMatch()
    {
    }

    protected void onMatch(int match, int total)
    {
    }

    protected void continueSearch()
    {
        if (!matches.isEmpty()) {
            resetHighlight();

            currentMatch++;
            if (currentMatch >= matches.size()) {
                currentMatch = 0;
            }
            handleMatch();
        } else {
            onNoMatch();
        }
    }
    public void findPrev()
    {
        if (!matches.isEmpty()) {
            resetHighlight();
            currentMatch--;
            if (currentMatch < 0) {
                currentMatch = matches.size() - 1;
            }
            handleMatch();
        } else {
            onNoMatch();
        }
    }


    private void handleMatch()
    {
        Match match = matches.get(currentMatch);
        content.getCaret().setDot(match.start);
        content.getCaret().moveDot(match.end);
        content.getCaret().setSelectionVisible(true);
        Highlighter h = content.getHighlighter();
        LayeredHighlighter.LayerPainter painter = new DefaultHighlighter.DefaultHighlightPainter(highlightColor);
        try {
            h.removeHighlight(match.highlight);
            match.highlight = h.addHighlight(match.start, match.end, painter);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        onMatch(currentMatch, matches.size());
    }


    private void resetHighlight()
    {
        if (currentMatch >= 0 && currentMatch < matches.size()) {
            Match match = matches.get(currentMatch);
            Highlighter h = content.getHighlighter();
            LayeredHighlighter.LayerPainter painter = new DefaultHighlighter.DefaultHighlightPainter(highlightColor.brighter());
            try {
                h.removeHighlight(match.highlight);
                match.highlight = h.addHighlight(match.start, match.end, painter);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
        }
    }

    public void setMatchCase(boolean selected)
    {
        matchCase = selected;
    }

    public void setUseRegex(boolean selected)
    {
        useRegex = selected;
    }

    public void setHighlightColor(Color color)
    {
        highlightColor = color;
    }

    private class Match
    {
        public Object highlight;
        int start;
        int end;

        public Match(int start, int end, Object highlight)
        {
            this.start = start;
            this.end = end;
            this.highlight = highlight;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy