参见英文答案 >
Create a autocompleting textbox in Java with a dropdown list5个
算法
算法
>开始
>输入城市名称 – 部分或完整
>如果用户点击输入,请从JTextField获取文本
>开始暴力搜索.
>如果找到匹配项,将它们放在Vector中并将其放在JList中
>如果没有找到匹配,请在Vector中添加一个字符串“No Match Found”
>将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的大小(JScrollPane中的JList)根据结果而变化 – 如果城市名称较小,则JWindow很小,如果城市名称较大,则JWindow很大.
我已经尝试了所有可能的组合.我尝试使用JWindow,JList和JScrollPane的setPreferredDimension(),但问题不会消失.
我想要它匹配装饰的JFrame的大小,无论什么
解决方法
> JList或JComboBox不返回适当的PreferredSize,必须设置此值,为JWindow使用
JList.setPrototypeCellValue()(必须在任何更改后打包)和/或使用
JList.setVisibleRowCount(),然后在JScrollPane中为JList返回getPreferredScrollableViewportSize()
>不要使用
>不要重创轮子,使用 AutoComplete JComboBox / JTextField,可以重定向/从匹配返回结果到弹出窗口
>不要使用
KeyListener
,使用
DocumentListener
(可以从系统剪贴板插入字符)为
JTextComponents
>不要重创轮子,使用 AutoComplete JComboBox / JTextField,可以重定向/从匹配返回结果到弹出窗口
JWindow
/ undecorated JDialog
(quite the best workaround for popup recycle)
编辑
Anyways so basically I will have to manually create a list of all the
cities that are to be supported right ?? bx @Little Child
>这个想法可能很容易,可以把JTable
to the JWindow
>一列,
>没有JTableHeader
>添加RowSorter(参见教程中的代码示例)>然后每个步骤都完成:-),没有其他需要在那里(也许奖金更改JTextField的背景,在RowFilter返回没有匹配的情况下,从DocumentListener添加setVisible弹出窗口(一定要测试!isVisible))