如何实现JCombobox的如下功能:
1:在JCombobox中编辑值时检索item,如:item中值为:ab,ac,bb,cc 我们输入a时:下拉框展示 ab ac两条数据  输入b时展示ab,bb
2:Jcombobox是在点击他时会弹出下拉列表,如何实现在编辑时自动弹出下拉列表。(其实1中就包含了2)。
先  谢谢各位帮忙。

解决方案 »

  1.   

    去swing hacks这本书里找吧,就有这个例子
      

  2.   

    昨天工作上需要,写了一个这样的控件
    你看下行不行
    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) {
    setSelectedItem(null);
    } else if (anIndex < -1) {
    throw new IllegalArgumentException("setSelectedIndex: " + anIndex
    + " out of bounds");
    } else if (anIndex >= size) {
    setSelectedItem(size - 1);
    } else {
    setSelectedItem(showModel.getElementAt(anIndex));
    }
    } @Override
    public void contentsChanged(ListDataEvent e) {
    Object oldSelection = selectedItemReminder;
    Object newSelection = showModel.getSelectedItem();
    if (oldSelection == null || !oldSelection.equals(newSelection)) {
    selectedItemChanged();
    if (!selectingItem) {
    fireActionEvent();
    }
    }
    } @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
    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);
    } protected void installDefaults() {
    super.installDefaults();
    }

    @Override
    protected void uninstallDefaults() {
    super.uninstallDefaults();
    }

    @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;
    } /**
     * 按关键字进行查询
     * @param text - 关键字
     */
    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 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);
    }
    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    int index = comboBox.getSelectedIndex();
    if (index >= 0) {
    comboBox.getEditor().setItem(comboBox.getSelectedItem());
    } else {
    comboBox.getEditor().setItem(null);
    }
    }
    } @Override
    public void keyTyped(KeyEvent e) {
    findMatchs();
    } @Override
    public void mouseClicked(MouseEvent e) {} @Override
    public void mousePressed(MouseEvent e) {
    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) {
    setPopupVisible(filterComboBox, true);
    }

    @Override
    public void focusLost(FocusEvent e) {} } }

    public static void main(String... args) {
    Vector<String> data = new Vector<String>(0);
    data.add("ab");
    data.add("ac");
    data.add("bb");
    data.add("cc");
    JPanel panel = new JPanel();
    JComboBox comboBox = new JFilterComboBox(data);
    // comboBox.setEditable(true);
    panel.add(comboBox);
    JFrame frame = new JFrame();
    frame.setSize(400, 300);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(panel);
    frame.setVisible(true);
    }}