gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.swing / org.gvsig.tools.swing.impl / src / main / java / org / gvsig / tools / swing / impl / FilteredListModelImpl.java @ 2260
History | View | Annotate | Download (5.6 KB)
1 |
package org.gvsig.tools.swing.impl; |
---|---|
2 |
|
3 |
import java.util.AbstractList; |
4 |
import org.gvsig.tools.swing.api.FilteredListModel; |
5 |
import java.util.List; |
6 |
import java.util.Objects; |
7 |
import javax.swing.AbstractListModel; |
8 |
import javax.swing.DefaultListModel; |
9 |
import javax.swing.ListModel; |
10 |
import javax.swing.SwingUtilities; |
11 |
import org.apache.commons.io.FilenameUtils; |
12 |
import org.apache.commons.lang3.ObjectUtils; |
13 |
import org.apache.commons.lang3.StringUtils; |
14 |
import org.gvsig.tools.task.AbstractCancellableTask; |
15 |
import org.gvsig.tools.util.LabeledValue; |
16 |
import org.gvsig.tools.util.LabeledValueImpl; |
17 |
|
18 |
/**
|
19 |
*
|
20 |
* @author jjdelcerro
|
21 |
*/
|
22 |
class FilteredListModelImpl extends AbstractListModel implements FilteredListModel { |
23 |
|
24 |
private static class ListModelToListAdapter extends AbstractList { |
25 |
|
26 |
private final ListModel model; |
27 |
|
28 |
public ListModelToListAdapter(ListModel model) { |
29 |
this.model = model;
|
30 |
} |
31 |
|
32 |
@Override
|
33 |
public Object get(int index) { |
34 |
return this.model.getElementAt(index); |
35 |
} |
36 |
|
37 |
@Override
|
38 |
public int size() { |
39 |
return this.model.getSize(); |
40 |
} |
41 |
|
42 |
@Override
|
43 |
public Object set(int index, Object element) { |
44 |
if( !(model instanceof DefaultListModel) ) { |
45 |
throw new IllegalStateException("The model is unmodifiable."); |
46 |
} |
47 |
return ((DefaultListModel)this.model).set(index, element); |
48 |
} |
49 |
|
50 |
} |
51 |
|
52 |
private ListModel elements; |
53 |
private DefaultListModel<LabeledValue> filteredElements; |
54 |
private String filter; |
55 |
private AbstractCancellableTask th;
|
56 |
|
57 |
public FilteredListModelImpl(ListModel model) { |
58 |
if( model == null ) { |
59 |
this.elements = new DefaultListModel(); |
60 |
} else {
|
61 |
this.elements = model;
|
62 |
} |
63 |
this.filteredElements = new DefaultListModel(); |
64 |
this.filter = null; |
65 |
this.th = null; |
66 |
} |
67 |
|
68 |
@Override
|
69 |
public ListModel getModel() { |
70 |
return this.elements; |
71 |
} |
72 |
|
73 |
@Override
|
74 |
public int getSize() { |
75 |
return this.filteredElements.getSize(); |
76 |
} |
77 |
|
78 |
@Override
|
79 |
public void clear() { |
80 |
this.elements = new DefaultListModel(); |
81 |
this.filteredElements = new DefaultListModel(); |
82 |
this.filter = null; |
83 |
fireContentsChanged(); |
84 |
} |
85 |
|
86 |
@Override
|
87 |
public LabeledValue getElementAt(int index) { |
88 |
return this.filteredElements.getElementAt(index); |
89 |
} |
90 |
|
91 |
@Override
|
92 |
public void addElement(LabeledValue element) { |
93 |
if( element==null ) { |
94 |
return;
|
95 |
} |
96 |
if( !(elements instanceof DefaultListModel) ) { |
97 |
throw new IllegalStateException("The model is unmodifiable."); |
98 |
} |
99 |
((DefaultListModel)this.elements).addElement(element); |
100 |
if (filter==null || FilenameUtils.wildcardMatch(element.toString().toLowerCase(), filter)) { |
101 |
this.filteredElements.addElement(element);
|
102 |
} |
103 |
fireContentsChanged(); |
104 |
} |
105 |
|
106 |
@Override
|
107 |
public void addElement(Object element) { |
108 |
if( !(element instanceof LabeledValue) ) { |
109 |
element = new LabeledValueImpl<>(Objects.toString(element, ""), element); |
110 |
} |
111 |
this.addElement((LabeledValue)element);
|
112 |
} |
113 |
|
114 |
|
115 |
@Override
|
116 |
public void setFilter(String filter) { |
117 |
if (StringUtils.isBlank(filter)) {
|
118 |
this.filter = null; |
119 |
} else {
|
120 |
if( StringUtils.containsAny(filter, "*?") ) { |
121 |
this.filter = filter;
|
122 |
} else {
|
123 |
this.filter = "*" + filter + "*"; |
124 |
} |
125 |
} |
126 |
this.copy(elements, filteredElements, this.filter); |
127 |
fireContentsChanged(); |
128 |
} |
129 |
|
130 |
private void copy(ListModel source, DefaultListModel target, String filter) { |
131 |
target.clear(); |
132 |
if( filter!=null ) { |
133 |
filter = filter.toLowerCase(); |
134 |
} |
135 |
for (int i = 0; i < source.getSize(); i++) { |
136 |
Object item = source.getElementAt(i);
|
137 |
if( item == null ) { |
138 |
continue;
|
139 |
} |
140 |
if( filter==null ) { |
141 |
target.addElement(item); |
142 |
} else {
|
143 |
if (FilenameUtils.wildcardMatch(item.toString().toLowerCase(), filter)) {
|
144 |
target.addElement(item); |
145 |
} |
146 |
} |
147 |
|
148 |
} |
149 |
} |
150 |
private void fireContentsChanged() { |
151 |
if( !SwingUtilities.isEventDispatchThread() ) { |
152 |
SwingUtilities.invokeLater(() -> {
|
153 |
fireContentsChanged(); |
154 |
}); |
155 |
return;
|
156 |
} |
157 |
this.fireContentsChanged(this, 0, this.filteredElements.size()); |
158 |
} |
159 |
|
160 |
@Override
|
161 |
public String getFilter() { |
162 |
return this.filter; |
163 |
} |
164 |
|
165 |
@Override
|
166 |
public void sort(final boolean ascending) { |
167 |
this.sortBackground(ascending);
|
168 |
} |
169 |
|
170 |
private void sortBackground(final boolean ascending) { |
171 |
if (this.th != null) { |
172 |
this.th.cancelRequest();
|
173 |
} |
174 |
this.th = new AbstractCancellableTask("FilteredListModelSorter") { |
175 |
@Override
|
176 |
public void run() { |
177 |
final List items = new ListModelToListAdapter(elements); |
178 |
items.sort((Object o1, Object o2) -> { |
179 |
int r = ObjectUtils.compare(o1.toString(), o2.toString());
|
180 |
if (ascending) {
|
181 |
return r;
|
182 |
} |
183 |
return -r;
|
184 |
}); |
185 |
if (this.isCancellationRequested()) { |
186 |
return;
|
187 |
} |
188 |
copy(elements, filteredElements, filter); |
189 |
fireContentsChanged(); |
190 |
} |
191 |
}; |
192 |
th.start(); |
193 |
} |
194 |
|
195 |
} |