锁定老帖子 主题:Swing小应用(Todo-list)之二
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|||
---|---|---|---|
作者 | 正文 | ||
发表时间:2009-09-17
最后修改:2009-09-17
前言用过vim, emacs的人都知道,这两个工具中都有很好用的增量搜索(incremental search )功能,所谓增量搜索,就是随着你的关键字的输入,结果在不断的进行刷新匹配,现在的很多web搜索框都提供类似的功能,最著名的当然是Google的,速度快,匹配率比较高(要不然也不会令人“心神不宁”了,哈哈)。
效果及实现
效果如图所示,下边我们来看看大概说下原理,一般来说,我们需要一个搜索框,来对列表中的元素进行搜索,Swing采用MVC模式,所以实现起来比较容易,而且代码结构也更为直观,当搜索框中的内容发生变化时,我们需要对类表中的对象进行遍历,如果有匹配,将这些匹配的item放入一个临时的List中,而列表中原来的对象不做更改(那样,当搜索条件为空的时候,显示整个列表)。
每一个JInputField都是一个Document,Document上可以注册监听器,当JInputField内容发生变化时,通知List的datamodel进行更新,同时Swing会将更新反映在UI组件上(JList)。
先来看JList的数据模型的实现: package org.free.todolist.model; import java.util.ArrayList; import java.util.List; import javax.swing.AbstractListModel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; import javax.swing.text.Document; /** * * @author juntao.qiu@gmail.com * */ public class FilterableListModel extends AbstractListModel implements DocumentListener { private static final long serialVersionUID = -2409529218176332776L; private List<Object> list; private List<Object> filteredList; private String lastFilter = ""; public FilterableListModel() { list = new ArrayList<Object>(); filteredList = new ArrayList<Object>(); } public void addElement(Object element) { list.add(element); filter(lastFilter); } public int getSize() { return filteredList.size(); } public Object getElementAt(int index) { Object returnValue; if (index < filteredList.size()) { returnValue = filteredList.get(index); } else { returnValue = null; } return returnValue; } public void removeElement(int index){ list.remove(index); filter(lastFilter); } private void filter(String search) { filteredList.clear(); for (Object element : list) { if (element.toString().indexOf(search, 0) != -1) { filteredList.add(element); } } fireContentsChanged(this, 0, getSize()); } public void insertUpdate(DocumentEvent event) { Document doc = event.getDocument(); try { lastFilter = doc.getText(0, doc.getLength()); filter(lastFilter); } catch (BadLocationException e) { e.printStackTrace(); } } public void removeUpdate(DocumentEvent event) { Document doc = event.getDocument(); try { lastFilter = doc.getText(0, doc.getLength()); filter(lastFilter); } catch (BadLocationException e) { e.printStackTrace(); } } public void changedUpdate(DocumentEvent event) { } public void clear() { list.clear(); filteredList.clear(); } } 主要的方法是这个filter(), 当Document内容发生改变时,它会raise一个事件给父类AbstractListModel,然后AbstractListModel去更改JList的UI,从而实现过滤的功能。
List的UI组件比较简单,只需要设置好其数据模型即可: package org.free.todolist.ui; import javax.swing.JList; import javax.swing.JTextField; import javax.swing.ListModel; import org.free.todolist.model.FilterableListModel; /** * * @author juntao.qiu@gmail.com * */ public class FilterableList extends JList { private static final long serialVersionUID = 2827679372675804255L; public FilterableList() { FilterableListModel model = new FilterableListModel(); setModel(model); } /** * register the search box on list */ public void installFilterField(JTextField input) { if (input != null) { FilterableListModel model = (FilterableListModel) getModel(); input.getDocument().addDocumentListener(model); } } /** * unregister the search box on list. */ public void uninstallFilterField(JTextField input) { if (input != null) { FilterableListModel model = (FilterableListModel) getModel(); input.getDocument().removeDocumentListener(model); } } public void setModel(ListModel model) { if (!(model instanceof FilterableListModel)) { throw new IllegalArgumentException(); } else { super.setModel(model); } } public void addElement(Object element) { ((FilterableListModel) getModel()).addElement(element); } /** * get the filterable list model of current list * @return */ public FilterableListModel getContents(){ return (FilterableListModel)getModel(); } } 如果需要完整的代码,可以到sTodo 的项目主页上下载。sTodo已经有了讨论组,如果有兴趣,欢迎加入:sTodo讨论组
后记Swing的定制性相当高,几乎可以任意搭配,任意组合,但是灵活性高了,学习曲线就显得陡峭了,且所有的UI需要在EDT中更新,如果控制不好,很容易造成假死。
sTodo现在的版本是V0.3,基本功能已经完成,如对todo的增删改查,将某一个todo发送到指定邮箱,导出成各种格式(这个目前做的不好,代码还没有更新在SVN上),后期打算将这个项目做成一个可编程的小应用,你可以任意对其进行扩展,目前,插件部分已经基本可用,还没有移植到项目中去,等周末或者国庆长假的时候可能就可以做进去了。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||
返回顶楼 | |||
发表时间:2009-09-18
最近在正要实现一个增量搜索的功能,楼主能不能把sun那篇文章的地址也贴出来,谢了:)
|
|||
返回顶楼 | |||
发表时间:2009-09-21
ntower 写道 最近在正要实现一个增量搜索的功能,楼主能不能把sun那篇文章的地址也贴出来,谢了:)
不好意思,这几天没怎么上论坛,这个是地址: http://java.sun.com/developer/JDCTechTips/2005/tt1214.html |
|||
返回顶楼 | |||
发表时间:2009-09-24
嗯,这篇文章很有用,谢啦! 最近也在学习swing,以后多多交流 :)
|
|||
返回顶楼 | |||
发表时间:2009-09-24
麻烦把依赖的jar上传下,不太好找
|
|||
返回顶楼 | |||
发表时间:2009-09-24
jvincent 写道 麻烦把依赖的jar上传下,不太好找
好的,晚上回去传吧。 |
|||
返回顶楼 | |||
发表时间:2010-08-19
大哥jar给我们上传一下啊。老是报缺少jar |
|||
返回顶楼 | |||
发表时间:2010-08-20
已经解决了,哈哈
|
|||
返回顶楼 | |||
浏览 3337 次