This question already has answers here:
Create a autocompleting textbox in Java with a dropdown list

(7个答案)


已关闭8年。




算法
  • 开始
  • 输入城市名称-一部分或完整的
  • 如果用户按下Enter键,则从JTextField的文本中提取
  • 开始蛮力搜索。
  • 如果找到匹配项,则将它们放入Vector中,然后将其放入JList
  • 如果找不到匹配项,请在String中添加一个Vector“找不到匹配项”
  • 向包含结果
  • 的用户显示JWindow
  • 停止

  • 代码:
    package test;
    import javax.swing.*;
    
    import java.awt.Dimension;
    import java.awt.event.*;
    import java.util.Vector;
    
    public class AutoCompleteTest extends JFrame{
        JTextField city = new JTextField(10);
        String enteredName = null;
        String[] cities = {"new jersey","new hampshire",
                "sussex","essex","london","delhi","new york"};
        JList list = new JList();
        JScrollPane pane = new JScrollPane();
        ResultWindow r = new ResultWindow();
    //------------------------------------------------------------------------------
        public static void main(String[] args) {
            new AutoCompleteTest();
        }
    //------------------------------------------------------------------------------
        public AutoCompleteTest(){
            setLayout(new java.awt.FlowLayout());
            setVisible(true);
            add(city);
    //      add(pane);
            pack();
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            city.addKeyListener(new TextHandler());
        }
    //------------------------------------------------------------------------------
        public void initiateSearch(String lookFor){
            Vector<String> matches = new Vector<>();
            lookFor = lookFor.toLowerCase();
            for(String each : cities){
                if(each.contains(lookFor)){
                    matches.add(each);
                    System.out.println("Match: " + each);
                }
            }
            this.repaint();
    
            if(matches.size()!=0){
                list.setListData(matches);
                r.searchResult = list;
                r.pane = pane;
                r.initiateDisplay();
            }else{
                matches.add("No Match Found");
                list.setListData(matches);
                r.searchResult = list;
                r.pane = pane;
                r.initiateDisplay();
            }
    
        }
    //------------------------------------------------------------------------------
        public class ResultWindow extends JWindow{
            public JScrollPane pane;
            public JList searchResult;
    //------------------------------------------------------------------------------
            public ResultWindow(){
    
            }
    //------------------------------------------------------------------------------
            public void initiateDisplay(){
                pane.setViewportView(searchResult);
                add(pane);
                pack();
                this.setLocation(AutoCompleteTest.this.getX() + 2,
                        AutoCompleteTest.this.getY()+
                        AutoCompleteTest.this.getHeight());
    
    //          this.setPreferredSize(city.getPreferredSize());
                this.setVisible(true);
            }
        }
    //------------------------------------------------------------------------------
    
        class TextHandler implements KeyListener{
            @Override
            public void keyTyped(KeyEvent e){
    
            }
    
            @Override
            public void keyPressed(KeyEvent e){
                if(r.isVisible()){
                    r.setVisible(false);
                }
                if(e.getKeyChar() == '\n'){
                    initiateSearch(city.getText());
                }
            }
    
            @Override
            public void keyReleased(KeyEvent e){
    
            }
        }
    //------------------------------------------------------------------------------
    }
    

    输出

    问题

    显示结果的JWindow的大小(在JList中为JScrollPane)会根据结果而变化-如果城市名小,则JWindow小,如果城市名大,则JWindow大。

    我尝试了所有可能的组合。我尝试使用setPreferredDimension()JWindowJListJScrollPane,但问题不会解决。
    我希望它与装饰的JFrame的大小匹配,无论如何

    最佳答案

  • JListJComboBox不返回正确的PreferredSize,必须设置此值,将JList.setPrototypeCellValue()pack()一起使用JWindow(必须在任何更改后打包),或者与JList.setVisibleRowCount()一起使用,然后值将getPreferredScrollableViewportSize()中的JList返回JScrollPaneKeyListener
  • 不要使用 DocumentListener ,而将 JTextComponents (可以从系统剪贴板插入字符)用于 JWindow
  • 不要重新发明轮子,使用AutoComplete JComboBox / JTextField,您可以将匹配结果重定向/返回到弹出式 JDialog / undecorated JTable (quite the best workaround for popup recycle)

  • 编辑


  • 这个想法可能很容易,您可以将 JWindow to the Column
  • 放进去
    带有一个JTableHeader
  • 没有Background
  • 在那里添加RowSorter(请参阅教程中的代码示例)
  • 然后完成每个步骤:-),在此不需要任何其他操作(在JTextField不返回任何匹配项的情况下,也许可以更改RowFiltersetVisible的额外好处,可以从DocumentListener中为弹出窗口添加!isVisible(一定要测试ojit_code))
  • 关于java - 在Java中实现自动完成-我做对了吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14849176/

    10-12 18:48