在Java中实现自动完成 - 我在做对吗? [英] Implementing auto complete in Java - am I doing it right?
问题描述
算法
- 开始
- 输入城市名 - 部分或完全
- 如果用户点击进入,采取从
的JTextField
文本 - 开始蛮力搜索。
- 如果找到匹配项,将它们放在一个
矢量
,并把它放在一个JList的
- 如果没有发现匹配,添加一个
字符串
无匹配找到在矢量
- 显示
的JWindow
来包含结果用户 - 停止
code:
封装测试;
进口的javax.swing *。进口java.awt.Dimension中;
java.awt.event中导入*。
进口java.util.Vector中;公共类AutoCompleteTest扩展的JFrame {
JTextField的城市=新的JTextField(10);
字符串enteredName = NULL;
的String [] =城市{新泽西,新罕布什尔
苏塞克斯,埃塞克斯,伦敦,德里,纽约};
JList的列表=新的JList();
JScrollPane的窗格=新JScrollPane的();
ResultWindow R =新ResultWindow();
// ------------------------------------------------ ------------------------------
公共静态无效的主要(字串[] args){
新AutoCompleteTest();
}
// ------------------------------------------------ ------------------------------
公共AutoCompleteTest(){
的setLayout(新java.awt.FlowLayout中());
调用setVisible(真);
加(市);
//添加(面板);
包();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
city.addKeyListener(新TextHandler());
}
// ------------------------------------------------ ------------------------------
公共无效initiateSearch(字符串lookFor){
矢量<串GT;比赛=新的矢量<>();
lookFor = lookFor.toLowerCase();
对于(每个字符串:市){
如果(each.contains(lookFor)){
matches.add(个);
的System.out.println(匹配+每);
}
}
this.repaint(); 如果(matches.size()!= 0){
list.setListData(匹配);
r.searchResult =清单;
r.pane =窗格;
r.initiateDisplay();
}其他{
matches.add(无匹配找到);
list.setListData(匹配);
r.searchResult =清单;
r.pane =窗格;
r.initiateDisplay();
} }
// ------------------------------------------------ ------------------------------
公共类ResultWindow扩展的JWindow {
公共JScrollPane的窗格;
公共JList的信息搜索结果;
// ------------------------------------------------ ------------------------------
公共ResultWindow(){ }
// ------------------------------------------------ ------------------------------
公共无效initiateDisplay(){
pane.setViewportView(信息搜索结果);
加(面板);
包();
this.setLocation(AutoCompleteTest.this.getX()+ 2,
AutoCompleteTest.this.getY()+
AutoCompleteTest.this.getHeight());// this.set preferredSize(city.get preferredSize());
this.setVisible(真);
}
}
// ------------------------------------------------ ------------------------------ 类TextHandler实现的KeyListener {
@覆盖
公共无效的keyTyped(KeyEvent的E){ } @覆盖
公共无效键pressed(KeyEvent的E){
如果(r.isVisible()){
r.setVisible(假);
}
如果(e.getKeyChar()=='\\ n'){
initiateSearch(city.getText());
}
} @覆盖
公共无效调用keyReleased(KeyEvent的E){ }
}
// ------------------------------------------------ ------------------------------
}
输出
问题
大小的的JWindow
显示结果(这是一个 JList的
在根据结果JScrollPane的
)的变化 - 如果这个城市的名字是小,的JWindow
是小,如果城市名大,的JWindow
大。
我已经试过所有可能的组合。我试着用集preferredDimension()
的的JWindow
的 JList的的code>和
JScrollPane的
,但这个问题不会去。结果
我希望它匹配的大小装饰的JFrame
不管是什么
-
JList的
或的JComboBox
不正确的返回preferredSize
,必须设置此值,使用的 JList.setPrototypeCellValue()与包()
为的JWindow
(必须在任何更改后进行包装),并或的 JList.setVisibleRowCount(),则返回值的get preferredScrollableViewportSize()
为JList的
在JScrollPane的
-
不使用
的KeyListener
,使用的DocumentListener
(字符可以从系统剪贴板中插入)的的JTextComponents
-
不推倒重来,使用自动完成的JComboBox / JTextField的,则可以重定向/回报从该弹出
的JWindow
/未修饰的<$比赛结果C $ C>的JDialog (相当于弹出循环最好的解决方法)
修改
不管怎么说所以基本上我将不得不手动创建的所有列表
城市要被支持的权利? BX @Little儿童
块引用>
这种想法可能是相当容易的,你可以把
的JTable
到的JWindow
一个
列
,没有
JTableHeader的
添加有 RowSorter的(见$ C教程中的$ C为例)
然后每步骤完成:-),没有别的要求没有(也许奖金来改变
背景
的JTextField $的C $ C>在
(一定要测试的RowFilter
没有返回比赛,从调用setVisible
的弹出窗口的情况下>的DocumentListener!ISVISIBLE
))Algorithm
- Start
- Input a city name - partial or complete
- If the user hits enter , take the text from
JTextField
- Begin brute force search.
- If the matches are found, put them in a
Vector
and put it in aJList
- If no match is found, add a
String
"No Match Found" inVector
- Display
JWindow
to user containing the results- Stop
Code:
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){ } } //------------------------------------------------------------------------------ }
Output
Problem
The size of the
JWindow
displaying the results (which is aJList
in aJScrollPane
) changes based on the results - if the city name is small,JWindow
is small, if the city name is big,JWindow
is big.I have tried every possible combination. I tried using
setPreferredDimension()
of theJWindow
, theJList
andJScrollPane
but the issue won't go.
I want it to match the size of the decoratedJFrame
no matter what解决方案
JList
orJComboBox
doesn't returns properPreferredSize
, have to set this value, use JList.setPrototypeCellValue() withpack()
forJWindow
(must be packed after any changes) and or with JList.setVisibleRowCount(), then value returnsgetPreferredScrollableViewportSize()
forJList
inJScrollPane
don't to use
KeyListener
, useDocumentListener
(chars can be inserted from system clipboard) forJTextComponents
don't to reinvent the wheel, use AutoComplete JComboBox / JTextField, you can to redirect / returns result from matches to the popup
JWindow
/ undecoratedJDialog
(quite the best workaround for popup recycle)EDIT
Anyways so basically I will have to manually create a list of all the cities that are to be supported right ?? bx @Little Child
this idea could be quite easy, you can to put
JTable
to theJWindow
with one
Column
,without
JTableHeader
add there RowSorter (see code example in tutorial)
then every steps are done :-), nothing else is required there (maybe bonus to change
Background
ofJTextField
in the case thatRowFilter
returns no matches, addsetVisible
for popup window fromDocumentListener
(be sure to test for!isVisible
))这篇关于在Java中实现自动完成 - 我在做对吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!