/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.impl.gui.customcontrols; import java.awt.*; import java.awt.event.*; import java.util.*; import java.util.List; import javax.swing.*; import javax.swing.event.*; import net.java.sip.communicator.impl.gui.lookandfeel.*; /** * SIPCommSmartComboBox is an editable combo box which selects an item * according to user input. * * @author Yana Stamcheva */ public class SIPCommSmartComboBox extends JComboBox { private ArrayList historyList = new ArrayList(); /** * Creates an instance of SIPCommSmartComboBox. */ public SIPCommSmartComboBox() { setModel(new FilterableComboBoxModel(historyList)); setEditor(new CallComboEditor()); setEditable(true); setFocusable(true); } /** * The data model used for this combo box. Filters the contents of the * combo box popup according to the user input. */ public class FilterableComboBoxModel extends AbstractListModel implements MutableComboBoxModel { private List items; private Filter filter; private List filteredItems; private Object selectedItem; public FilterableComboBoxModel(List items) { this.items = new ArrayList(items); filteredItems = new ArrayList(items.size()); updateFilteredItems(); } public boolean contains(Object obj) { return items.contains(obj); } public void addElement( Object obj ) { items.add(obj); updateFilteredItems(); } public void removeElement( Object obj ) { items.remove(obj); updateFilteredItems(); } public void removeElementAt(int index) { items.remove(index); updateFilteredItems(); } public void insertElementAt( Object obj, int index ) { items.add(index, obj); updateFilteredItems(); } public void setFilter(Filter filter) { this.filter = filter; updateFilteredItems(); } protected void updateFilteredItems() { fireIntervalRemoved(this, 0, filteredItems.size()); filteredItems.clear(); if (filter == null) filteredItems.addAll(items); else { for (Iterator iterator = items.iterator(); iterator.hasNext();) { Object item = iterator.next(); if (filter.accept(item)) filteredItems.add(item); } } fireIntervalAdded(this, 0, filteredItems.size()); } public int getSize() { return filteredItems.size(); } public Object getElementAt(int index) { return filteredItems.get(index); } public Object getSelectedItem() { return selectedItem; } public void setSelectedItem(Object val) { if ((selectedItem == null) && (val == null)) return; if ((selectedItem != null) && selectedItem.equals(val)) return; if ((val != null) && val.equals(selectedItem)) return; selectedItem = val; fireContentsChanged(this, -1, -1); } } public static interface Filter { public boolean accept(Object obj); } class StartsWithFilter implements Filter { private String prefix; public StartsWithFilter(String prefix) { this.prefix = prefix.toLowerCase(); } public boolean accept(Object o) { if(o != null) { String objectString = o.toString().toLowerCase(); return (objectString.indexOf(prefix) >= 0) ? true : false; } return false; } } public class CallComboEditor implements ComboBoxEditor, DocumentListener { private JTextField text; private volatile boolean filtering = false; private volatile boolean setting = false; public CallComboEditor() { text = new JTextField(15); text.getDocument().addDocumentListener(this); // Enable delete button from the UI. if (text.getUI() instanceof SIPCommTextFieldUI) { ((SIPCommTextFieldUI) text.getUI()) .setDeleteButtonEnabled(true); } } public Component getEditorComponent() { return text; } public void setItem(Object item) { if(filtering) return; setting = true; String newText = (item == null) ? "" : item.toString(); text.setText(newText); setting = false; } public Object getItem() { return text.getText(); } public void selectAll() { text.selectAll(); } public void addActionListener(ActionListener l) { text.addActionListener(l); } public void removeActionListener(ActionListener l) { text.removeActionListener(l); } public void insertUpdate(DocumentEvent e) { handleChange(); } public void removeUpdate(DocumentEvent e) { handleChange(); } public void changedUpdate(DocumentEvent e) { } protected void handleChange() { if (setting) return; filtering = true; Filter filter = null; if (text.getText().length() > 0) { filter = new StartsWithFilter(text.getText()); } ((FilterableComboBoxModel) getModel()).setFilter(filter); setPopupVisible(false); if(getModel().getSize() > 0) setPopupVisible(true); filtering = false; } } }