TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
支持自动过滤的 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;
-
- /**
- * 创建一个JFilterComboBox,
- * 其项取自现有的ComboBoxModel。
- * 由于提供了ComboBoxModel,
- * 使用此构造方法创建的组合框不创建默认组合框模型,
- * 这可能影响插入、移除和添加方法的行为方式。
- * @param aModel - 提供显示的项列表的 ComboBoxModel
- */
- public JFilterComboBox(ComboBoxModel aModel) {
- super(aModel);
- initialize();
- }
-
- /**
- * 创建包含指定数组中的元素的 JFilterComboBox。
- * 默认情况下,选择数组中的第一项(因而也选择了该项的数据模型)。
- * @param items - 要插入到组合框的对象数组
- */
- public JFilterComboBox(final Object items[]) {
- super(items);
- initialize();
- }
-
- /**
- * 创建包含指定 Vector 中的元素的 JFilterComboBox。
- * 默认情况下,选择数组中的第一项(因而也选择了该项的数据模型)。
- * @param items - 要插入到组合框的向量数组
- */
- public JFilterComboBox(Vector< ?> items) {
- super(items);
- initialize();
- }
-
- /**
- * 创建具有默认数据模型的 JFilterComboBox。
- * 默认的数据模型为空对象列表。使用 addItem 添加项。
- * 默认情况下,选择数据模型中的第一项。
- */
- 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("ab");
- data.add("ac");
- data.add("bb");
- data.add("cc");
- 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);
- }
-
- }
复制代码
源码下载:http://file.javaxxz.com/2014/11/17/235744296.zip |
|