Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 710|回复: 0

[Swing学习]支持自动过滤的JComboBox(JAVA)

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-17 23:57:44 | 显示全部楼层 |阅读模式
    支持自动过滤的 JComboBox , 根据输入内容过滤可选项,支持键盘和鼠标的选择.
    1. import java.awt.Component;  
    2. import java.awt.event.FocusEvent;  
    3. import java.awt.event.FocusListener;  
    4. import java.awt.event.ItemEvent;  
    5. import java.awt.event.KeyEvent;  
    6. import java.awt.event.KeyListener;  
    7. import java.awt.event.MouseEvent;  
    8. import java.awt.event.MouseListener;  
    9. import java.util.Vector;  
    10.   
    11. import javax.swing.ComboBoxModel;  
    12. import javax.swing.DefaultComboBoxModel;  
    13. import javax.swing.JComboBox;  
    14. import javax.swing.JComponent;  
    15. import javax.swing.JFrame;  
    16. import javax.swing.JList;  
    17. import javax.swing.JPanel;  
    18. import javax.swing.ListCellRenderer;  
    19. import javax.swing.SwingUtilities;  
    20. import javax.swing.event.ListDataEvent;  
    21. import javax.swing.plaf.basic.BasicComboPopup;  
    22. import javax.swing.plaf.basic.ComboPopup;  
    23. import javax.swing.plaf.metal.MetalComboBoxUI;  
    24.   
    25. /**
    26. * 自动过滤下拉框
    27. * @author Sun
    28. *
    29. */  
    30. @SuppressWarnings("serial")  
    31. public class JFilterComboBox extends JComboBox {  
    32.       
    33.     /**
    34.      * 显示用模型
    35.      */  
    36.     protected static DefaultComboBoxModel showModel = new DefaultComboBoxModel();  
    37.     /**
    38.      * 正在选择
    39.      */  
    40.     private boolean selectingItem;  
    41.       
    42.     /**
    43.      * 创建一个JFilterComboBox,
    44.      * 其项取自现有的ComboBoxModel。
    45.      * 由于提供了ComboBoxModel,
    46.      * 使用此构造方法创建的组合框不创建默认组合框模型,
    47.      * 这可能影响插入、移除和添加方法的行为方式。
    48.      * @param aModel - 提供显示的项列表的 ComboBoxModel
    49.      */  
    50.     public JFilterComboBox(ComboBoxModel aModel) {  
    51.         super(aModel);  
    52.         initialize();  
    53.     }  
    54.   
    55.     /**
    56.      * 创建包含指定数组中的元素的 JFilterComboBox。
    57.      * 默认情况下,选择数组中的第一项(因而也选择了该项的数据模型)。  
    58.      * @param items - 要插入到组合框的对象数组
    59.      */  
    60.     public JFilterComboBox(final Object items[]) {  
    61.         super(items);  
    62.         initialize();  
    63.     }  
    64.       
    65.     /**
    66.      *  创建包含指定 Vector 中的元素的 JFilterComboBox。
    67.      * 默认情况下,选择数组中的第一项(因而也选择了该项的数据模型)。  
    68.      * @param items - 要插入到组合框的向量数组
    69.      */  
    70.     public JFilterComboBox(Vector< ?> items) {  
    71.         super(items);  
    72.         initialize();  
    73.     }  
    74.       
    75.     /**
    76.      * 创建具有默认数据模型的 JFilterComboBox。
    77.      * 默认的数据模型为空对象列表。使用 addItem 添加项。
    78.      * 默认情况下,选择数据模型中的第一项。
    79.      */  
    80.     public JFilterComboBox() {  
    81.         super();  
    82.         initialize();  
    83.     }  
    84.       
    85.     private void initialize() {  
    86.         showModel.addListDataListener(this);  
    87.     }  
    88.       
    89.     @Override  
    90.     public void updateUI() {  
    91.         setUI(new MetalFilterComboBoxUI());  
    92.         ListCellRenderer renderer = getRenderer();  
    93.         if (renderer instanceof Component) {  
    94.             SwingUtilities.updateComponentTreeUI((Component) renderer);  
    95.         }  
    96.     }  
    97.       
    98.     @Override  
    99.     public Object getSelectedItem() {  
    100.         return showModel.getSelectedItem();  
    101.     }  
    102.   
    103.     @Override  
    104.     public void setSelectedItem(Object anObject) {  
    105.         Object oldSelection = selectedItemReminder;  
    106.         Object objectToSelect = anObject;  
    107.         if (oldSelection == null || !oldSelection.equals(anObject)) {  
    108.   
    109.             if (anObject != null && !isEditable()) {  
    110.                 boolean found = false;  
    111.                 for (int i = 0; i < showModel.getSize(); i++) {  
    112.                     Object element = showModel.getElementAt(i);  
    113.                     if (anObject.equals(element)) {  
    114.                         found = true;  
    115.                         objectToSelect = element;  
    116.                         break;  
    117.                     }  
    118.                 }  
    119.                 if (!found) {  
    120.                     return;  
    121.                 }  
    122.             }  
    123.   
    124.             selectingItem = true;  
    125.             showModel.setSelectedItem(objectToSelect);  
    126.             selectingItem = false;  
    127.   
    128.             if (selectedItemReminder != showModel.getSelectedItem()) {  
    129.                 selectedItemChanged();  
    130.             }  
    131.         }  
    132.         fireActionEvent();  
    133.     }  
    134.   
    135.     @Override  
    136.     public void setSelectedIndex(int anIndex) {  
    137.         int size = showModel.getSize();  
    138.         if (anIndex == -1 || size == 0) {  
    139.             setSelectedItem(null);  
    140.         } else if (anIndex < -1) {  
    141.             throw new IllegalArgumentException("setSelectedIndex: " + anIndex  
    142.                     + " out of bounds");  
    143.         } else if (anIndex >= size) {  
    144.             setSelectedItem(showModel.getElementAt(size - 1));  
    145.         } else {  
    146.             setSelectedItem(showModel.getElementAt(anIndex));  
    147.         }  
    148.     }  
    149.   
    150.     @Override  
    151.     public int getSelectedIndex() {  
    152.         Object sObject = showModel.getSelectedItem();  
    153.         int i, c;  
    154.         Object obj;  
    155.   
    156.         for (i = 0, c = showModel.getSize(); i < c; i++) {  
    157.             obj = showModel.getElementAt(i);  
    158.             if (obj != null && obj.equals(sObject))  
    159.                 return i;  
    160.         }  
    161.         return -1;  
    162.     }  
    163.   
    164.     @Override  
    165.     public void contentsChanged(ListDataEvent e) {  
    166.         Object oldSelection = selectedItemReminder;  
    167.         Object newSelection = showModel.getSelectedItem();  
    168.         if (oldSelection == null || !oldSelection.equals(newSelection)) {  
    169.             selectedItemChanged();  
    170.             if (!selectingItem) {  
    171.                 fireActionEvent();  
    172.             }  
    173.         }  
    174.     }  
    175.   
    176.     @Override  
    177.     protected void selectedItemChanged() {  
    178.         if (selectedItemReminder != null) {  
    179.             fireItemStateChanged(new ItemEvent(this,  
    180.                     ItemEvent.ITEM_STATE_CHANGED, selectedItemReminder,  
    181.                     ItemEvent.DESELECTED));  
    182.         }  
    183.   
    184.         selectedItemReminder = showModel.getSelectedItem();  
    185.   
    186.         if (selectedItemReminder != null) {  
    187.             fireItemStateChanged(new ItemEvent(this,  
    188.                     ItemEvent.ITEM_STATE_CHANGED, selectedItemReminder,  
    189.                     ItemEvent.SELECTED));  
    190.         }  
    191.     }  
    192.   
    193.     @Override  
    194.     public void intervalAdded(ListDataEvent e) {  
    195.         if (selectedItemReminder != showModel.getSelectedItem()) {  
    196.             selectedItemChanged();  
    197.         }  
    198.     }  
    199.   
    200.     @Override  
    201.     public void setEditable(boolean aFlag) {  
    202.         super.setEditable(true);  
    203.     }  
    204.   
    205.     /**
    206.      * 返回显示用模型
    207.      * @return
    208.      */  
    209.     public DefaultComboBoxModel getShowModel() {  
    210.         return showModel;  
    211.     }  
    212.       
    213.     /**
    214.      * Metal L&F 风格的 UI 类
    215.      * @author Sun
    216.      *
    217.      */  
    218.     class MetalFilterComboBoxUI extends MetalComboBoxUI {  
    219.          
    220.         /**
    221.          * 编辑区事件监听器
    222.          */  
    223.         protected EditorListener editorListener;  
    224.         /**
    225.          * 该 UI 类负责绘制的控件
    226.          */  
    227.         protected JFilterComboBox filterComboBox;  
    228.   
    229.         @Override  
    230.         public void installUI(JComponent c) {  
    231.             filterComboBox = (JFilterComboBox) c;  
    232.             filterComboBox.setEditable(true);  
    233.             super.installUI(c);  
    234.         }  
    235.   
    236.         @Override  
    237.         public void configureEditor() {  
    238.             super.configureEditor();  
    239.             editor.addKeyListener(getEditorListener());  
    240.             editor.addMouseListener(getEditorListener());  
    241.             editor.addFocusListener(getEditorListener());  
    242.         }  
    243.          
    244.         @Override  
    245.         public void unconfigureEditor() {  
    246.             super.unconfigureEditor();  
    247.             if (editorListener != null) {  
    248.                 editor.removeKeyListener(editorListener);  
    249.                 editor.removeMouseListener(editorListener);  
    250.                 editor.removeFocusListener(editorListener);  
    251.                 editorListener = null;  
    252.             }  
    253.         }  
    254.          
    255.         @Override  
    256.         protected ComboPopup createPopup() {  
    257.             return new FilterComboPopup(filterComboBox);  
    258.         }  
    259.          
    260.         /**
    261.          * 初始化并返回编辑区事件监听器
    262.          * @return
    263.          */  
    264.         protected EditorListener getEditorListener() {  
    265.             if (editorListener == null) {  
    266.                 editorListener = new EditorListener();  
    267.             }  
    268.             return editorListener;  
    269.         }  
    270.   
    271.         /**
    272.          * 按关键字进行查询,该方法中,可以自行加入各种查询算法
    273.          */  
    274.         protected void findMatchs() {  
    275.             ComboBoxModel model = filterComboBox.getModel();  
    276.             DefaultComboBoxModel showModel = filterComboBox.getShowModel();  
    277.             showModel.removeAllElements();  
    278.             for (int i = 0; i < model.getSize(); i++) {  
    279.                 String name = model.getElementAt(i).toString();  
    280.                 if (name.indexOf(getEditorText()) >= 0) {  
    281.                     showModel.addElement(model.getElementAt(i));  
    282.                 }  
    283.             }  
    284.             ((FilterComboPopup)popup ).repaint();  
    285.         }  
    286.          
    287.         /**
    288.          * 返回编辑区文本
    289.          * @return
    290.          */  
    291.         private String getEditorText() {  
    292.             return filterComboBox.getEditor().getItem().toString();  
    293.         }  
    294.          
    295.         /**
    296.          * 弹出面板类
    297.          * @author Sun
    298.          *
    299.          */  
    300.         class FilterComboPopup extends BasicComboPopup {  
    301.   
    302.             public FilterComboPopup(JComboBox combo) {  
    303.                 super(combo);  
    304.             }  
    305.               
    306.             @Override  
    307.             protected JList createList() {  
    308.                 JList list = super.createList();  
    309.                 list.setModel(filterComboBox.getShowModel());  
    310.                 return list;  
    311.             }  
    312.               
    313.             @Override  
    314.             public void setVisible(boolean b) {  
    315.                 super.setVisible(b);  
    316.                 if (!b) {  
    317.                     comboBox.getEditor().setItem(comboBox.getSelectedItem());  
    318.                 }  
    319.             }  
    320.               
    321.             @Override  
    322.             public void show() {  
    323.                 findMatchs();  
    324.                 super.show();  
    325.             }  
    326.   
    327.         }  
    328.          
    329.         /**
    330.          * 编辑区事件监听器类
    331.          * @author Sun
    332.          *
    333.          */  
    334.         class EditorListener implements KeyListener,MouseListener, FocusListener {  
    335.               
    336.             /**
    337.              * 旧文本,用于键盘输入时的比对
    338.              */  
    339.             private String oldText = "";  
    340.               
    341.             @Override  
    342.             public void keyReleased(KeyEvent e) {  
    343.                 String newText = getEditorText();  
    344.                 if (!newText.equals(oldText)) {  
    345.                     findMatchs();  
    346.                 }  
    347.             }  
    348.               
    349.             @Override  
    350.             public void keyPressed(KeyEvent e) {  
    351.                 oldText = getEditorText();  
    352.                 if (!isPopupVisible(filterComboBox)) {  
    353.                     setPopupVisible(filterComboBox, true);  
    354.                 }  
    355.             }  
    356.   
    357.             @Override  
    358.             public void keyTyped(KeyEvent e) {  
    359.                 findMatchs();  
    360.             }  
    361.   
    362.             @Override  
    363.             public void mouseClicked(MouseEvent e) {}  
    364.   
    365.             @Override  
    366.             public void mousePressed(MouseEvent e) {  
    367.                 if (!isPopupVisible(filterComboBox)) {  
    368.                     setPopupVisible(filterComboBox, true);  
    369.                 }  
    370.             }  
    371.   
    372.             @Override  
    373.             public void mouseReleased(MouseEvent e) {}  
    374.   
    375.             @Override  
    376.             public void mouseEntered(MouseEvent e) {}  
    377.   
    378.             @Override  
    379.             public void mouseExited(MouseEvent e) {}  
    380.               
    381.             @Override  
    382.             public void focusGained(FocusEvent e) {  
    383.                 if (!isPopupVisible(filterComboBox)) {  
    384.                     setPopupVisible(filterComboBox, true);  
    385.                 }  
    386.             }  
    387.               
    388.             @Override  
    389.             public void focusLost(FocusEvent e) {}  
    390.   
    391.         }  
    392.   
    393.     }  
    394.       
    395.     /**
    396.      * 使用示例
    397.      * @param args
    398.      */  
    399.     public static void main(String... args) {  
    400.         Vector< String> data = new Vector< String>(0);  
    401.         data.add("ab");  
    402.         data.add("ac");  
    403.         data.add("bb");  
    404.         data.add("cc");  
    405.         JPanel panel = new JPanel();  
    406.         panel.add(new JFilterComboBox(data));  
    407.         JFrame frame = new JFrame();  
    408.         frame.setSize(400, 300);  
    409.         frame.setLocationRelativeTo(null);  
    410.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    411.         frame.setContentPane(panel);  
    412.         frame.setVisible(true);  
    413.     }  
    414.   
    415. }  
    复制代码


       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/17/235744296.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 07:26 , Processed in 0.352968 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表