Statistics
| Revision:

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
}