JTextField特例的怪异java自动完成

JTextField特例的怪异java自动完成,java,swing,autocomplete,jtextfield,Java,Swing,Autocomplete,Jtextfield,我有一个JTextFields的自动补全功能,到目前为止似乎是可行的,但是出现了一个特定的子类,如下所示:尝试插入“em”,而不是“emanuele semani”自动补全,您得到的是“eanuemeli li”,它甚至不存在于列表中(列表仅包含两项: 伊曼纽尔·塞马尼 李曼努埃梅利 ) 我知道这些名字很奇怪,但是有两本书有这些名字 import java.util.ArrayList; import javax.swing.*; import javax.swing.text.Document

我有一个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();
        }
    }
    

    我的答案是关于
    为什么要重新发明轮子
    ,使用

    您应该更换

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


    自动完成JComboBox/JTextField链接有自己的bug(在初始完成后,我无法删除并启动一个新的链接),当我使用标准JTextFields时,它需要一个专门的JTextField。decorator需要一个完整的库来做一件非常简单的事情..退格和选择都没有问题(在这两种情况下)我发布这个答案的原因,可能还有另一个问题,你在使用数组之前对数组进行了排序吗没有我没有对数组进行排序。。无论如何,我的自动完成是内联完成,而示例是标准完成,这对我来说是不够的:(
    plarz.net.planig
    是第三方API吗?您可能想看看。没有第三方API..我修复了代码..请删除注释;)有大量的Jide是开源的,在GPL下我想要内联自动完成。。非行开始自动补全:(抱歉,我本应指定..无法理解您关于行内自动补全的观点。您能解释一下吗。我的示例搜索字符串中的任何匹配项,并完成剩余部分,如果我使用startsWith,我只能搜索以该词开始的匹配项..如果我想搜索“哈利·波特”,但我只记得我的例子中的“波特”,而startsWith则要求我写“哈尔”。。。
    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);
            }
        }
    }
    
    if (o.toLowerCase().contains(partialString.toLowerCase()))
    
    if (o.toLowerCase().startsWith(partialString.toLowerCase()))