我有一个 JTextFields 的自动完成功能,到目前为止似乎可以工作,但是出现了一个特定的子案例,如下所示:尝试插入“em”,而不是“emanuele semani”自动完成,你会得到“eanuemeli li”,它甚至不存在列表(仅包含两项的列表:
- 伊曼纽尔·塞马尼
- 曼纽梅里
)
我知道这些名字很奇怪,但是有两本书有这些名字..
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.text.Document;
import AutoCompleteDocument;
import CompletionService;
public class AutoCompleteExample
{
TitleService titleService;
Document titleAutoCompleteDocument;
JTextField titleField;
private class TitleService extends CompletionService
{
public TitleService()
{
ArrayList<String> eventTitles = getBookTitles();
for (int i = 0; eventTitles != null && i < eventTitles.size(); i++)
{
if (eventTitles.get(i) != null)
{
data.add(eventTitles.get(i));
}
}
}
}
public AutoCompleteExample()
{
JPanel panel = new JPanel();
titleField = new JTextField();
titleField.setColumns(50);
panel.add(titleField);
titleService = new TitleService();
titleAutoCompleteDocument = new AutoCompleteDocument(titleService,
titleField);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setSize(700, 100);
frame.setVisible(true);
refreshCompletionServices();
}
public void refreshCompletionServices()
{
titleService = new TitleService();
titleAutoCompleteDocument = new AutoCompleteDocument(titleService,
titleField);
titleField.setDocument(titleAutoCompleteDocument);
}
private ArrayList<String> getBookTitles()
{
ArrayList<String> titles = new ArrayList<>();
titles.add("emanule semani");
titles.add("manuemeli li");
return titles;
}
public static void main(String args[])
{
AutoCompleteExample ex = new AutoCompleteExample();
}
}
和 CompletionService.java 类是
import java.util.ArrayList;
import java.util.List;
public class CompletionService
{
public List<String> data = new ArrayList<>();
String autoComplete(String partialString)
{
String hit = null;
for (String o : data)
{
if (o.toLowerCase().contains(partialString.toLowerCase()))
{
// CompletionService contract states that we only
// should return completion for unique hits.
if (hit == null)
{
int index = o.toLowerCase().indexOf(partialString.toLowerCase());
hit = o.substring(index);
}
else
{
if (hit.length() > o.length())
{
hit = o;
}
}
}
}
return hit;
}
}
和 AUtoCompleteDocument.java 是
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;
public class AutoCompleteDocument extends PlainDocument
{
private static final long serialVersionUID = 1L;
private CompletionService completionService;
private JTextComponent documentOwner;
public AutoCompleteDocument(CompletionService service,
JTextComponent documentOwner)
{
this.completionService = service;
this.documentOwner = documentOwner;
}
protected String complete(String str)
{
Object o = completionService.autoComplete(str);
return o == null ? null : o.toString();
}
@Override
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException
{
if (str == null || str.length() == 0)
{
return;
}
String text = getText(0, offs); // Current text.
String completion = complete(text + str);
int length = offs + str.length();
if (completion != null && text.length() > 0)
{
str = completion.substring(length - 1);
super.insertString(offs, str, a);
documentOwner.select(length, getLength());
}
else
{
super.insertString(offs, str, a);
}
}
}