我试图创建一个单词搜索引擎,通过通配符搜索找到单词,并突出显示它找到的所有单词。我已经进行了搜索,但是荧光笔只会突出显示它找到的第一个单词。假设我搜索' * 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 :(得分:1)
这个解决方案花了我一些尝试,但现在它的工作原理。它似乎做你想要的,代码对我来说非常简单(至少我现在读的时候)。
我使用正则表达式进行文本匹配(类Pattern
和Matcher
),因为它们使代码非常简单。因此,首先需要通过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());
}
}