JCombobox过滤文本

 

 
import java.awt.Component;  
import java.awt.event.FocusEvent;  
import java.awt.event.FocusListener;  
import java.awt.event.ItemEvent;  
import java.awt.event.KeyEvent;  
import java.awt.event.KeyListener;  
import java.awt.event.MouseEvent;  
import java.awt.event.MouseListener;  
import java.util.Vector;  
  
import javax.swing.ComboBoxModel;  
import javax.swing.DefaultComboBoxModel;  
import javax.swing.JComboBox;  
import javax.swing.JComponent;  
import javax.swing.JFrame;  
import javax.swing.JList;  
import javax.swing.JPanel;  
import javax.swing.ListCellRenderer;  
import javax.swing.SwingUtilities;  
import javax.swing.event.ListDataEvent;  
import javax.swing.plaf.basic.BasicComboPopup;  
import javax.swing.plaf.basic.ComboPopup;  
import javax.swing.plaf.metal.MetalComboBoxUI;  
  
/** 
 * 自动过滤下拉框 
 * @author Sun 
 * 
 */  
@SuppressWarnings("serial")  
public class JFilterComboBox extends JComboBox {  
      
    /** 
     * 显示用模型 
     */  
    protected static DefaultComboBoxModel showModel = new DefaultComboBoxModel();  
    /** 
     * 正在选择 
     */  
    private boolean selectingItem;  
      
    /** 
     * 创建一个 <code>JFilterComboBox</code>, 
     * 其项取自现有的 <code>ComboBoxModel</code>。 
     * 由于提供了 <code>ComboBoxModel</code>, 
     * 使用此构造方法创建的组合框不创建默认组合框模型, 
     * 这可能影响插入、移除和添加方法的行为方式。 
     * @param aModel - 提供显示的项列表的 <code>ComboBoxModel</code> 
     */  
    public JFilterComboBox(ComboBoxModel aModel) {  
        super(aModel);  
        initialize();  
    }  
  
    /** 
     * 创建包含指定数组中的元素的 <code>JFilterComboBox</code>。 
     * 默认情况下,选择数组中的第一项(因而也选择了该项的数据模型)。  
     * @param items - 要插入到组合框的对象数组 
     */  
    public JFilterComboBox(final Object items[]) {  
        super(items);  
        initialize();  
    }  
      
    /** 
     * 创建包含指定 <code>Vector</code> 中的元素的 <code>JFilterComboBox</code>。 
     * 默认情况下,选择数组中的第一项(因而也选择了该项的数据模型)。  
     * @param items - 要插入到组合框的向量数组 
     */  
    public JFilterComboBox(Vector<?> items) {  
        super(items);  
        initialize();  
    }  
      
    /** 
     * 创建具有默认数据模型的 <code>JFilterComboBox</code>。 
     * 默认的数据模型为空对象列表。使用 <code>addItem</code> 添加项。 
     * 默认情况下,选择数据模型中的第一项。 
     */  
    public JFilterComboBox() {  
        super();  
        initialize();  
    }  
      
    private void initialize() {  
        showModel.addListDataListener(this);  
    }  
      
    @Override  
    public void updateUI() {  
        setUI(new MetalFilterComboBoxUI());  
        ListCellRenderer renderer = getRenderer();  
        if (renderer instanceof Component) {  
            SwingUtilities.updateComponentTreeUI((Component) renderer);  
        }  
    }  
      
    @Override  
    public Object getSelectedItem() {  
        return showModel.getSelectedItem();  
    }  
  
    @Override  
    public void setSelectedItem(Object anObject) {  
        Object oldSelection = selectedItemReminder;  
        Object objectToSelect = anObject;  
        if (oldSelection == null || !oldSelection.equals(anObject)) {  
  
            if (anObject != null && !isEditable()) {  
                boolean found = false;  
                for (int i = 0; i < showModel.getSize(); i++) {  
                    Object element = showModel.getElementAt(i);  
                    if (anObject.equals(element)) {  
                        found = true;  
                        objectToSelect = element;  
                        break;  
                    }  
                }  
                if (!found) {  
                    return;  
                }  
            }  
  
            selectingItem = true;  
            showModel.setSelectedItem(objectToSelect);  
            selectingItem = false;  
  
            if (selectedItemReminder != showModel.getSelectedItem()) {  
                selectedItemChanged();  
            }  
        }  
        fireActionEvent();  
    }  
  
    @Override  
    public void setSelectedIndex(int anIndex) {  
        int size = showModel.getSize();  
        if (anIndex == -1 || size == 0) {  
            setSelectedItem(null);  
        } else if (anIndex < -1) {  
            throw new IllegalArgumentException("setSelectedIndex: " + anIndex  
                    + " out of bounds");  
        } else if (anIndex >= size) {  
            setSelectedItem(showModel.getElementAt(size - 1));  
        } else {  
            setSelectedItem(showModel.getElementAt(anIndex));  
        }  
    }  
  
    @Override  
    public int getSelectedIndex() {  
        Object sObject = showModel.getSelectedItem();  
        int i, c;  
        Object obj;  
  
        for (i = 0, c = showModel.getSize(); i < c; i++) {  
            obj = showModel.getElementAt(i);  
            if (obj != null && obj.equals(sObject))  
                return i;  
        }  
        return -1;  
    }  
  
    @Override  
    public void contentsChanged(ListDataEvent e) {  
        Object oldSelection = selectedItemReminder;  
        Object newSelection = showModel.getSelectedItem();  
        if (oldSelection == null || !oldSelection.equals(newSelection)) {  
            selectedItemChanged();  
            if (!selectingItem) {  
                fireActionEvent();  
            }  
        }  
    }  
  
    @Override  
    protected void selectedItemChanged() {  
        if (selectedItemReminder != null) {  
            fireItemStateChanged(new ItemEvent(this,  
                    ItemEvent.ITEM_STATE_CHANGED, selectedItemReminder,  
                    ItemEvent.DESELECTED));  
        }  
  
        selectedItemReminder = showModel.getSelectedItem();  
  
        if (selectedItemReminder != null) {  
            fireItemStateChanged(new ItemEvent(this,  
                    ItemEvent.ITEM_STATE_CHANGED, selectedItemReminder,  
                    ItemEvent.SELECTED));  
        }  
    }  
  
    @Override  
    public void intervalAdded(ListDataEvent e) {  
        if (selectedItemReminder != showModel.getSelectedItem()) {  
            selectedItemChanged();  
        }  
    }  
  
    @Override  
    public void setEditable(boolean aFlag) {  
        super.setEditable(true);  
    }  
  
    /** 
     * 返回显示用模型 
     * @return 
     */  
    public DefaultComboBoxModel getShowModel() {  
        return showModel;  
    }  
      
    /** 
     * Metal L&F 风格的 UI 类 
     * @author Sun 
     * 
     */  
    class MetalFilterComboBoxUI extends MetalComboBoxUI {  
          
        /** 
         * 编辑区事件监听器 
         */  
        protected EditorListener editorListener;  
        /** 
         * 该 UI 类负责绘制的控件 
         */  
        protected JFilterComboBox filterComboBox;  
  
        @Override  
        public void installUI(JComponent c) {  
            filterComboBox = (JFilterComboBox) c;  
            filterComboBox.setEditable(true);  
            super.installUI(c);  
        }  
  
        @Override  
        public void configureEditor() {  
            super.configureEditor();  
            editor.addKeyListener(getEditorListener());  
            editor.addMouseListener(getEditorListener());  
            editor.addFocusListener(getEditorListener());  
        }  
          
        @Override  
        public void unconfigureEditor() {  
            super.unconfigureEditor();  
            if (editorListener != null) {  
                editor.removeKeyListener(editorListener);  
                editor.removeMouseListener(editorListener);  
                editor.removeFocusListener(editorListener);  
                editorListener = null;  
            }  
        }  
          
        @Override  
        protected ComboPopup createPopup() {  
            return new FilterComboPopup(filterComboBox);  
        }  
          
        /** 
         * 初始化并返回编辑区事件监听器 
         * @return 
         */  
        protected EditorListener getEditorListener() {  
            if (editorListener == null) {  
                editorListener = new EditorListener();  
            }  
            return editorListener;  
        }  
  
        /** 
         * 按关键字进行查询,该方法中,可以自行加入各种查询算法 
         */  
        protected void findMatchs() {  
            ComboBoxModel model = filterComboBox.getModel();  
            DefaultComboBoxModel showModel = filterComboBox.getShowModel();  
            showModel.removeAllElements();  
            for (int i = 0; i < model.getSize(); i++) {  
                String name = model.getElementAt(i).toString();  
                if (name.indexOf(getEditorText()) >= 0) {  
                    showModel.addElement(model.getElementAt(i));  
                }  
            }  
            ((FilterComboPopup)popup ).repaint();  
        }  
          
        /** 
         * 返回编辑区文本 
         * @return 
         */  
        private String getEditorText() {  
            return filterComboBox.getEditor().getItem().toString();  
        }  
          
        /** 
         * 弹出面板类 
         * @author Sun 
         * 
         */  
        class FilterComboPopup extends BasicComboPopup {  
  
            public FilterComboPopup(JComboBox combo) {  
                super(combo);  
            }  
              
            @Override  
            protected JList createList() {  
                JList list = super.createList();  
                list.setModel(filterComboBox.getShowModel());  
                return list;  
            }  
              
            @Override  
            public void setVisible(boolean b) {  
                super.setVisible(b);  
                if (!b) {  
                    comboBox.getEditor().setItem(comboBox.getSelectedItem());  
                }  
            }  
              
            @Override  
            public void show() {  
                findMatchs();  
                super.show();  
            }  
  
        }  
          
        /** 
         * 编辑区事件监听器类 
         * @author Sun 
         * 
         */  
        class EditorListener implements KeyListener,MouseListener, FocusListener {  
              
            /** 
             * 旧文本,用于键盘输入时的比对 
             */  
            private String oldText = "";  
              
            @Override  
            public void keyReleased(KeyEvent e) {  
                String newText = getEditorText();  
                if (!newText.equals(oldText)) {  
                    findMatchs();  
                }  
            }  
              
            @Override  
            public void keyPressed(KeyEvent e) {  
                oldText = getEditorText();  
                if (!isPopupVisible(filterComboBox)) {  
                    setPopupVisible(filterComboBox, true);  
                }  
            }  
  
            @Override  
            public void keyTyped(KeyEvent e) {  
                findMatchs();  
            }  
  
            @Override  
            public void mouseClicked(MouseEvent e) {}  
  
            @Override  
            public void mousePressed(MouseEvent e) {  
                if (!isPopupVisible(filterComboBox)) {  
                    setPopupVisible(filterComboBox, true);  
                }  
            }  
  
            @Override  
            public void mouseReleased(MouseEvent e) {}  
  
            @Override  
            public void mouseEntered(MouseEvent e) {}  
  
            @Override  
            public void mouseExited(MouseEvent e) {}  
              
            @Override  
            public void focusGained(FocusEvent e) {  
                if (!isPopupVisible(filterComboBox)) {  
                    setPopupVisible(filterComboBox, true);  
                }  
            }  
              
            @Override  
            public void focusLost(FocusEvent e) {}  
  
        }  
  
    }  
      
    /** 
     * 使用示例 
     * @param args 
     */  
    public static void main(String... args) {  
        Vector<String> data = new Vector<String>(0);  
        data.add("Java");  
        data.add("C#");  
        data.add(".Net");  
        data.add("C++");

        JPanel panel = new JPanel();  
        panel.add(new JFilterComboBox(data));  
        JFrame frame = new JFrame();  
        frame.setSize(400, 300);  
        frame.setLocationRelativeTo(null);  
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        frame.setContentPane(panel);  
        frame.setVisible(true);  
    }  
  
} 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值