我的程序中有一个 JTextField 和一个 JList 。 JList 包含用户的联系人。我想根据 JTextField 上的文本过滤 JList。例如,如果我输入“Mike”,它只会显示包括“Mike”的联系人。当用户清除 JTextField 时,它将重置过滤器。
我知道我可以通过两个数组手动完成此操作。一份用于原始联系人,一份用于过滤后的联系人。当用户更改 JTextField 的值时,我将遍历原始列表,更新临时列表并更新 JList。我只是想知道是否有一些内置功能可以避免手工劳动。
执行此类操作的最佳方法是使用 ListModel 实现来过滤其内容。
我不知道任何默认过滤 ListModel 实现,但它应该不会太难做到。
这是一个快速而肮脏的解决方案,仅供您参考。您可能想为其添加更多附加功能。
package test;
import java.util.ArrayList;
import javax.swing.AbstractListModel;
import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
public class FilteredListModel extends AbstractListModel {
public static interface Filter {
boolean accept(Object element);
}
private final ListModel _source;
private Filter _filter;
private final ArrayList<Integer> _indices = new ArrayList<Integer>();
public FilteredListModel(ListModel source) {
if (source == null)
throw new IllegalArgumentException("Source is null");
_source = source;
_source.addListDataListener(new ListDataListener() {
public void intervalRemoved(ListDataEvent e) {
doFilter();
}
public void intervalAdded(ListDataEvent e) {
doFilter();
}
public void contentsChanged(ListDataEvent e) {
doFilter();
}
});
}
public void setFilter(Filter f) {
_filter = f;
doFilter();
}
private void doFilter() {
_indices.clear();
Filter f = _filter;
if (f != null) {
int count = _source.getSize();
for (int i = 0; i < count; i++) {
Object element = _source.getElementAt(i);
if (f.accept(element)) {
_indices.add(i);
}
}
fireContentsChanged(this, 0, getSize() - 1);
}
}
public int getSize() {
return (_filter != null) ? _indices.size() : _source.getSize();
}
public Object getElementAt(int index) {
return (_filter != null) ? _source.getElementAt(_indices.get(index)) : _source.getElementAt(index);
}
}
为了使用它,您需要将其设置到 JList,然后根据需要调用 setFilter()。
这是一个例子:
ListModel source = new DefaultListModel(); // use a model of your choice here;
FilteredListModel filteredListModel = new FilteredListModel(source);
JList list = new JList(filteredListModel);
filteredListModel.setFilter(new FilteredListModel.Filter() {
public boolean accept(Object element) {
return false; // put your filtering logic here.
}
});
一旦调用 setFilter() 方法,屏幕上的 JList 就会相应地更改其内容。
或者,您可能希望为过滤器实现观察者/可观察模式,这样您就可以重新过滤列表,而无需调用方法 setFilter()。您可以稍后尝试一下。对于第一次迭代,只要每次用户在 JTextField 中键入内容时调用方法 setFilter 就足够了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)