swing实现类似百度过滤文本框

来源:互联网 发布:linux shell实例 编辑:程序博客网 时间:2024/04/29 11:48

//自定义过滤文本框

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class FilterTextField extends JTextField {

    private static final long serialVersionUID = 1L;
    private Vector<Object> allData;

    private Vector<Object> currentData;
    JPopupMenu menu;
    JList list;

    private boolean shouldFilter = true;

    public FilterTextField(Vector<Object> allData) {
        super();
        this.allData = allData;
        currentData = new Vector<Object>(allData);       
        initComponents();
        addKeyListener(keyListener);
       
        getDocument().addDocumentListener(documentListener);
    }

    private void initComponents() {
        menu = new JPopupMenu();
        menu.setInvoker(this);
        menu.setInheritsPopupMenu(true);
        menu.setLightWeightPopupEnabled(true);

        list = new JList();
        list.setFixedCellHeight(20);
        list.setVisibleRowCount(5);
        list.setModel(new ImitateListModel());
        list.addMouseListener(listMouseListener);
        menu.add(new JScrollPane(list));
        //menu.setPreferredSize(new Dimension(200,200));
    }

    private class ImitateListModel extends DefaultListModel {
        private static final long serialVersionUID = 1L;

        @Override
        public int getSize() {
            return currentData.size();
        }

        @Override
        public Object getElementAt(int index) {
            return currentData.get(index);
        }
    }

    private void filterValues(String filterStr) {
        currentData.clear();
        if (filterStr == null || "".equals(filterStr)) {
            currentData.addAll(allData);

        } else {

            for (Iterator<Object> it = allData.iterator(); it.hasNext();) {
                Object obj = it.next();
                String sValue = obj == null ? "" : obj.toString();
                if (sValue.toUpperCase().startsWith(filterStr.toUpperCase())) {
                    currentData.add(obj);
                }
            }
        }
        list.setModel(new ImitateListModel());
        list.setSelectedIndex(-1);
        showPopup();
    }

    private void showPopup() {
        Rectangle bounds = getBounds();
        Point location = getLocationOnScreen();

        menu.setPopupSize(bounds.width, list.getFixedCellHeight()
                * list.getVisibleRowCount());
        menu.setLocation(location.x, location.y + bounds.height);

        menu.setVisible(true);
        requestFocus();
    }

    private DocumentListener documentListener = new DocumentListener() {

        public void removeUpdate(DocumentEvent e) {
            if (shouldFilter) {
                String text = getText();
                filterValues(text);
            }

        }

        public void insertUpdate(DocumentEvent e) {
            if (shouldFilter) {
                String text = getText();
                filterValues(text);
            }

        }

        public void changedUpdate(DocumentEvent e) {

        }
    };

    private KeyListener keyListener = new KeyListener() {

        public void keyTyped(KeyEvent e) {
        }

        public void keyReleased(KeyEvent e) {

        }

        public void keyPressed(KeyEvent e) {
            String text = getText();
            if (e.getKeyCode() == KeyEvent.VK_UP) {
                shouldFilter = false;
                if (!menu.isVisible()) {
                    filterValues(text);
                } else {
                    int index = list.getSelectedIndex();
                    index--;
                    index = index < 0 ? list.getModel().getSize() - 1 : index;

                    list.setSelectedIndex(index);
                    Object obj = list.getModel().getElementAt(index);
                    setText(obj == null ? "" : obj.toString());
                }

                shouldFilter = true;

            } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                shouldFilter = false;
                if (!menu.isVisible()) {
                    filterValues(text);
                } else {
                    int index = list.getSelectedIndex();
                    index++;
                    index = index >= list.getModel().getSize() - 1 ? 0 : index;

                    list.setSelectedIndex(index);
                    Object obj = list.getModel().getElementAt(index);
                    setText(obj == null ? "" : obj.toString());
                }

                shouldFilter = true;
            } else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                shouldFilter = false;
                if (!menu.isVisible()) {
                    filterValues(text);
                } else {
                    int index = list.getSelectedIndex();
                    if (index < 0) {
                        return;
                    }

                    Object obj = list.getModel().getElementAt(index);
                    setText(obj == null ? "" : obj.toString());
                    menu.setVisible(false);
                }

                shouldFilter = true;
            }

        }
    };

    private MouseAdapter listMouseListener = new MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent e) {
            int index = list.getSelectedIndex();
            Object obj = list.getModel().getElementAt(index);
            setText(obj == null ? "" : obj.toString());
            menu.setVisible(false);
        }
    };
}

 

 

//测试窗口


import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Arrays;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class TestFrame extends JFrame {
    private static final long serialVersionUID = 1L;
    private String[] values = new String[] { "ab", "ac", "ad", "bc", "bd", "cc" };

    public TestFrame() {
        super();
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        installComponents();
        setSize(600, 400);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void installComponents() {
        Container c = getContentPane();
        c.setLayout(new BorderLayout());
        JPanel pnl =new JPanel(new FlowLayout(FlowLayout.LEFT));
        JTextField txt=new FilterTextField(new Vector<Object>(Arrays.asList(values)));
        txt.setPreferredSize(new Dimension(200,20));
        pnl.add(txt);
        c.add(pnl, BorderLayout.NORTH);
        c.add(new JLabel("111111111111111111111111111111"));

    }

    public static void main(String[] args) {
        new TestFrame();
    }
}

 

原创粉丝点击