2014-12-14 8 views
1

와일드 카드 검색을 사용하여 단어를 찾고 해당 단어를 모두 강조 표시하는 단어 검색 엔진을 만들고자합니다. 검색을 진행할 수 있지만 하이 라이터는 찾은 첫 단어 만 강조 표시합니다. '* 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){} 
    } 
} 

하는 문자열이 모두 내가 그들을 인쇄 한 하이 라이터로 전달되고 있는지 확인하려면 다음은

는 하이 라이터 내 코드, 패턴 매처에 의해 반환되는 문자열이 메서드에 전달되는 것입니다 방법.

+0

시작 색인이 현재 반복 횟수를 초과 할 경우이 단어는 반복해서 강조 표시됩니다. 그것이 문제가 될지 고려하십시오. 나는 for-loop를'text.indexOf()'가'-1'을 반환하지 않는다는 조건에서 while-loop로 바꿀 것을 제안합니다. – initramfs

답변

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()); 
    } 

} 
관련 문제