Revision 2260 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
FilteredListModelImpl.java | ||
---|---|---|
1 | 1 |
package org.gvsig.tools.swing.impl; |
2 | 2 |
|
3 |
import java.util.AbstractList; |
|
3 | 4 |
import org.gvsig.tools.swing.api.FilteredListModel; |
4 |
import java.util.ArrayList; |
|
5 |
import java.util.Comparator; |
|
6 | 5 |
import java.util.List; |
7 | 6 |
import java.util.Objects; |
8 | 7 |
import javax.swing.AbstractListModel; |
8 |
import javax.swing.DefaultListModel; |
|
9 |
import javax.swing.ListModel; |
|
9 | 10 |
import javax.swing.SwingUtilities; |
10 | 11 |
import org.apache.commons.io.FilenameUtils; |
11 | 12 |
import org.apache.commons.lang3.ObjectUtils; |
... | ... | |
20 | 21 |
*/ |
21 | 22 |
class FilteredListModelImpl extends AbstractListModel implements FilteredListModel { |
22 | 23 |
|
23 |
private List<LabeledValue> elements; |
|
24 |
private List<LabeledValue> filteredElements; |
|
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; |
|
25 | 54 |
private String filter; |
26 |
private boolean sorting; |
|
27 | 55 |
private AbstractCancellableTask th; |
28 | 56 |
|
29 |
public FilteredListModelImpl() { |
|
30 |
this.elements = new ArrayList<>(); |
|
31 |
this.filteredElements = this.elements; |
|
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(); |
|
32 | 64 |
this.filter = null; |
33 |
this.sorting = false; |
|
34 | 65 |
this.th = null; |
35 | 66 |
} |
36 | 67 |
|
37 | 68 |
@Override |
69 |
public ListModel getModel() { |
|
70 |
return this.elements; |
|
71 |
} |
|
72 |
|
|
73 |
@Override |
|
38 | 74 |
public int getSize() { |
39 |
return this.filteredElements.size();
|
|
75 |
return this.filteredElements.getSize();
|
|
40 | 76 |
} |
41 | 77 |
|
42 | 78 |
@Override |
43 | 79 |
public void clear() { |
44 |
this.elements = new ArrayList<>();
|
|
45 |
this.filteredElements = this.elements;
|
|
80 |
this.elements = new DefaultListModel();
|
|
81 |
this.filteredElements = new DefaultListModel();
|
|
46 | 82 |
this.filter = null; |
47 | 83 |
fireContentsChanged(); |
48 | 84 |
} |
49 | 85 |
|
50 | 86 |
@Override |
51 | 87 |
public LabeledValue getElementAt(int index) { |
52 |
return this.filteredElements.get(index); |
|
88 |
return this.filteredElements.getElementAt(index);
|
|
53 | 89 |
} |
54 | 90 |
|
55 | 91 |
@Override |
... | ... | |
57 | 93 |
if( element==null ) { |
58 | 94 |
return; |
59 | 95 |
} |
60 |
this.elements.add(element); |
|
61 |
if (this.elements != this.filteredElements) { |
|
62 |
this.filteredElements.add(element); |
|
96 |
if( !(elements instanceof DefaultListModel) ) { |
|
97 |
throw new IllegalStateException("The model is unmodifiable."); |
|
63 | 98 |
} |
99 |
((DefaultListModel)this.elements).addElement(element); |
|
100 |
if (filter==null || FilenameUtils.wildcardMatch(element.toString().toLowerCase(), filter)) { |
|
101 |
this.filteredElements.addElement(element); |
|
102 |
} |
|
64 | 103 |
fireContentsChanged(); |
65 | 104 |
} |
66 | 105 |
|
67 | 106 |
@Override |
68 | 107 |
public void addElement(Object element) { |
69 |
this.addElement(new LabeledValueImpl<>(Objects.toString(element, ""), element)); |
|
108 |
if( !(element instanceof LabeledValue) ) { |
|
109 |
element = new LabeledValueImpl<>(Objects.toString(element, ""), element); |
|
110 |
} |
|
111 |
this.addElement((LabeledValue)element); |
|
70 | 112 |
} |
71 | 113 |
|
72 | 114 |
|
... | ... | |
74 | 116 |
public void setFilter(String filter) { |
75 | 117 |
if (StringUtils.isBlank(filter)) { |
76 | 118 |
this.filter = null; |
77 |
this.filteredElements = this.elements; |
|
78 | 119 |
} else { |
79 | 120 |
if( StringUtils.containsAny(filter, "*?") ) { |
80 | 121 |
this.filter = filter; |
81 | 122 |
} else { |
82 | 123 |
this.filter = "*" + filter + "*"; |
83 | 124 |
} |
84 |
this.filteredElements = new ArrayList<>(); |
|
85 |
for (LabeledValue element : elements) { |
|
86 |
if (FilenameUtils.wildcardMatch(element.getLabel().toLowerCase(), this.filter.toLowerCase())) { |
|
87 |
this.filteredElements.add(element); |
|
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); |
|
88 | 145 |
} |
89 | 146 |
} |
147 |
|
|
90 | 148 |
} |
91 |
fireContentsChanged(); |
|
92 | 149 |
} |
93 |
|
|
94 | 150 |
private void fireContentsChanged() { |
95 | 151 |
if( !SwingUtilities.isEventDispatchThread() ) { |
96 | 152 |
SwingUtilities.invokeLater(() -> { |
... | ... | |
118 | 174 |
this.th = new AbstractCancellableTask("FilteredListModelSorter") { |
119 | 175 |
@Override |
120 | 176 |
public void run() { |
121 |
final List items = new ArrayList<>(elements); |
|
122 |
items.sort(new Comparator<LabeledValue>() { |
|
123 |
@Override |
|
124 |
public int compare(LabeledValue o1, LabeledValue o2) { |
|
125 |
int r = ObjectUtils.compare(o1.getLabel(), o2.getLabel()); |
|
126 |
if (ascending) { |
|
127 |
return r; |
|
128 |
} |
|
129 |
return r * -1; |
|
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; |
|
130 | 182 |
} |
183 |
return -r; |
|
131 | 184 |
}); |
132 | 185 |
if (this.isCancellationRequested()) { |
133 | 186 |
return; |
134 | 187 |
} |
135 |
elements = items; |
|
136 |
filteredElements = elements; |
|
137 |
if (filter != null) { |
|
138 |
setFilter(filter); |
|
139 |
} else { |
|
140 |
fireContentsChanged(); |
|
141 |
} |
|
188 |
copy(elements, filteredElements, filter); |
|
189 |
fireContentsChanged(); |
|
142 | 190 |
} |
143 | 191 |
}; |
144 | 192 |
th.start(); |
Also available in: Unified diff