Reputation: 3952
I have an autocompletion of JTextFields which so far seemed to work, however a specific subcase has appeared which is shown below: try inserting "em" and instead of "emanuele semani" autocompletion you get "eanuemeli li" which doesn't even exist in the list (the list containing only two items:
)
I know the names are weird however two books had these names..
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();
}
}
and CompletionService.java class is
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;
}
}
and the AUtoCompleteDocument.java is
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);
}
}
}
Upvotes: 0
Views: 760
Reputation: 13066
You should replace
if (o.toLowerCase().contains(partialString.toLowerCase()))
to
if (o.toLowerCase().startsWith(partialString.toLowerCase()))
Upvotes: 1