Java中的多个单词突出显示

时间:2014-12-14 14:31:18

标签: java highlight

我试图创建一个单词搜索引擎,通过通配符搜索找到单词,并突出显示它找到的所有单词。我已经进行了搜索,但是荧光笔只会突出显示它找到的第一个单词。假设我搜索' * hat',''的所有实例'突出显示,但它没有突出显示任何其他单词,例如' what' (即使它们返回到找到的控制台)。

这是我的荧光笔代码,模式匹配器返回的字符串传递给此方法:

public static void highlighter(String s){
    String text = displayString.getText();
    highlightStr = new DefaultHighlighter();
    painter = new DefaultHighlighter.DefaultHighlightPainter(Color.pink);
    displayString.setHighlighter(highlightStr); 
    //highlightStr.removeAllHighlights();

    for(int index = 0; index < text.length(); index++){        
        int start = text.indexOf(s, index);

        try{
            int end = start + s.length();
            highlightStr.addHighlight(start, end, painter);
            displayString.setCaretPosition(end);
        }catch(BadLocationException e){} 
    }
}

为了确保字符串全部传递给荧光笔我从方法中打印出来。

1 个答案:

答案 0 :(得分:1)

这个解决方案花了我一些尝试,但现在它的工作原理。它似乎做你想要的,代码对我来说非常简单(至少我现在读的时候)。

我使用正则表达式进行文本匹配(类PatternMatcher),因为它们使代码非常简单。因此,首先需要通过compileWildcard方法将通配符模式转换为正则表达式。

package so27470328;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.DefaultHighlighter.DefaultHighlightPainter;
import javax.swing.text.Highlighter;
import javax.swing.text.Highlighter.HighlightPainter;

public class Main {

  public static void main(String[] args) {
    final JTextArea textarea = new JTextArea(25, 80);
    textarea.setText("I'm trying to make a word search engine ... method.");
    Highlighter highlighter = new DefaultHighlighter();
    final DefaultHighlightPainter painter = new DefaultHighlightPainter(Color.pink);
    textarea.setHighlighter(highlighter);

    final JTextField highlight = new JTextField(80);
    highlight.getDocument().addDocumentListener(new DocumentListener() {

      private void updateHighlights() {
        highlight(textarea, highlight.getText(), painter);
      }

      @Override
      public void removeUpdate(DocumentEvent e) {
        updateHighlights();
      }

      @Override
      public void insertUpdate(DocumentEvent e) {
        updateHighlights();
      }

      @Override
      public void changedUpdate(DocumentEvent e) {
        updateHighlights();
      }
    });

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setLayout(new BorderLayout());
    frame.add(highlight, BorderLayout.NORTH);
    frame.add(textarea, BorderLayout.CENTER);
    frame.setPreferredSize(new Dimension(600, 400));
    frame.pack();
    frame.setVisible(true);
  }

  public static void highlight(JTextArea textarea, String textToHighlight,
      HighlightPainter painter) {
    String text = textarea.getText();
    Highlighter highlighter = textarea.getHighlighter();
    highlighter.removeAllHighlights();

    if (!textToHighlight.isEmpty()) {
      Matcher m = compileWildcard(textToHighlight).matcher(text);
      while (m.find()) {
        try {
          highlighter.addHighlight(m.start(), m.end(), painter);
        } catch (BadLocationException e) {
          throw new IllegalStateException(e); /* cannot happen */
        }
        textarea.setCaretPosition(m.end());
      }
    }
  }

  public static Pattern compileWildcard(String wildcard) {
    StringBuilder sb = new StringBuilder("\\b"); /* word boundary */
    /* the following replaceAll is just for performance */
    for (char c : wildcard.replaceAll("\\*+", "*").toCharArray()) {
      if (c == '*') {
        sb.append("\\S*"); /*- arbitrary non-space characters */
      } else {
        sb.append(Pattern.quote(String.valueOf(c)));
      }
    }
    sb.append("\\b"); /* word boundary */
    return Pattern.compile(sb.toString());
  }

}