使用下拉列表在Java中创建自动完成文本框

使用下拉列表在Java中创建自动完成文本框,java,swing,autocomplete,autosuggest,Java,Swing,Autocomplete,Autosuggest,我想创建一个自动建议文本框,在每次密钥释放事件时查询数据库。 这部分很简单,但我想给它一个很好的视觉效果。类似于我们在Facebook搜索等网站上看到的自动建议文本框 如何制作这样的界面 一个天真的想法是将一个JList放在文本框的正下方,并在找到一个JList时将其设置为可见,并在其中显示结果 有没有更好的方法或标准方法呢?一个非常简单的方法是使用GlazedList实现自动完成。站起来跑步很容易。你可以找到它 只需一行代码,即可在JComboBox上安装auto complete,如下所示:

我想创建一个自动建议文本框,在每次密钥释放事件时查询数据库。 这部分很简单,但我想给它一个很好的视觉效果。类似于我们在Facebook搜索等网站上看到的自动建议文本框

如何制作这样的界面

一个天真的想法是将一个JList放在文本框的正下方,并在找到一个JList时将其设置为可见,并在其中显示结果


有没有更好的方法或标准方法呢?

一个非常简单的方法是使用
GlazedList
实现自动完成。站起来跑步很容易。你可以找到它

只需一行代码,即可在JComboBox上安装auto complete,如下所示:

JComboBox comboBox = new JComboBox();
Object[] elements = new Object[] {"Cat", "Dog", "Lion", "Mouse"};
AutoCompleteSupport.install(comboBox, GlazedLists.eventListOf(elements));

而且
SwingX
支持自动完成,可能比
GlazedList
更易于使用。使用
SwingX
编写的所有代码都是
AutoCompleteDecorator.decoration(组合框)

@syb0rg的答案更简单,因为它使用了第三方库

但是,我使用了另一种方法:

它使用一个名为
autosuggester
的自定义类,该类接受
JTextField
、它的
窗口
和一个
数组列表
,以检查键入的单词、背景颜色和文本颜色、建议焦点颜色以及不透明度值。通过传递
JTextField
reference,添加了一个
DocumentListener
,它将检查键入的单词,是否显示建议,如果是,显示什么建议。当键入一个单词时,
DocumentListener
将在
wordTyped(..)中使用当前键入的单词或(至少键入了多少单词)激发
wordTyped(String wordTyped)
方法
将对照
AutoSuggester
s classes字典中的单词进行检查,该字典是
字符串的基本
数组列表
,可以动态设置,如下例所示:

(目前,您必须使用鼠标单击要自动完成的单词,或者使用向下键遍历时使用向下键和文本字段并输入以选择建议。我尚未实现):

导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.GridLayout;
导入java.awt.Window;
导入java.awt.event.ActionEvent;
导入java.awt.event.KeyEvent;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.util.ArrayList;
导入javax.swing.AbstractAction;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
导入javax.swing.JWindow;
导入javax.swing.KeyStroke;
导入javax.swing.SwingUtilities;
导入javax.swing.border.LineBorder;
导入javax.swing.event.DocumentEvent;
导入javax.swing.event.DocumentListener;
/**
*@作者大卫
*/
公开课考试{
公开考试(){
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField=新的JTextField(10);
AutoSuggester AutoSuggester=新的AutoSuggester(f,帧,null,Color.WHITE.brighter(),Color.BLUE,Color.RED,0.75f){
@凌驾
布尔字类型(字符串类型DWORD){
//为字典创建列表在您的情况下,可以通过调用查询db并以arraylist形式返回结果的方法来完成此操作
ArrayList words=新的ArrayList();
添加(“你好”);
文字。添加(“遗产”);
加上(“幸福”);
添加(“再见”);
词语。添加(“残忍”);
词语。添加(“car”);
词语。添加(“战争”);
文字。添加(“遗嘱”);
字。加上(“世界”);
文字。添加(“墙”);
词典(单词);
//addToDictionary(“bye”);//添加单个单词
return super.wordTyped(typedWord);//现在调用super检查是否与最新字典匹配
}
};
JPanel p=新的JPanel();
p、 添加(f);
框架。添加(p);
frame.pack();
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新测试();
}
});
}
}
类自动建议器{
私有最终JTextField textField;
专用最终窗口容器;
私人JPanel建议小组;
私有JWindow自动建议弹出窗口;
私有字符串类型字;
私有最终ArrayList字典=新ArrayList();
私人int currentIndexOfSpace,tW,tH;
私有DocumentListener DocumentListener=新DocumentListener(){
@凌驾
公共作废插入更新(DocumentEvent de){
检查并显示建议();
}
@凌驾
公共作废移除更新(DocumentEvent de){
检查并显示建议();
}
@凌驾
公共作废更改日期(DocumentEvent de){
检查并显示建议();
}
};
私人最终颜色建议文本颜色;
私人最终颜色建议聚焦颜色;
公共自动建议器(JTextField textField,Window Main Window,ArrayList单词,彩色popUpBackground,彩色textColor,彩色建议FocusedColor,浮点不透明度){
this.textField=textField;
this.suggestionTextColor=textColor;
this.container=main窗口;
this.suggestionFocusedColor=suggestionFocusedColor;
this.textField.getDocument().addDocumentListener(documentListener);
词典(单词);
typedWord=“”;
currentIndexOfSpace=0;
tW=0;
tH=0;
自动提示弹出窗口
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * @author David
 */
public class Test {

    public Test() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        JTextField f = new JTextField(10);

        AutoSuggestor autoSuggestor = new AutoSuggestor(f, frame, null, Color.WHITE.brighter(), Color.BLUE, Color.RED, 0.75f) {
            @Override
            boolean wordTyped(String typedWord) {

                //create list for dictionary this in your case might be done via calling a method which queries db and returns results as arraylist
                ArrayList<String> words = new ArrayList<>();
                words.add("hello");
                words.add("heritage");
                words.add("happiness");
                words.add("goodbye");
                words.add("cruel");
                words.add("car");
                words.add("war");
                words.add("will");
                words.add("world");
                words.add("wall");


                setDictionary(words);
                //addToDictionary("bye");//adds a single word

                return super.wordTyped(typedWord);//now call super to check for any matches against newest dictionary
            }
        };

        JPanel p = new JPanel();

        p.add(f);

        frame.add(p);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }
}

class AutoSuggestor {

    private final JTextField textField;
    private final Window container;
    private JPanel suggestionsPanel;
    private JWindow autoSuggestionPopUpWindow;
    private String typedWord;
    private final ArrayList<String> dictionary = new ArrayList<>();
    private int currentIndexOfSpace, tW, tH;
    private DocumentListener documentListener = new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent de) {
            checkForAndShowSuggestions();
        }

        @Override
        public void removeUpdate(DocumentEvent de) {
            checkForAndShowSuggestions();
        }

        @Override
        public void changedUpdate(DocumentEvent de) {
            checkForAndShowSuggestions();
        }
    };
    private final Color suggestionsTextColor;
    private final Color suggestionFocusedColor;

    public AutoSuggestor(JTextField textField, Window mainWindow, ArrayList<String> words, Color popUpBackground, Color textColor, Color suggestionFocusedColor, float opacity) {
        this.textField = textField;
        this.suggestionsTextColor = textColor;
        this.container = mainWindow;
        this.suggestionFocusedColor = suggestionFocusedColor;
        this.textField.getDocument().addDocumentListener(documentListener);

        setDictionary(words);

        typedWord = "";
        currentIndexOfSpace = 0;
        tW = 0;
        tH = 0;

        autoSuggestionPopUpWindow = new JWindow(mainWindow);
        autoSuggestionPopUpWindow.setOpacity(opacity);

        suggestionsPanel = new JPanel();
        suggestionsPanel.setLayout(new GridLayout(0, 1));
        suggestionsPanel.setBackground(popUpBackground);

        addKeyBindingToRequestFocusInPopUpWindow();
    }

    private void addKeyBindingToRequestFocusInPopUpWindow() {
        textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released");
        textField.getActionMap().put("Down released", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {//focuses the first label on popwindow
                for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) {
                    if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) {
                        ((SuggestionLabel) suggestionsPanel.getComponent(i)).setFocused(true);
                        autoSuggestionPopUpWindow.toFront();
                        autoSuggestionPopUpWindow.requestFocusInWindow();
                        suggestionsPanel.requestFocusInWindow();
                        suggestionsPanel.getComponent(i).requestFocusInWindow();
                        break;
                    }
                }
            }
        });
        suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released");
        suggestionsPanel.getActionMap().put("Down released", new AbstractAction() {
            int lastFocusableIndex = 0;

            @Override
            public void actionPerformed(ActionEvent ae) {//allows scrolling of labels in pop window (I know very hacky for now :))

                ArrayList<SuggestionLabel> sls = getAddedSuggestionLabels();
                int max = sls.size();

                if (max > 1) {//more than 1 suggestion
                    for (int i = 0; i < max; i++) {
                        SuggestionLabel sl = sls.get(i);
                        if (sl.isFocused()) {
                            if (lastFocusableIndex == max - 1) {
                                lastFocusableIndex = 0;
                                sl.setFocused(false);
                                autoSuggestionPopUpWindow.setVisible(false);
                                setFocusToTextField();
                                checkForAndShowSuggestions();//fire method as if document listener change occured and fired it

                            } else {
                                sl.setFocused(false);
                                lastFocusableIndex = i;
                            }
                        } else if (lastFocusableIndex <= i) {
                            if (i < max) {
                                sl.setFocused(true);
                                autoSuggestionPopUpWindow.toFront();
                                autoSuggestionPopUpWindow.requestFocusInWindow();
                                suggestionsPanel.requestFocusInWindow();
                                suggestionsPanel.getComponent(i).requestFocusInWindow();
                                lastFocusableIndex = i;
                                break;
                            }
                        }
                    }
                } else {//only a single suggestion was given
                    autoSuggestionPopUpWindow.setVisible(false);
                    setFocusToTextField();
                    checkForAndShowSuggestions();//fire method as if document listener change occured and fired it
                }
            }
        });
    }

    private void setFocusToTextField() {
        container.toFront();
        container.requestFocusInWindow();
        textField.requestFocusInWindow();
    }

    public ArrayList<SuggestionLabel> getAddedSuggestionLabels() {
        ArrayList<SuggestionLabel> sls = new ArrayList<>();
        for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) {
            if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) {
                SuggestionLabel sl = (SuggestionLabel) suggestionsPanel.getComponent(i);
                sls.add(sl);
            }
        }
        return sls;
    }

    private void checkForAndShowSuggestions() {
        typedWord = getCurrentlyTypedWord();

        suggestionsPanel.removeAll();//remove previos words/jlabels that were added

        //used to calcualte size of JWindow as new Jlabels are added
        tW = 0;
        tH = 0;

        boolean added = wordTyped(typedWord);

        if (!added) {
            if (autoSuggestionPopUpWindow.isVisible()) {
                autoSuggestionPopUpWindow.setVisible(false);
            }
        } else {
            showPopUpWindow();
            setFocusToTextField();
        }
    }

    protected void addWordToSuggestions(String word) {
        SuggestionLabel suggestionLabel = new SuggestionLabel(word, suggestionFocusedColor, suggestionsTextColor, this);

        calculatePopUpWindowSize(suggestionLabel);

        suggestionsPanel.add(suggestionLabel);
    }

    public String getCurrentlyTypedWord() {//get newest word after last white spaceif any or the first word if no white spaces
        String text = textField.getText();
        String wordBeingTyped = "";
        if (text.contains(" ")) {
            int tmp = text.lastIndexOf(" ");
            if (tmp >= currentIndexOfSpace) {
                currentIndexOfSpace = tmp;
                wordBeingTyped = text.substring(text.lastIndexOf(" "));
            }
        } else {
            wordBeingTyped = text;
        }
        return wordBeingTyped.trim();
    }

    private void calculatePopUpWindowSize(JLabel label) {
        //so we can size the JWindow correctly
        if (tW < label.getPreferredSize().width) {
            tW = label.getPreferredSize().width;
        }
        tH += label.getPreferredSize().height;
    }

    private void showPopUpWindow() {
        autoSuggestionPopUpWindow.getContentPane().add(suggestionsPanel);
        autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textField.getWidth(), 30));
        autoSuggestionPopUpWindow.setSize(tW, tH);
        autoSuggestionPopUpWindow.setVisible(true);

        int windowX = 0;
        int windowY = 0;

        windowX = container.getX() + textField.getX() + 5;
        if (suggestionsPanel.getHeight() > autoSuggestionPopUpWindow.getMinimumSize().height) {
            windowY = container.getY() + textField.getY() + textField.getHeight() + autoSuggestionPopUpWindow.getMinimumSize().height;
        } else {
            windowY = container.getY() + textField.getY() + textField.getHeight() + autoSuggestionPopUpWindow.getHeight();
        }

        autoSuggestionPopUpWindow.setLocation(windowX, windowY);
        autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textField.getWidth(), 30));
        autoSuggestionPopUpWindow.revalidate();
        autoSuggestionPopUpWindow.repaint();

    }

    public void setDictionary(ArrayList<String> words) {
        dictionary.clear();
        if (words == null) {
            return;//so we can call constructor with null value for dictionary without exception thrown
        }
        for (String word : words) {
            dictionary.add(word);
        }
    }

    public JWindow getAutoSuggestionPopUpWindow() {
        return autoSuggestionPopUpWindow;
    }

    public Window getContainer() {
        return container;
    }

    public JTextField getTextField() {
        return textField;
    }

    public void addToDictionary(String word) {
        dictionary.add(word);
    }

    boolean wordTyped(String typedWord) {

        if (typedWord.isEmpty()) {
            return false;
        }
        //System.out.println("Typed word: " + typedWord);

        boolean suggestionAdded = false;

        for (String word : dictionary) {//get words in the dictionary which we added
            boolean fullymatches = true;
            for (int i = 0; i < typedWord.length(); i++) {//each string in the word
                if (!typedWord.toLowerCase().startsWith(String.valueOf(word.toLowerCase().charAt(i)), i)) {//check for match
                    fullymatches = false;
                    break;
                }
            }
            if (fullymatches) {
                addWordToSuggestions(word);
                suggestionAdded = true;
            }
        }
        return suggestionAdded;
    }
}

class SuggestionLabel extends JLabel {

    private boolean focused = false;
    private final JWindow autoSuggestionsPopUpWindow;
    private final JTextField textField;
    private final AutoSuggestor autoSuggestor;
    private Color suggestionsTextColor, suggestionBorderColor;

    public SuggestionLabel(String string, final Color borderColor, Color suggestionsTextColor, AutoSuggestor autoSuggestor) {
        super(string);

        this.suggestionsTextColor = suggestionsTextColor;
        this.autoSuggestor = autoSuggestor;
        this.textField = autoSuggestor.getTextField();
        this.suggestionBorderColor = borderColor;
        this.autoSuggestionsPopUpWindow = autoSuggestor.getAutoSuggestionPopUpWindow();

        initComponent();
    }

    private void initComponent() {
        setFocusable(true);
        setForeground(suggestionsTextColor);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me) {
                super.mouseClicked(me);

                replaceWithSuggestedText();

                autoSuggestionsPopUpWindow.setVisible(false);
            }
        });

        getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "Enter released");
        getActionMap().put("Enter released", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                replaceWithSuggestedText();
                autoSuggestionsPopUpWindow.setVisible(false);
            }
        });
    }

    public void setFocused(boolean focused) {
        if (focused) {
            setBorder(new LineBorder(suggestionBorderColor));
        } else {
            setBorder(null);
        }
        repaint();
        this.focused = focused;
    }

    public boolean isFocused() {
        return focused;
    }

    private void replaceWithSuggestedText() {
        String suggestedWord = getText();
        String text = textField.getText();
        String typedWord = autoSuggestor.getCurrentlyTypedWord();
        String t = text.substring(0, text.lastIndexOf(typedWord));
        String tmp = t + text.substring(text.lastIndexOf(typedWord)).replace(typedWord, suggestedWord);
        textField.setText(tmp + " ");
    }
}
package autocomplete;

import com.mxrck.autocompleter.TextAutoCompleter;
import java.sql.SQLException;
import javax.swing.JFrame;
import javax.swing.JTextField;


public class AutoComplete {
    JFrame f=new JFrame();
    JTextField t1;
AutoComplete() throws ClassNotFoundException, SQLException{

    f.setSize(500,500);
    f.setLocation(500,100);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setLayout(null);
    f.setVisible(true);


    t1=new JTextField();
    t1.setBounds(50,80,200,20);
    f.add(t1);


    TextAutoCompleter complete=new TextAutoCompleter(t1);
    DBConn conn=new DBConn();
        conn.connection();
        conn.retrieve();
    while(conn.rs.next()){

        complete.addItem(conn.rs.getString("number"));
    }


}


    public static void main(String[] args) throws ClassNotFoundException,
    SQLException{           

        new AutoComplete();
   }

}


//Create seperate class for database connection and write the following code


package autocomplete;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class DBConn {

    Connection con; ResultSet rs;PreparedStatement stat;

public void connection() throws ClassNotFoundException, SQLException{
    String url="jdbc:mysql://localhost:3306/";
    String driver="com.mysql.jdbc.Driver";   
    String db="demo";
    String username="root";
    String password="root";
    stat =null; 

        Class.forName(driver);
       con=(Connection)DriverManager.getConnection
       (url+db,username,password);              
        System.out.println("Connecttion SuccessFul");
}  

public void retrieve() throws SQLException{

    Statement  stmt=con.createStatement();
    String query="select number from phone";
    rs = stmt.executeQuery(query);

    System.out.println("retrieve succesfully");

}
//here I have to do my code for up key
    //---------------------------------------------------------------------
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Up released");
    textField.getActionMap().put("Up released", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent ae) {//focuses the first label on popwindow
            for (int i = suggestionsPanel.getComponentCount()-1; i >=0; i--) {
                if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) {
                    ((SuggestionLabel) suggestionsPanel.getComponent(i)).setFocused(true);
                    autoSuggestionPopUpWindow.toFront();
                    autoSuggestionPopUpWindow.requestFocusInWindow();
                    suggestionsPanel.requestFocusInWindow();
                    suggestionsPanel.getComponent(i).requestFocusInWindow();
                    break;
                }
            }
        }
    });

    suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Up released");
    suggestionsPanel.getActionMap().put("Up released", new AbstractAction() {
        //######int lastFocusableIndex = 0;
        int lastFocusableIndex = 0;
        //lastFocusableIndex=lastFocusableIndex___;
        @Override
        public void actionPerformed(ActionEvent ae) {//allows scrolling of labels in pop window (I know very hacky for now :))

            ArrayList<SuggestionLabel> sls = getAddedSuggestionLabels();
            int max = sls.size();
            lastFocusableIndex=lastFocusableIndex___;

            System.out.println("UP UP UP UP");//***// 
            System.out.println("max = "+String.valueOf(max));//***// 
            System.out.println("lastFocusableIndex = "+String.valueOf(lastFocusableIndex));//***// 
            System.out.println("UP UP UP UP");//***// 

            if (max > 1) {//more than 1 suggestion
                for (int i = max-1; i >=0; i--) {
                    SuggestionLabel sl = sls.get(i);
                    if (sl.isFocused()) {
                        if (lastFocusableIndex == 0) {
                            lastFocusableIndex = max - 1;
                            lastFocusableIndex___=lastFocusableIndex;
                            sl.setFocused(false);
                            autoSuggestionPopUpWindow.setVisible(false);
                            setFocusToTextField();
                            checkForAndShowSuggestions();//fire method as if document listener change occured and fired it

                        } else {
                            sl.setFocused(false);
                            lastFocusableIndex = i;
                            lastFocusableIndex___=lastFocusableIndex;
                        }
                    } else if (lastFocusableIndex > i) {
                        if (i < max ) {
                            sl.setFocused(true);
                            autoSuggestionPopUpWindow.toFront();
                            autoSuggestionPopUpWindow.requestFocusInWindow();
                            suggestionsPanel.requestFocusInWindow();
                            suggestionsPanel.getComponent(i).requestFocusInWindow();
                            lastFocusableIndex = i;
                            lastFocusableIndex___=lastFocusableIndex;
                            break;
                        }
                    }
                }
            } else {//only a single suggestion was given
                autoSuggestionPopUpWindow.setVisible(false);
                setFocusToTextField();
                checkForAndShowSuggestions();//fire method as if document listener change occured and fired it
            }
        }
    });
import javax.swing.border.LineBorder
import java.util.ArrayList
import javax.swing.event.DocumentListener

import java.awt.*
import java.awt.event.*
import javax.swing.*
import javax.swing.event.DocumentEvent

/**
 * Author of the original version: David @ https://stackoverflow.com/users/1133011/david-kroukamp
 */
class Test {
    init {

        val frame = JFrame()
        frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE


        val f = JTextField(10)

        val autoSuggestor = object : AutoSuggestor(f, frame, ArrayList(), Color.WHITE.brighter(), Color.BLUE, Color.RED, 0.75f) {
            override fun wordTyped(typedWord: String?): Boolean {

                //create list for dictionary this in your case might be done via calling a method which queries db and returns results as arraylist
                val words = ArrayList<String>()
                words.add("hello")
                words.add("heritage")
                words.add("happiness")
                words.add("goodbye")
                words.add("cruel")
                words.add("car")
                words.add("war")
                words.add("will")
                words.add("world")
                words.add("wall")


                setDictionary(words)
                //addToDictionary("bye");//adds a single word

                return super.wordTyped(typedWord)//now call super to check for any matches against newest dictionary
            }
        }

        val p = JPanel()

        p.add(f)

        frame.add(p)

        frame.pack()
        frame.isVisible = true
    }

    companion object {

        @JvmStatic
        fun main(args: Array<String>) {
            SwingUtilities.invokeLater { Test() }
        }
    }
}

internal open class AutoSuggestor(val textField: JTextField, val container: Window, words: ArrayList<String>, popUpBackground: Color, private val suggestionsTextColor: Color, private val suggestionFocusedColor: Color, opacity: Float, private val callback: (String) -> Unit = {}) {
    private val suggestionsPanel: JPanel
    val autoSuggestionPopUpWindow: JWindow
    private var typedWord: String? = null
    private val dictionary = ArrayList<String>()
    private var currentIndexOfSpace: Int = 0
    private var tW: Int = 0
    private var tH: Int = 0
    private val documentListener = object : DocumentListener {
        override fun insertUpdate(de: DocumentEvent) {
            checkForAndShowSuggestions()
        }

        override fun removeUpdate(de: DocumentEvent) {
            checkForAndShowSuggestions()
        }

        override fun changedUpdate(de: DocumentEvent) {
            checkForAndShowSuggestions()
        }
    }

    val addedSuggestionLabels: ArrayList<SuggestionLabel>
        get() {
            val sls = ArrayList<SuggestionLabel>()
            for (i in 0 until suggestionsPanel.componentCount) {
                if (suggestionsPanel.getComponent(i) is SuggestionLabel) {
                    val sl = suggestionsPanel.getComponent(i) as SuggestionLabel
                    sls.add(sl)
                }
            }
            return sls
        }

    //get newest word after last white space if any or the first word if no white spaces
    val currentlyTypedWord: String
        get() {
            val text = textField.text
            var wordBeingTyped = ""
            if (text.contains(" ")) {
                val tmp = text.lastIndexOf(" ")
                if (tmp >= currentIndexOfSpace) {
                    currentIndexOfSpace = tmp
                    wordBeingTyped = text.substring(text.lastIndexOf(" "))
                }
            } else {
                wordBeingTyped = text
            }
            return wordBeingTyped.trim { it <= ' ' }
        }

    init {
        this.textField.document.addDocumentListener(documentListener)

        setDictionary(words)

        typedWord = ""
        currentIndexOfSpace = 0
        tW = 0
        tH = 0

        autoSuggestionPopUpWindow = JWindow(container)
        autoSuggestionPopUpWindow.opacity = opacity

        suggestionsPanel = JPanel()
        suggestionsPanel.layout = GridLayout(0, 1)
        suggestionsPanel.background = popUpBackground

        addFocusListenersToHandleVisibilityOfPopUpWindow()
        addKeyBindingToRequestFocusInPopUpWindow()
    }

    private fun addFocusListenersToHandleVisibilityOfPopUpWindow() {
        textField.addFocusListener(object:FocusListener {
            override fun focusLost(e: FocusEvent?) {
                var focusOnPopUp = false
                for (i in 0 until suggestionsPanel.componentCount) {
                    if (suggestionsPanel.getComponent(i) is SuggestionLabel) {
                        val label = suggestionsPanel.getComponent(i) as SuggestionLabel
                        if (label.isFocused)
                            focusOnPopUp = true
                    }
                }

                if (!focusOnPopUp && !shouldShowPopUpWindow) {
                    autoSuggestionPopUpWindow.isVisible = false
                }
            }
            override fun focusGained(e: FocusEvent?) {
                shouldShowPopUpWindow = false
            }
        })
    }

    private fun addKeyBindingToRequestFocusInPopUpWindow() {
        textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true), "Escape released")
        textField.actionMap.put("Escape released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {// Hide the popwindow
                shouldShowPopUpWindow = false
                autoSuggestionPopUpWindow.isVisible = false
            }
        })


        textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released")
        textField.actionMap.put("Down released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {//focuses the first label on popwindow
                for (i in 0 until suggestionsPanel.componentCount) {
                    if (suggestionsPanel.getComponent(i) is SuggestionLabel) {
                        (suggestionsPanel.getComponent(i) as SuggestionLabel).isFocused = true
                        autoSuggestionPopUpWindow.toFront()
                        autoSuggestionPopUpWindow.requestFocusInWindow()
                        suggestionsPanel.requestFocusInWindow()
                        suggestionsPanel.getComponent(i).requestFocusInWindow()
                        break
                    }
                }
            }
        })

        textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Up released")
        textField.actionMap.put("Up released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {//focuses the last label on popwindow
                for (i in 0 until suggestionsPanel.componentCount) {
                    val reverseIndex = suggestionsPanel.componentCount-1 - i
                    if (suggestionsPanel.getComponent(reverseIndex) is SuggestionLabel) {
                        (suggestionsPanel.getComponent(reverseIndex) as SuggestionLabel).isFocused = true
                        autoSuggestionPopUpWindow.toFront()
                        autoSuggestionPopUpWindow.requestFocusInWindow()
                        suggestionsPanel.requestFocusInWindow()
                        suggestionsPanel.getComponent(reverseIndex).requestFocusInWindow()
                        break
                    }
                }
            }
        })

        suggestionsPanel.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true), "Escape released")
        suggestionsPanel.actionMap.put("Escape released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {// Hide the popwindow
                shouldShowPopUpWindow = false
                autoSuggestionPopUpWindow.isVisible = false
            }
        })
        suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Up released")
        suggestionsPanel.actionMap.put("Up released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {//allows scrolling of labels in pop window (I know very hacky for now :))

                val sls = addedSuggestionLabels
                val max = sls.size

                var indexOfFocusedSuggestion = -1
                for (i in 0 until max) {
                    val sl = sls[i]
                    if ( sl.isFocused )
                        indexOfFocusedSuggestion = i
                }

                if (indexOfFocusedSuggestion - 1 < 0) {
                    sls[indexOfFocusedSuggestion].isFocused = false
                    autoSuggestionPopUpWindow.isVisible = false
                    setFocusToTextField()
                    checkForAndShowSuggestions()//fire method as if document listener change occured and fired it
                }
                else {
                    sls[indexOfFocusedSuggestion].isFocused = false
                    sls[indexOfFocusedSuggestion-1].isFocused = true
                    autoSuggestionPopUpWindow.toFront()
                    autoSuggestionPopUpWindow.requestFocusInWindow()
                    suggestionsPanel.requestFocusInWindow()
                    suggestionsPanel.getComponent(indexOfFocusedSuggestion-1).requestFocusInWindow()
                }

            }
        })
        suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released")
        suggestionsPanel.actionMap.put("Down released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {//allows scrolling of labels in pop window (I know very hacky for now :))

                val sls = addedSuggestionLabels
                val max = sls.size

                var indexOfFocusedSuggestion = -1
                for (i in 0 until max) {
                    val sl = sls[i]
                    if ( sl.isFocused )
                        indexOfFocusedSuggestion = i
                }

                if (indexOfFocusedSuggestion + 1 >= max) {
                    sls[indexOfFocusedSuggestion].isFocused = false
                    autoSuggestionPopUpWindow.isVisible = false
                    setFocusToTextField()
                    checkForAndShowSuggestions()//fire method as if document listener change occured and fired it
                }
                else {
                    sls[indexOfFocusedSuggestion].isFocused = false
                    sls[indexOfFocusedSuggestion+1].isFocused = true
                    autoSuggestionPopUpWindow.toFront()
                    autoSuggestionPopUpWindow.requestFocusInWindow()
                    suggestionsPanel.requestFocusInWindow()
                    suggestionsPanel.getComponent(indexOfFocusedSuggestion+1).requestFocusInWindow()
                }
            }

        })
    }

    private fun setFocusToTextField() {
        container.toFront()
        container.requestFocusInWindow()
        textField.requestFocusInWindow()
    }

    var shouldShowPopUpWindow = false

    private fun checkForAndShowSuggestions() {
        typedWord = currentlyTypedWord

        suggestionsPanel.removeAll()//remove previos words/jlabels that were added

        //used to calcualte size of JWindow as new Jlabels are added
        tW = 0
        tH = 0

        val added = wordTyped(typedWord)

        if (!added) {
            if (autoSuggestionPopUpWindow.isVisible) {
                autoSuggestionPopUpWindow.isVisible = false
            }
        } else {
            shouldShowPopUpWindow = true
            showPopUpWindow()
            setFocusToTextField()
        }
    }

    protected fun addWordToSuggestions(word: String) {
        val suggestionLabel = SuggestionLabel(word, suggestionFocusedColor, suggestionsTextColor, this, callback)

        calculatePopUpWindowSize(suggestionLabel)

        suggestionsPanel.add(suggestionLabel)
    }

    private fun calculatePopUpWindowSize(label: JLabel) {
        //so we can size the JWindow correctly
        if (tW < label.preferredSize.width) {
            tW = label.preferredSize.width
        }
        tH += label.preferredSize.height
    }

    private fun showPopUpWindow() {
        autoSuggestionPopUpWindow.contentPane.add(suggestionsPanel)
        autoSuggestionPopUpWindow.minimumSize = Dimension(textField.width, 30)
        autoSuggestionPopUpWindow.setSize(tW, tH)
        autoSuggestionPopUpWindow.isVisible = true

        var windowX = 0
        var windowY = 0

        windowX = container.getX() + textField.x + 5
        if (suggestionsPanel.height > autoSuggestionPopUpWindow.minimumSize.height) {
            windowY = container.getY() + textField.y + textField.height + autoSuggestionPopUpWindow.minimumSize.height
        } else {
            windowY = container.getY() + textField.y + textField.height + autoSuggestionPopUpWindow.height
        }

        autoSuggestionPopUpWindow.setLocation(windowX, windowY)
        autoSuggestionPopUpWindow.minimumSize = Dimension(textField.width, 30)
        autoSuggestionPopUpWindow.revalidate()
        autoSuggestionPopUpWindow.repaint()

    }

    fun setDictionary(words: ArrayList<String>?) {
        dictionary.clear()
        if (words == null) {
            return //so we can call constructor with null value for dictionary without exception thrown
        }
        for (word in words) {
            dictionary.add(word)
        }
    }

    fun addToDictionary(word: String) {
        dictionary.add(word)
    }

    open fun wordTyped(typedWord: String?): Boolean {

        if (typedWord!!.isEmpty()) {
            return false
        }

        var suggestionAdded = false

        for (word in dictionary) {//get words in the dictionary which we added
            var fullyMatches = word.length >= typedWord.length
            for (i in 0 until typedWord.length) {//each string in the word
                if (word.length > i && !typedWord.toLowerCase().startsWith(word.toLowerCase()[i].toString(), i)) {//check for match
                    fullyMatches = false
                    break
                }
            }
            if (fullyMatches) {
                addWordToSuggestions(word)
                suggestionAdded = true
            }
        }
        return suggestionAdded
    }
}

internal class SuggestionLabel(string: String, private val suggestionBorderColor: Color, private val suggestionsTextColor: Color, private val autoSuggestor: AutoSuggestor, private val callback: (String) -> Unit) : JLabel(string) {

    var isFocused = false
        set(focused) {
            if (focused) {
                border = LineBorder(suggestionBorderColor)
            } else {
                border = null
            }
            repaint()
            field = focused
        }
    private val autoSuggestionsPopUpWindow: JWindow
    private val textField: JTextField

    init {
        this.textField = autoSuggestor.textField
        this.autoSuggestionsPopUpWindow = autoSuggestor.autoSuggestionPopUpWindow

        initComponent()
    }

    private fun initComponent() {
        isFocusable = true
        foreground = suggestionsTextColor

        addMouseListener(object : MouseAdapter() {
            override fun mouseClicked(me: MouseEvent) {
                super.mouseClicked(me)

                replaceWithSuggestedText()

                autoSuggestionsPopUpWindow.isVisible = false
            }
        })

        getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "Enter released")
        actionMap.put("Enter released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {
                replaceWithSuggestedText()
                autoSuggestionsPopUpWindow.isVisible = false
            }
        })

        getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true), "Escape released")
        actionMap.put("Escape released", object : AbstractAction() {
            override fun actionPerformed(ae: ActionEvent) {// Hide the popwindow
                autoSuggestionsPopUpWindow.isVisible = false
            }
        })
    }

    private fun replaceWithSuggestedText() {

        val suggestedWord = text
        val text = textField.text
        val typedWord = autoSuggestor.currentlyTypedWord
        val t = text.substring(0, text.lastIndexOf(typedWord))
        val tmp = t + text.substring(text.lastIndexOf(typedWord)).replace(typedWord, suggestedWord)
        textField.text = tmp
        callback(tmp)
    }
}