11

算法

  1. 开始
  2. 输入城市名称 - 部分或完整
  3. 如果用户点击 enter ,则从JTextField
  4. 开始蛮力搜索。
  5. 如果找到匹配项,将它们放入 aVector并放入 aJList
  6. 如果未找到匹配项,请在其中添加String“未找到匹配项”Vector
  7. 向用户显示JWindow包含结果
  8. 停止

代码:

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在 a 中JScrollPane)根据结果而变化 - 如果城市名称小,JWindow则小,如果城市名称大,JWindow则大。

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

4

4 回答 4

7

编辑

无论如何,基本上我将不得不手动创建所有要支持的城市的列表,对吗??bx @小孩子

  • 这个想法可能很容易,你可以JTableJWindow

  • 与一个Column

  • 没有JTableHeader

  • 在那里添加RowSorter(参见教程中的代码示例)

  • 然后每个步骤都完成了:-),那里不需要其他任何东西(在没有返回匹配项的情况下,可能会有额外Background的好处,添加弹出窗口(一定要测试))JTextFieldRowFiltersetVisibleDocumentListener!isVisible

于 2013-02-13T08:31:04.230 回答
1

JFrame每次启动搜索时都需要使用宽度,并使用它来计算列表的宽度。

只需像这样更改initialSearch() 函数:

public void initiateSearch(String lookFor){

    //add the following two statements to set the width of the list.
    int newWidth = AutoCompleteTest.this.getSize().width;        
    list.setPreferredSize(new Dimension(newWidth, list.getPreferredSize().height));

        Vector<String> matches = new Vector<String>();
        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();
        }

    }

这是一个示例输出:

小尺寸

在此处输入图像描述

PS:为了更好的美学尝试使用一些布局使文本字段填满整个宽度。

于 2013-02-13T08:32:48.430 回答
1

您应该使用JComboBox,对于自动完成功能,请阅读这篇文章

于 2013-02-13T08:36:14.363 回答
1

一种解决方案是将 initialDisplay() 更改为此:

public void initiateDisplay()
    {
        this.pane.setViewportView(this.searchResult);
        this.add(this.pane);
        this.pack();
        this.setLocation(AutoCompleteTest.this.getX() + 2, AutoCompleteTest.this.getY()
                + AutoCompleteTest.this.getHeight());

        int padding = 5;
        int height = this.searchResult.getModel().getSize()
                * AutoCompleteTest.this.city.getSize().height;
        int windowWidth = AutoCompleteTest.this.getSize().width;

        this.setSize(windowWidth, height);
        this.setVisible(true);
    }
于 2013-02-13T08:42:37.700 回答