如何列出在文本字段内输入时的建议

时间:2011-07-13 05:32:23

标签: java swing autocomplete jtextfield autosuggest

您好,在我的Java swing应用程序中,我需要显示具有相同初始值的所有可能的现有条目 用户在文本字段中键入时的字符。让我们说文本字段中的用户类型字母'A'应该是国家'America'和'Africa'将是建议。这样用户就可以从列表中选择一个。国家/地区列表位于我的数据库中。我知道如何从数据库中检索数据。但我不知道如何列出它们以及我应该使用哪些组件来实现。 任何人都可以指导我吗?或者如果你能提供一个例子,那就太好了。

4 个答案:

答案 0 :(得分:7)

您可以使用autocomplete package from SwingX。如果你需要更多现实生活中的例子,Google可以使用“swingx autocomplete”,但最简单的方法是在其上创建JComboBox并调用 AutoCompleteDecorator.decorate(comboBox);

答案 1 :(得分:4)

您应该尝试将JComboBox作为自动提示框而不是JTextField。但如果您仍然希望使用JTextField完成,那么......

  1. 制作包含建议列表的JPanel。最初它将不可见。
  2. 每当用户键入内容进行搜索并将结果添加到JPanel中的列表时。
  3. 在框架上层的文本字段底部显示JPanel。
  4. 在列表中实施点击事件,以便当用户点击它时,文本将被复制到文本字段。

答案 2 :(得分:3)

there是两个类(你需要正确的功能),自动完成JTextField和自动完成JComboBox,优点是你可以设置if是否严格(如果List不包含则允许输入)或不< / p>

答案 3 :(得分:-1)

我遇到了类似的问题:
我想要一个Textfield免费输入文本,但可以建议现有的值。

我首先发现这篇文章,但是swingX不允许输入除建议文本之外的文本。 然后我发现另一篇链接到此页面的帖子: http://www.jroller.com/santhosh/date/20050620

一些修改,我从目录选择更改为我自己的字符串。可能会在此发布此信息以便完成并为以后的搜索者提供帮助:

他制作了一个抽象的课程AutoCompleter来处理这些事件:

// @author Santhosh Kumar T - santhosh@in.fiorano.com 
public abstract class AutoCompleter{ 
    JList list = new JList(); 
    JPopupMenu popup = new JPopupMenu(); 
    JTextComponent textComp; 
    private static final String AUTOCOMPLETER = "AUTOCOMPLETER"; //NOI18N 

    public AutoCompleter(JTextComponent comp){ 
        textComp = comp; 
        textComp.putClientProperty(AUTOCOMPLETER, this); 
        JScrollPane scroll = new JScrollPane(list); 
        scroll.setBorder(null); 

        list.setFocusable( false ); 
        scroll.getVerticalScrollBar().setFocusable( false ); 
        scroll.getHorizontalScrollBar().setFocusable( false ); 

        popup.setBorder(BorderFactory.createLineBorder(Color.black)); 
        popup.add(scroll); 

        if(textComp instanceof JTextField){ 
            textComp.registerKeyboardAction(showAction, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), JComponent.WHEN_FOCUSED); 
            textComp.getDocument().addDocumentListener(documentListener); 
        }else 
            textComp.registerKeyboardAction(showAction, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), JComponent.WHEN_FOCUSED); 

        textComp.registerKeyboardAction(upAction, KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), JComponent.WHEN_FOCUSED); 
        textComp.registerKeyboardAction(hidePopupAction, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED); 

        popup.addPopupMenuListener(new PopupMenuListener(){ 
            public void popupMenuWillBecomeVisible(PopupMenuEvent e){ 
            } 

            public void popupMenuWillBecomeInvisible(PopupMenuEvent e){ 
                textComp.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 
            } 

            public void popupMenuCanceled(PopupMenuEvent e){ 
            } 
        }); 
        list.setRequestFocusEnabled(false); 
    } 

    static Action acceptAction = new AbstractAction(){ 
        public void actionPerformed(ActionEvent e){ 
            JComponent tf = (JComponent)e.getSource(); 
            AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER); 
            completer.popup.setVisible(false); 
            completer.acceptedListItem((String)completer.list.getSelectedValue()); 
        } 
    }; 

    DocumentListener documentListener = new DocumentListener(){ 
        public void insertUpdate(DocumentEvent e){ 
            showPopup(); 
        } 

        public void removeUpdate(DocumentEvent e){ 
            showPopup(); 
        } 

        public void changedUpdate(DocumentEvent e){} 
    }; 

    private void showPopup(){ 
        popup.setVisible(false); 
        if(textComp.isEnabled() && updateListData() && list.getModel().getSize()!=0){ 
            if(!(textComp instanceof JTextField)) 
                textComp.getDocument().addDocumentListener(documentListener); 
            textComp.registerKeyboardAction(acceptAction, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); 
            int size = list.getModel().getSize(); 
            list.setVisibleRowCount(size<10 ? size : 10); 

            int x = 0; 
            try{ 
                int pos = Math.min(textComp.getCaret().getDot(), textComp.getCaret().getMark()); 
                x = textComp.getUI().modelToView(textComp, pos).x; 
            } catch(BadLocationException e){ 
                // this should never happen!!! 
                e.printStackTrace(); 
            } 
            popup.show(textComp, x, textComp.getHeight()); 
        }else 
            popup.setVisible(false); 
        textComp.requestFocus(); 
    } 

    static Action showAction = new AbstractAction(){ 
        public void actionPerformed(ActionEvent e){ 
            JComponent tf = (JComponent)e.getSource(); 
            AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER); 
            if(tf.isEnabled()){ 
                if(completer.popup.isVisible()) 
                    completer.selectNextPossibleValue(); 
                else 
                    completer.showPopup(); 
            } 
        } 
    }; 

    static Action upAction = new AbstractAction(){ 
        public void actionPerformed(ActionEvent e){ 
            JComponent tf = (JComponent)e.getSource(); 
            AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER); 
            if(tf.isEnabled()){ 
                if(completer.popup.isVisible()) 
                    completer.selectPreviousPossibleValue(); 
            } 
        } 
    }; 

    static Action hidePopupAction = new AbstractAction(){ 
        public void actionPerformed(ActionEvent e){ 
            JComponent tf = (JComponent)e.getSource(); 
            AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER); 
            if(tf.isEnabled()) 
                completer.popup.setVisible(false); 
        } 
    }; 

    /** 
     * Selects the next item in the list.  It won't change the selection if the 
     * currently selected item is already the last item. 
     */ 
    protected void selectNextPossibleValue(){ 
        int si = list.getSelectedIndex(); 

        if(si < list.getModel().getSize() - 1){ 
            list.setSelectedIndex(si + 1); 
            list.ensureIndexIsVisible(si + 1); 
        } 
    } 

    /** 
     * Selects the previous item in the list.  It won't change the selection if the 
     * currently selected item is already the first item. 
     */ 
    protected void selectPreviousPossibleValue(){ 
        int si = list.getSelectedIndex(); 

        if(si > 0){ 
            list.setSelectedIndex(si - 1); 
            list.ensureIndexIsVisible(si - 1); 
        } 
    } 

    // update list model depending on the data in textfield 
    protected abstract boolean updateListData(); 

    // user has selected some item in the list. update textfield accordingly... 
    protected abstract void acceptedListItem(String selected); 
}

一个处理PopUp内容的实例:

// @author Santhosh Kumar T - santhosh@in.fiorano.com 
public class FileAutoCompleter extends AutoCompleter{ 
    public FileAutoCompleter(JTextComponent comp){ 
        super(comp); 
    } 

    protected boolean updateListData(){ 
        String value = textComp.getText(); 
        int index1 = value.lastIndexOf('\\'); 
        int index2 = value.lastIndexOf('/'); 
        int index = Math.max(index1, index2); 
        if(index==-1) 
            return false; 
        String dir = value.substring(0, index+1); 
        final String prefix = index==value.length()-1 ? null : value.substring(index + 1).toLowerCase(); 
        String[] files = new File(dir).list(new FilenameFilter(){ 
            public boolean accept(File dir, String name){ 
                return prefix!=null ? name.toLowerCase().startsWith(prefix) : true; 
            } 
        }); 
        if(files == null){ 
            list.setListData(new String[0]); 
            return true; 
        } else{ 
            if(files.length==1 && files[0].equalsIgnoreCase(prefix)) 
                list.setListData(new String[0]); 
            else 
                list.setListData(files); 
            return true; 
        } 
    } 

    protected void acceptedListItem(String selected){ 
        if(selected==null) 
            return; 

        String value = textComp.getText(); 
        int index1 = value.lastIndexOf('\\'); 
        int index2 = value.lastIndexOf('/'); 
        int index = Math.max(index1, index2); 
        if(index==-1) 
            return; 
        int prefixlen = textComp.getDocument().getLength()-index-1; 
        try{ 
            textComp.getDocument().insertString(textComp.getCaretPosition(), selected.substring(prefixlen), null); 
        } catch(BadLocationException e){ 
            e.printStackTrace(); 
        } 
    } 
}

使用

在程序中调用所有内容
new FileAutoCompleter(yourJTextField);