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); } }
相关推荐
`JComboBox`是由`javax.swing.JComboBox`类定义的,它结合了下拉列表和文本输入框的功能。我们可以预先设定一些选项,用户可以选择这些选项,同时也可以在输入框中输入自定义的值。 下面是一个简单的`JComboBox`...
在`JComboBox`中实现关键字搜索,通常需要自定义`ComboBoxModel`或扩展`DefaultComboBoxModel`来支持过滤功能。`FilterableComboBox`这个名字暗示了我们可能有一个定制的`ComboBox`类,它增加了对关键词过滤的支持。...
自动搜寻功能通常是指当用户在`JComboBox`的文本输入框中开始输入时,组合框会自动过滤出与输入字符相匹配的选项,并突出显示或直接定位到第一个匹配项。这不仅节省了用户的输入时间,也提高了数据选择的准确性。 #...
在这个方法中,我们会根据当前输入的文本过滤出匹配的建议,并更新`JComboBox`的内容,同时显示下拉列表。 ```java txtInput.getDocument().addDocumentListener(new DocumentListener() { public void insert...
在实际应用中,`JCheckbox` 和 `JComboBox` 经常用于配置界面、设置选项或过滤数据等场景。了解它们的工作方式和如何有效利用事件处理,能帮助我们编写出更高效、用户友好的Java Swing应用程序。因此,深入学习和...
- 数据展示:JTable显示职位列表或求职者列表,支持排序和过滤功能。 此外,系统还可能涉及到数据库操作,如使用JDBC(Java Database Connectivity)连接MySQL或SQLite等数据库,存储和检索数据。为了实现事件监听...
6. JComboBox:下拉列表框,用户可以从预定义的选项中选择。 7. JList:显示一组可选择的项目,用户可以通过滚动或选择来操作。 8. JTable:用于展示二维数据的表格,支持排序、筛选等功能。 9. JScrollPane:滚动...
而在Java Swing或JavaFX中,可以使用`JComboBox`类并自定义其`ActionListener`和`Renderer`。 综上所述,实现“自动显示下拉列表框”涉及了用户输入监听、数据过滤、异步加载、匹配算法等多个方面。通过巧妙地结合...
- 文件选择和过滤器处理,如FileNameExtensionFilter用于限制保存文件的类型。 此Java记事本程序设计涵盖了Java GUI编程、文件I/O、事件处理、字符串操作等多个核心知识点,是学习和巩固Java编程技能的优秀实践...
1. **列表和组合框(Ch02-ListsAndCombos)**: 这一章主要探讨了如何定制JList和JComboBox组件,提供自定义的渲染器和编辑器,以及如何实现多选和分组功能,使用户界面更加友好和功能强大。 2. **文件选择器(Ch04-...
7. **Ch02-ListsAndCombos**:`JList`和`JComboBox`是常用的下拉选择组件,它们在数据选择和过滤场景中常见。掌握这两者的基本使用和高级特性,可以提升用户界面的交互性。 8. **Ch12-Miscellany**:这部分可能包含...
可以设置其最大字符数,文本过滤器等属性,也可以添加TextListener或DocumentListener来监听文本变化。 3. **复选框(JCheckBox)**:复选框允许用户在一组选项中选择多个选项。可以使用ItemListener或...
此外,为了提供更好的用户体验,可以添加搜索过滤器,只显示最相关的几个结果,例如按匹配度排序或者限制显示数量。 在实际应用中,还可以考虑一些进阶功能,比如联想词、上下文关联预测,以及用户自定义词汇库等。...
2. 纯文本文档:纯文本文档通常以`.txt`为扩展名,是一种最简单的文本格式,不含任何格式化信息,只包含基本的文本内容。 3. GROUP BY语句:在SQL中,GROUP BY用于将数据表中的数据按指定的一个或多个列进行分组,...
5. **搜索图书**: 搜索功能可能涉及文本输入和过滤。可以创建一个`JTextField`供用户输入关键词,监听其键入事件,实时更新显示的图书列表。`ArrayList`的`contains`方法或自定义的过滤器函数可以用来查找匹配的图书...
- 支持排序、过滤等功能。 7. **JComboBox**: - 用于提供下拉列表选项。 - 用户可以从列表中选择一项。 #### 四、事件处理的过程 1. **事件源**: - 触发事件的对象,如按钮、文本框等。 2. **事件**: - ...
在Swing中,我们通常会用到JFrame作为主窗口,JPanel作为容器来组织其他组件,JButton用于用户交互,JLabel显示文本或图标,JTable用于展示和操作数据,JComboBox和JTextField则用来输入和选择信息。此外,我们还会...
5. **JComboBox**或**JList**:在Swing中,`JComboBox`或`JList`可以用来展示字体列表,让用户进行选择。开发者可能创建了一个这些组件的实例,并填充了系统字体的名称。 6. **事件监听**:为了响应用户的字体选择...
- **JComboBox**:创建下拉列表,如选择联系人的类别。 - **JTable**:展示表格数据,用于显示联系人列表。 ### 五、事件处理 - **ActionListener**:为按钮添加事件监听器,实现点击按钮时触发的功能。 - **...
例如,`JFrame`用于创建窗口,`JPanel`作为容器组织其他组件,`JLabel`显示文本或图标,`JTextField`用于输入文本,`JComboBox`为下拉列表选择项,而`JButton`则处理用户交互事件。 2. **ActionListener接口**:`...