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

View differences:

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