0

我有一个 JTextFields 的自动完成功能,到目前为止似乎可以工作,但是出现了一个特定的子案例,如下所示:尝试插入“em”,而不是“emanuele semani”自动完成,你会得到“eanuemeli li”,它甚至不存在列表(仅包含两项的列表:

  1. 伊曼纽尔·塞马尼
  2. 曼纽梅里

)

我知道这些名字很奇怪,但是有两本书有这些名字..

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

2 回答 2

1

我的回答是关于Why to reinvent the wheel,使用

于 2013-03-25T14:31:39.513 回答
1

你应该更换

if (o.toLowerCase().contains(partialString.toLowerCase()))

if (o.toLowerCase().startsWith(partialString.toLowerCase()))
于 2013-03-25T14:53:32.947 回答