// user has selected some item in the classes. update textfield accordingly... protected void acceptedListItem(String selected){ if(selected==null) return;
int prefixlen = textComp.getDocument().getLength();
// @author Santhosh Kumar T - [email protected] public abstract class AutoCompleter{ JList list = new JList(); JPopupMenu popup = new JPopupMenu(); JTextComponent textComp; private static final String AUTOCOMPLETER = "AUTOCOMPLETER"; //NOI18N
public AutoCompleter(JTextComponent comp){ textComp = comp; textComp.putClientProperty(AUTOCOMPLETER, this); JScrollPane scroll = new JScrollPane(list); scroll.setBorder(null);
int x = 0; try{ int pos = Math.min(textComp.getCaret().getDot(), textComp.getCaret().getMark()); x = textComp.getUI().modelToView(textComp, pos).x; } catch(BadLocationException e){ // this should never happen!!! e.printStackTrace(); } popup.show(textComp, x, textComp.getHeight()); }else popup.setVisible(false); textComp.requestFocus(); }
/** * Selects the next item in the list. It won't change the selection if the * currently selected item is already the last item. */ protected void selectNextPossibleValue(){ int si = list.getSelectedIndex();
/** * Selects the previous item in the list. It won't change the selection if the * currently selected item is already the first item. */ protected void selectPreviousPossibleValue(){ int si = list.getSelectedIndex();
private List completionList;
private boolean ignoreCase;
public ListAutoCompleter(JTextComponent comp, List completionList, boolean ignoreCase){
super(comp);
this.completionList = completionList;
this.ignoreCase = ignoreCase;
}
// update classes model depending on the data in textfield
protected boolean updateListData(){
String value = textComp.getText();
int substringLen = value.length();
List possibleStrings = new ArrayList();
Iterator iter = completionList.iterator();
while(iter.hasNext()){
String listEntry = (String)iter.next();
if(substringLen>=listEntry.length())
continue;
if(ignoreCase){
if(value.equalsIgnoreCase(listEntry.substring(0, substringLen)))
possibleStrings.add(listEntry);
}else if(listEntry.startsWith(value))
possibleStrings.add(listEntry);
}
list.setListData(possibleStrings.toArray());
return true;
}
// user has selected some item in the classes. update textfield accordingly...
protected void acceptedListItem(String selected){
if(selected==null)
return;
int prefixlen = textComp.getDocument().getLength();
try{
textComp.getDocument().insertString(textComp.getCaretPosition(), selected.substring(prefixlen), null);
} catch(BadLocationException e){
e.printStackTrace();
}
popup.setVisible(false);
}
}
public abstract class AutoCompleter{
JList list = new JList();
JPopupMenu popup = new JPopupMenu();
JTextComponent textComp;
private static final String AUTOCOMPLETER = "AUTOCOMPLETER"; //NOI18N
public AutoCompleter(JTextComponent comp){
textComp = comp;
textComp.putClientProperty(AUTOCOMPLETER, this);
JScrollPane scroll = new JScrollPane(list);
scroll.setBorder(null);
list.setFocusable( false );
scroll.getVerticalScrollBar().setFocusable( false );
scroll.getHorizontalScrollBar().setFocusable( false );
popup.setBorder(BorderFactory.createLineBorder(Color.black));
popup.add(scroll);
if(textComp instanceof JTextField){
textComp.registerKeyboardAction(showAction, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), JComponent.WHEN_FOCUSED);
textComp.getDocument().addDocumentListener(documentListener);
}else
textComp.registerKeyboardAction(showAction, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
textComp.registerKeyboardAction(upAction, KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), JComponent.WHEN_FOCUSED);
textComp.registerKeyboardAction(hidePopupAction, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED);
popup.addPopupMenuListener(new PopupMenuListener(){
public void popupMenuWillBecomeVisible(PopupMenuEvent e){
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e){
textComp.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
}
public void popupMenuCanceled(PopupMenuEvent e){
}
});
list.setRequestFocusEnabled(false);
}
static Action acceptAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
JComponent tf = (JComponent)e.getSource();
AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER);
completer.popup.setVisible(false);
completer.acceptedListItem((String)completer.list.getSelectedValue());
}
};
DocumentListener documentListener = new DocumentListener(){
public void insertUpdate(DocumentEvent e){
showPopup();
}
public void removeUpdate(DocumentEvent e){
showPopup();
}
public void changedUpdate(DocumentEvent e){}
};
private void showPopup(){
popup.setVisible(false);
if(textComp.isEnabled() && updateListData() && list.getModel().getSize()!=0){
if(!(textComp instanceof JTextField))
textComp.getDocument().addDocumentListener(documentListener);
textComp.registerKeyboardAction(acceptAction, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED);
int size = list.getModel().getSize();
list.setVisibleRowCount(size<10 ? size : 10);
int x = 0;
try{
int pos = Math.min(textComp.getCaret().getDot(), textComp.getCaret().getMark());
x = textComp.getUI().modelToView(textComp, pos).x;
} catch(BadLocationException e){
// this should never happen!!!
e.printStackTrace();
}
popup.show(textComp, x, textComp.getHeight());
}else
popup.setVisible(false);
textComp.requestFocus();
}
static Action showAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
JComponent tf = (JComponent)e.getSource();
AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER);
if(tf.isEnabled()){
if(completer.popup.isVisible())
completer.selectNextPossibleValue();
else
completer.showPopup();
}
}
};
static Action upAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
JComponent tf = (JComponent)e.getSource();
AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER);
if(tf.isEnabled()){
if(completer.popup.isVisible())
completer.selectPreviousPossibleValue();
}
}
};
static Action hidePopupAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
JComponent tf = (JComponent)e.getSource();
AutoCompleter completer = (AutoCompleter)tf.getClientProperty(AUTOCOMPLETER);
if(tf.isEnabled())
completer.popup.setVisible(false);
}
};
/**
* Selects the next item in the list. It won't change the selection if the
* currently selected item is already the last item.
*/
protected void selectNextPossibleValue(){
int si = list.getSelectedIndex();
if(si < list.getModel().getSize() - 1){
list.setSelectedIndex(si + 1);
list.ensureIndexIsVisible(si + 1);
}
}
/**
* Selects the previous item in the list. It won't change the selection if the
* currently selected item is already the first item.
*/
protected void selectPreviousPossibleValue(){
int si = list.getSelectedIndex();
if(si > 0){
list.setSelectedIndex(si - 1);
list.ensureIndexIsVisible(si - 1);
}
}
// update list model depending on the data in textfield
protected abstract boolean updateListData();
// user has selected some item in the list. update textfield accordingly...
protected abstract void acceptedListItem(String selected);
}
http://www.jroller.com/page/santhosh/20050620#file_path_autocompletion顺便推荐给楼主