具有可过滤功能的JList组件【Swing】

2023-11-02 17:18

本文主要是介绍具有可过滤功能的JList组件【Swing】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【场景】:在一个列表中,可以通过输入某个字符,而动态过滤列表中项的显示。当然,动态显示的项都是包含用户输入的字符!在此,实现的功能非常简单,没有 更多的复杂逻辑。仅是为学习者提供一些案例。可以从中进行自己需要的扩展。
【关系图】:



在Swing中,想构建自己的组件,最简单的就是继承现有的组件,再做可定制的功能扩展,也不需要做太多额外的工作,因为Swing为我们提供了良好的可 扩展性。上图,简略的说明了待开发的可过滤的列表关系类图。以下做一些简单的描述:
【FilteredList】:继承了JList,其中类FilteredModel与FilteredTextField是他的内部类实现。在这里使用 内部类是为了能够方便的访问到FilteredList外部数据,减少了与外部类的交互,在此不能确定的说这种方式是好是坏,其中的衡量就留给用户了。
【FilteredModel】:继承了AbstractListModel,FilteredList中的内部类,并作为其的一个属性存在。作用是保存 展现在列表中的数据,并且能做动态更新。
【FilteredTextField】:继承了JTextFiled,很显然的就是一个输入框,只是实现了一个DocumentListener接口, 做到实时监听用户输入的任何动作:插入、删除、修改等。在用户触发这个监听时,就需要和FilteredModel进行交互,动态变化 FilteredList中的数据显示。

【编码实现】
FilteredModel
在这个Model中主要的是设置一个filteredItems 属性,用来保存包含了用户输入字符的列表项;另一个items属性,保存列表原始的所有项。关键的算法是方法refilter():实时对用户输入进行过 滤,并把结果添加到filteredItems 中。
private class FilterModel extends AbstractListModel {
private List items;
private List filteredItems;
public FilterModel() {
items = new ArrayList();
filteredItems = new ArrayList();
}

public void addElement(Object o) {//添加一个项到列表中
items.add(o);
refilter();//每添加一个项就更新filterItems
}

private void refilter() {
filteredItems.clear();
String item = getFilterField().getText();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).toString().toUpperCase().indexOf(item, 0) != -1
|| items.get(i).toString().toLowerCase().indexOf(item,
0) != -1) {
filteredItems.add(items.get(i));
}
}
fireContentsChanged(this, 0, filteredItems.size());
}

@Override
public Object getElementAt(int index) {
if (index < filteredItems.size()) {
return filteredItems.get(index);
}
return null;
}

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


【FilterField】
private class FilterField extends JTextField implements DocumentListener {
public FilterField(int width) {
super(width);
getDocument().addDocumentListener(this);
}

@Override
public void changedUpdate(DocumentEvent e) {
model.refilter();//更新列表的显示数据,下同
}

@Override
public void insertUpdate(DocumentEvent e) {
model.refilter();
}

@Override
public void removeUpdate(DocumentEvent e) {
model.refilter();
}
}

【FilteredList】
public class FilteredList extends JList {
private FilterModel model;

private FilterField filterField;

public FilteredList() {
model = new FilterModel();
setModel(model);
filterField = new FilterField(20);
}

public void addItem(Object o) {
model.addElement(o);
}

public FilterField getFilterField() {
return filterField;
}
}
可见,FilteredList 实现起来非常的简单,只需定义前面已经创建出来的组件作为其属性。并更换Model。 使用自己实现的具有可过滤功能的Model。
下面是一段测试代码:
public static void main(String[] args) {
String[] listItems = { "Chris", "Joshua", "Daniel", "Michael", "Don",
"Kimi", "Kelly", "Keagan" };
JFrame frame = new JFrame("FilteredJList");
frame.getContentPane().setLayout(new BorderLayout());
// populate list
FilteredHistoryList list = new FilteredHistoryList();
for (int i = 0; i < listItems.length; i++)
list.addItem(listItems[i]);
// add to gui
JScrollPane pane = new JScrollPane(list,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.getContentPane().add(list.getFilterField(), BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

【小结】
在这里实现的只是为一个JList附加了一层特定的功能,当然,我们不能停留在仅仅学会如何编写这功能的代码上,还要搞清楚内部如何实现,最终是为什么要 如此去做。
在这里,使用继承机制,接口实现等,都是利用类库成熟的组件类,如此就能复用很多特性。我们需要的是JList上加一层额外的功能,那么当然需要继承自 JList,使他俩具有血缘关系啦,方便管理吗!从这里也可以感受到Swing编码的一种感觉:数据与展示层划分清晰,展示与数据没有耦合在一块。当然, 可以说,在这个例子中没有做的很好,也没有作出具体的层次优化,读者可以自己试一试……

【参考资料】:《Swing Hacks》 By Chris Adamson , Joshua Marinacci

这篇关于具有可过滤功能的JList组件【Swing】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/332102

相关文章

springboot+redis实现订单过期(超时取消)功能的方法详解

《springboot+redis实现订单过期(超时取消)功能的方法详解》在SpringBoot中使用Redis实现订单过期(超时取消)功能,有多种成熟方案,本文为大家整理了几个详细方法,文中的示例代... 目录一、Redis键过期回调方案(推荐)1. 配置Redis监听器2. 监听键过期事件3. Redi

Qt实现对Word网页的读取功能

《Qt实现对Word网页的读取功能》文章介绍了几种在Qt中实现Word文档(.docx/.doc)读写功能的方法,包括基于QAxObject的COM接口调用、DOCX模板替换及跨平台解决方案,重点讨论... 目录1. 核心实现方式2. 基于QAxObject的COM接口调用(Windows专用)2.1 环境

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

java敏感词过滤的实现方式

《java敏感词过滤的实现方式》文章描述了如何搭建敏感词过滤系统来防御用户生成内容中的违规、广告或恶意言论,包括引入依赖、定义敏感词类、非敏感词类、替换词类和工具类等步骤,并指出资源文件应放在src/... 目录1.引入依赖2.定义自定义敏感词类3.定义自定义非敏感类4.定义自定义替换词类5.最后定义工具类

SpringBoot+Vue3整合SSE实现实时消息推送功能

《SpringBoot+Vue3整合SSE实现实时消息推送功能》在日常开发中,我们经常需要实现实时消息推送的功能,这篇文章将基于SpringBoot和Vue3来简单实现一个入门级的例子,下面小编就和大... 目录前言先大概介绍下SSE后端实现(SpringBoot)前端实现(vue3)1. 数据类型定义2.

JavaWeb 中的 Filter组件详解

《JavaWeb中的Filter组件详解》本文详细介绍了JavaWeb中的Filter组件,包括其基本概念、工作原理、核心接口和类、配置方式以及常见应用示例,Filter可以实现请求预处理、响应后... 目录JavaWeb 中的 Filter 详解1. Filter 基本概念1.1 什么是 Filter1.

SpringBoot整合Apache Spark实现一个简单的数据分析功能

《SpringBoot整合ApacheSpark实现一个简单的数据分析功能》ApacheSpark是一个开源的大数据处理框架,它提供了丰富的功能和API,用于分布式数据处理、数据分析和机器学习等任务... 目录第一步、添加android依赖第二步、编写配置类第三步、编写控制类启动项目并测试总结ApacheS

2025最新版Android Studio安装及组件配置教程(SDK、JDK、Gradle)

《2025最新版AndroidStudio安装及组件配置教程(SDK、JDK、Gradle)》:本文主要介绍2025最新版AndroidStudio安装及组件配置(SDK、JDK、Gradle... 目录原生 android 简介Android Studio必备组件一、Android Studio安装二、A

Python实现繁体转简体功能的三种方案

《Python实现繁体转简体功能的三种方案》在中文信息处理中,繁体字与简体字的转换是一个常见需求,无论是处理港澳台地区的文本数据,还是开发面向不同中文用户群体的应用,繁简转换都是不可或缺的功能,本文将... 目录前言为什么需要繁简转换?python实现方案方案一:使用opencc库方案二:使用zhconv库

前端Visual Studio Code安装配置教程之下载、汉化、常用组件及基本操作

《前端VisualStudioCode安装配置教程之下载、汉化、常用组件及基本操作》VisualStudioCode是微软推出的一个强大的代码编辑器,功能强大,操作简单便捷,还有着良好的用户界面,... 目录一、Visual Studio Code下载二、汉化三、常用组件1、Auto Rename Tag2