Реализация автозаполнения в Java - я делаю это правильно? [дубликат]
этот вопрос уже есть ответ здесь:
алгоритм
- старт
- введите название города - частичное или полное
- если пользователь нажимает enter, возьмите текст из
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
и JScrollPane
но проблема не пойдет.
Я хочу, чтобы он соответствовал размеру украшенного JFrame
несмотря ни на что
4 ответов
JList
илиJComboBox
не возвращает правильноеPreferredSize
, чтобы установить это значение, используйте JList.setPrototypeCellValue () Сpack()
наJWindow
(должен быть упакован после любых изменений) и / или с JList.setVisibleRowCount(), а затем возвращает значениеgetPreferredScrollableViewportSize()
наJList
наJScrollPane
не использовать
KeyListener
используйтеDocumentListener
(символы могут быть вставлены из буфера обмена системы)JTextComponents
не изобретать колесо, использовать Автозаполнение JComboBox / JTextField, вы можете перенаправить / возвращает результат из матчей во всплывающее окно
JWindow
/ без украшенийJDialog
(довольно лучший обходной путь для popup recycle)
редактировать
в любом случае, так что в основном мне придется вручную создать список всех города, которые должны быть поддержаны правильно ?? ВХ @маленький ребенок
эта идея может быть довольно легко, вы можете поставить
JTable
доJWindow
С
Column
,без
JTableHeader
добавить RowSorter (см. Пример кода в учебнике)
затем все шаги сделаны : -), больше ничего не требуется (возможно, бонус для изменения
Background
ofJTextField
в случае, еслиRowFilter
не возвращает совпадений, добавитьsetVisible
для всплывающего окна изDocumentListener
(обязательно проверьте на!isVisible
))
вы должны использовать jcombobox в, и для автозаполнения прочитайте в этой статье.
вам нужно использовать ширину 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: просто для лучшей эстетики попробуйте использовать некоторый макет, чтобы текстовое поле заполнило всю ширину.
одним из решений было бы изменить 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);
}