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()
,JWindow
和JList
的{{1}},但问题不会发生。
我希望它与装饰JScrollPane
的大小相匹配,无论是什么
答案 0 :(得分:7)
JList
或JComboBox
未返回正确的PreferredSize
,必须设置此值,JList.setPrototypeCellValue()使用pack()
{{1} (必须在任何更改后打包)和/或JList.setVisibleRowCount(),然后JWindow
getPreferredScrollableViewportSize()
的值返回JList
不要使用KeyListener
,使用DocumentListener
(可以从系统剪贴板插入字符)JTextComponents
不要重新发明轮子,使用AutoComplete JComboBox / JTextField,你可以将匹配的结果重定向/返回弹出窗口JWindow
/ undecorated JDialog
(quite the best workaround for popup recycle)
修改
无论如何基本上我将不得不手动创建所有的列表 要得到支持的城市吗? bx @Little Child
这个想法可能很简单,你可以放JTable
to the JWindow
只有一个JScrollPane
,
没有Column
添加RowSorter(参见教程中的代码示例)
然后每个步骤都完成了:-),那里不需要任何其他内容(如果JTableHeader
没有返回任何匹配项,可能会更改Background
JTextField
的奖励,添加来自RowFilter
的弹出窗口setVisible
(请务必测试DocumentListener
))
答案 1 :(得分:1)
每次启动搜索时都需要使用JFrame
的宽度,并使用它来计算列表的宽度。
只需像这样更改initiateSearch()函数:
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:为了更好的美学,尝试使用一些布局使文本字段填满整个宽度。
答案 2 :(得分:1)
您应该使用JComboBox,并且要自动完成,请阅读this article。
答案 3 :(得分:1)
一种解决方案是将initiateDisplay()更改为:
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);
}