欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java实现自动补全提示的文本框

程序员文章站 2022-07-14 17:59:09
...
使用自定义的文本框控件,从数据库中读取值对输入内容自动提示。
1.ListPopup类:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.MouseInputListener;

/**
*
* @author William Chen
*/
public class ListPopup extends JPopupMenu implements MouseInputListener {

private JList list;
private JScrollPane pane;
private ArrayList<ListSelectionListener> listeners=new ArrayList<ListSelectionListener>();
public void addListSelectionListener(ListSelectionListener l){
if(!listeners.contains(l))
listeners.add(l);
}
public void setSelectedIndex(int index){
if(index>=list.getModel().getSize())
index=0;
if(index<0)
index=list.getModel().getSize()-1;
list.ensureIndexIsVisible(index);
list.setSelectedIndex(index);
}
public Object getSelectedValue(){
return list.getSelectedValue();
}
public int getSelectedIndex(){
return list.getSelectedIndex();
}
public boolean isSelected(){
return list.getSelectedIndex()!=-1;
}
public void setLastOneSelected(){
int count=list.getModel().getSize();
if(count>0){
list.ensureIndexIsVisible(count-1);
list.setSelectedIndex(count-1);
}
}
public void removeListSelectionListener(ListSelectionListener l){
if(listeners.contains(l))
listeners.remove(l);
}
private void fireValueChanged(ListSelectionEvent e){
for(ListSelectionListener l:listeners){
l.valueChanged(e);
}
}
public ListPopup() {
setLayout(new BorderLayout());
list = new JList();
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.addMouseListener(this);
list.addMouseMotionListener(this);
list.setModel(new DefaultListModel());
pane = new JScrollPane(list);
pane.setBorder(null);
add(pane, BorderLayout.CENTER);
}

public int getItemCount() {
DefaultListModel model = (DefaultListModel) list.getModel();
return model.getSize();
}

public Object getItem(int index) {
DefaultListModel model = (DefaultListModel) list.getModel();
return model.get(index);
}

public void addItem(Object o) {
DefaultListModel model = (DefaultListModel) list.getModel();
model.addElement(o);
list.repaint();
}

public void removeItem(Object o) {
DefaultListModel model = (DefaultListModel) list.getModel();
model.removeElement(o);
list.repaint();
}

public void setList(Iterable iterable) {
DefaultListModel model = new DefaultListModel();
for (Object o : iterable) {
model.addElement(o);
}
list.setModel(model);
list.repaint();
}

public void setList(Enumeration e) {
DefaultListModel model = new DefaultListModel();
while (e.hasMoreElements()) {
model.addElement(e.nextElement());
}
list.setModel(model);
list.repaint();
}

public void setList(Object... objects) {
DefaultListModel model = new DefaultListModel();
for (Object o : objects) {
model.addElement(o);
}
list.setModel(model);
list.repaint();
}


public void mouseClicked(MouseEvent e) {
}

public void mousePressed(MouseEvent e) {
if(list.getSelectedIndex()!=-1)
fireValueChanged(new ListSelectionEvent(list, list.getSelectedIndex(), list.getSelectedIndex(), true));
}

public void mouseReleased(MouseEvent e) {
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

public void mouseMoved(MouseEvent anEvent) {
if (anEvent.getSource() == list) {
Point location = anEvent.getPoint();
Rectangle r = new Rectangle();
list.computeVisibleRect(r);
if (r.contains(location)) {
updateListBoxSelectionForEvent(anEvent, false);
}
}
}

protected void updateListBoxSelectionForEvent(MouseEvent anEvent, boolean shouldScroll) {

Point location = anEvent.getPoint();
if (list == null) {
return;
}
int index = list.locationToIndex(location);
if (index == -1) {
if (location.y < 0) {
index = 0;
} else {
index = list.getModel().getSize() - 1;
}
}
if (list.getSelectedIndex() != index) {
list.setSelectedIndex(index);
if (shouldScroll) {
list.ensureIndexIsVisible(index);
}
}
}

public void mouseDragged(MouseEvent e) {
}
}


2.AutoCompletionField类:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class AutoCompletionField extends JTextField implements DocumentListener, MouseListener, ListSelectionListener, ActionListener, KeyListener {

private static int DEFAULT_PREFERRED_HEIGHT = 100;
private ListPopup popup;
private int preferredHeight = DEFAULT_PREFERRED_HEIGHT;
private CompletionFilter filter;

public void setFilter(CompletionFilter f) {
filter = f;
}

public AutoCompletionField() {
popup = new ListPopup();
getDocument().addDocumentListener(this);
addMouseListener(this);
popup.addListSelectionListener(this);
addActionListener(this);
addKeyListener(this);
}

public void setPopupPreferredHeight(int h) {
preferredHeight = h;
}

private boolean isListChange(ArrayList array) {
if (array.size() != popup.getItemCount()) {
return true;
}
for (int i = 0; i < array.size(); i++) {
if (!array.get(i).equals(popup.getItem(i))) {
return true;
}
}
return false;
}

private void textChanged() {
if ("".equals(this.getText()))
popup.setVisible(false);
else {
if (!popup.isVisible()) {
showPopup();
requestFocus();
}
if (filter != null) {
ArrayList array = filter.filter(getText());
changeList(array);
}

}

}

private void showPopup() {
popup.setPopupSize(getWidth(), preferredHeight);
popup.show(this, 0, getHeight()-1);
}

private void changeList(ArrayList array) {
if (array.size() == 0) {
if (popup.isVisible()) {
popup.setVisible(false);
}
} else {
if (!popup.isVisible()) {
showPopup();
}
}
if (isListChange(array)&&array.size()!=0) {
popup.setList(array);
}
}

public void insertUpdate(DocumentEvent e) {
textChanged();
}

public void removeUpdate(DocumentEvent e) {
textChanged();
}

public void changedUpdate(DocumentEvent e) {
textChanged();
}

public void mouseClicked(MouseEvent e) {
if(e.getClickCount()>1 && !popup.isVisible())
textChanged();
}

public void mousePressed(MouseEvent e) {
}

public void mouseReleased(MouseEvent e) {
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

public void valueChanged(ListSelectionEvent e) {
JList list=(JList)e.getSource();
String text=list.getSelectedValue().toString();
setText(text);
popup.setVisible(false);
}

public void actionPerformed(ActionEvent e) {
if(popup.isVisible()){
Object o=popup.getSelectedValue();
if(o!=null)
setText(o.toString());
popup.setVisible(false);
}
this.selectAll();
this.requestFocus();
}

public void keyTyped(KeyEvent e) {
}

public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_DOWN){
if(popup.isVisible()){
if(!popup.isSelected())
popup.setSelectedIndex(0);
else
popup.setSelectedIndex(popup.getSelectedIndex()+1);
}
}else if(e.getKeyCode()==KeyEvent.VK_UP){
if(popup.isVisible()){
if(!popup.isSelected())
popup.setLastOneSelected();
else
popup.setSelectedIndex(popup.getSelectedIndex()-1);
}
}else if(e.getKeyCode()==KeyEvent.VK_PAGE_DOWN){
if(popup.isVisible()){
if(!popup.isSelected())
popup.setSelectedIndex(0);
else
popup.setSelectedIndex(popup.getSelectedIndex()+5);
}
}else if(e.getKeyCode()==KeyEvent.VK_PAGE_UP){
if(popup.isVisible()){
if(!popup.isSelected())
popup.setLastOneSelected();
else
popup.setSelectedIndex(popup.getSelectedIndex()-5);
}
}
}

public void keyReleased(KeyEvent e) {
}
}


3.CompletionFilter类:

import java.util.ArrayList;

public interface CompletionFilter {
ArrayList filter(String text);
}


4.DefaultCompletionFilter类:

import java.util.ArrayList;
import java.util.Vector;

public class DefaultCompletionFilter implements CompletionFilter {

private Vector vector;

public DefaultCompletionFilter() {
vector = new Vector();
}

public DefaultCompletionFilter(Vector v) {
vector = v;
}
public ArrayList filter(String text) {
ArrayList list=new ArrayList();
String txt=text.trim();
int length=txt.length();
for(int i=0;i<vector.size();i++){
Object o=vector.get(i);
String str=o.toString();
if(length==0||str.startsWith(txt)) //输入内容与记录前端比较
list.add(o);
}
return list;
}
}


5.使用的控件MyAutoField,使用时指定查询条件和自动提示的字段:

import java.awt.im.InputMethodRequests;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import com.borland.jbcl.layout.XYConstraints;
import com.borland.jbcl.layout.XYLayout;
import yz.jlsys.connect.connector;

public class MyAutoField extends AutoCompletionField {

/** Creates new form AutoCompletionFrame */
public MyAutoField(String sql,String field) {
super();
Vector tempvector = new Vector();
connector connec = new connector(); // 数据库操作对象
ResultSet rs = connec.getResult(sql);
try{
//若结果集不为空,则显示每条记录
boolean isexist = false;
isexist = rs.first();

if(isexist)
{
//移动光标到零的位置
rs.beforeFirst();
while(rs.next() )
{
if(tempvector.contains(rs.getString(field)))
continue;
tempvector.add(rs.getString(field));
}
}
}
catch(SQLException e){

}
this.setFilter(new DefaultCompletionFilter(tempvector));
}

public InputMethodRequests getInputMethodRequests() {
return null;
}

public static void main(String args[]) {

try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame j = new JFrame();
j.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
j.setContentPane(contentPane);
contentPane.setLayout(new XYLayout());
j.setSize(800,720);
j.getContentPane().add(new MyAutoField("select * from clienttable where CLIENTNAME like '%'", "CLIENTNAME"), new XYConstraints(40, 95, 200, 25));
j.setVisible(true);

}
}


以上5个文件放到同一个包中,从MyAutoField的main可运行。