OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 147 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 147 Rev 150
Line 1... Line 1...
1
package org.openconcerto.modules.operation;
1
package org.openconcerto.modules.operation;
2
 
2
 
3
import java.util.ArrayList;
3
import java.util.ArrayList;
-
 
4
import java.util.Collection;
-
 
5
import java.util.Collections;
-
 
6
import java.util.HashSet;
4
import java.util.List;
7
import java.util.List;
-
 
8
import java.util.Set;
5
 
9
 
6
import javax.swing.AbstractListModel;
10
import javax.swing.AbstractListModel;
7
import javax.swing.SwingUtilities;
11
import javax.swing.SwingUtilities;
8
import javax.swing.SwingWorker;
12
import javax.swing.SwingWorker;
9
 
13
 
10
import org.openconcerto.ui.list.CheckListItem;
14
import org.openconcerto.ui.list.CheckListItem;
11
 
15
 
-
 
16
import net.jcip.annotations.GuardedBy;
-
 
17
 
12
public abstract class CheckListModel extends AbstractListModel {
18
public abstract class CheckListModel<T> extends AbstractListModel<CheckListItem> {
-
 
19
    private final Class<T> itemClass;
13
    private List<CheckListItem> items = new ArrayList<CheckListItem>();
20
    private List<CheckListItem> items = new ArrayList<CheckListItem>();
-
 
21
    // don't do multiple loads concurrently, allow to know if an update is coming
-
 
22
    @GuardedBy("EDT")
-
 
23
    private SwingWorker<?, ?> loadWorker;
-
 
24
    // needed so that we can store wantedCheckedKeys before the first fill
-
 
25
    @GuardedBy("EDT")
-
 
26
    private boolean neverFilled = true;
-
 
27
    // keys are needed since other classes might not be able to create instances of T
-
 
28
    // e.g. the key is an Integer ID and T is an SQLRow
-
 
29
    @GuardedBy("EDT")
-
 
30
    private Set<Object> wantedCheckedKeys;
-
 
31
 
-
 
32
    public CheckListModel(final Class<T> clazz) {
-
 
33
        this.itemClass = clazz;
-
 
34
    }
-
 
35
 
-
 
36
    public final Class<T> getItemClass() {
-
 
37
        return this.itemClass;
-
 
38
    }
-
 
39
 
-
 
40
    private final List<CheckListItem> getItems() {
-
 
41
        assert SwingUtilities.isEventDispatchThread();
-
 
42
        return this.items;
-
 
43
    }
14
 
44
 
15
    @Override
45
    @Override
16
    public int getSize() {
46
    public int getSize() {
17
        return items.size();
47
        return getItems().size();
18
    }
48
    }
19
 
49
 
20
    @Override
50
    @Override
21
    public Object getElementAt(int index) {
51
    public CheckListItem getElementAt(int index) {
22
        return items.get(index);
52
        return getItems().get(index);
23
    }
53
    }
24
 
54
 
25
    public void loadContent() {
55
    public void loadContent() {
26
        assert SwingUtilities.isEventDispatchThread();
56
        assert SwingUtilities.isEventDispatchThread();
-
 
57
        if (this.loadWorker != null) {
-
 
58
            this.loadWorker.cancel(true);
-
 
59
        }
27
        SwingWorker<List<CheckListItem>, Object> worker = new SwingWorker<List<CheckListItem>, Object>() {
60
        this.loadWorker = new SwingWorker<List<CheckListItem>, Object>() {
28
 
61
 
29
            @Override
62
            @Override
30
            protected List<CheckListItem> doInBackground() throws Exception {
63
            protected List<CheckListItem> doInBackground() throws Exception {
31
                return loadItems();
64
                return loadItems();
32
            }
65
            }
33
 
66
 
34
            @Override
67
            @Override
35
            protected void done() {
68
            protected void done() {
-
 
69
                // if cancel() is called after doInBackground() nothing happens
-
 
70
                // but updating is set to a new instance
-
 
71
                if (this.isCancelled() || CheckListModel.this.loadWorker != this) {
-
 
72
                    // une autre maj arrive
-
 
73
                    return;
-
 
74
                }
-
 
75
 
36
                try {
76
                try {
37
                    final List<CheckListItem> l = get();
77
                    final List<CheckListItem> l = get();
-
 
78
                    final Collection<Object> wantedKeys = getWantedCheckedKeys(true);
-
 
79
                    final boolean checkAll = items.isEmpty() && wantedKeys == null;
38
                    if (items.isEmpty()) {
80
                    if (checkAll) {
39
                        // On ajoute tout, et on sélectionne tout
81
                        // On ajoute tout, et on sélectionne tout
40
                        items.clear();
-
 
41
                        items.addAll(l);
82
                        items.addAll(l);
42
                        for (CheckListItem item : items) {
83
                        for (CheckListItem item : items) {
43
                            item.setSelected(true);
84
                            item.setSelected(true);
44
                        }
85
                        }
45
                    } else {
86
                    } else {
46
                        List<Object> previouslySelectedObject = new ArrayList<Object>();
87
                        final Collection<Object> toCheck = wantedKeys == null ? getCheckedKeys() : wantedKeys;
47
                        for (CheckListItem item : items) {
-
 
48
                            if (item.isSelected()) {
-
 
49
                                previouslySelectedObject.add(item.getObject());
-
 
50
                            }
-
 
51
                        }
-
 
52
                        items.clear();
88
                        items.clear();
53
                        items.addAll(l);
89
                        items.addAll(l);
54
                        // restaure la sélection
90
                        // restaure la sélection
55
                        for (CheckListItem item : items) {
-
 
56
                            final boolean wasSelected = previouslySelectedObject.contains(item.getObject());
-
 
57
                            item.setSelected(wasSelected);
91
                        _setCheckedKeys(toCheck);
58
                        }
-
 
59
                    }
92
                    }
-
 
93
                    CheckListModel.this.neverFilled = false;
-
 
94
                    CheckListModel.this.wantedCheckedKeys = null;
60
                    refresh();
95
                    fireContentsChanged();
61
                } catch (Exception e) {
96
                } catch (Exception e) {
62
                    e.printStackTrace();
97
                    e.printStackTrace();
-
 
98
                } finally {
-
 
99
                    assert CheckListModel.this.loadWorker == this;
-
 
100
                    CheckListModel.this.loadWorker = null;
63
                }
101
                }
64
 
102
 
65
            }
103
            }
66
        };
104
        };
67
        worker.execute();
105
        this.loadWorker.execute();
68
    }
106
    }
69
 
107
 
70
    public abstract List<CheckListItem> loadItems();
108
    public abstract List<CheckListItem> loadItems();
71
 
109
 
72
    public void refresh() {
110
    protected final void fireContentsChanged() {
73
        fireContentsChanged(this, 0, items.size());
111
        fireContentsChanged(this, 0, getSize() - 1);
-
 
112
    }
-
 
113
 
-
 
114
    public final List<CheckListItem> getCheckedItems() {
-
 
115
        final List<CheckListItem> result = new ArrayList<CheckListItem>();
-
 
116
        final int size = this.getSize();
-
 
117
        for (int i = 0; i < size; i++) {
-
 
118
            final CheckListItem item = this.getElementAt(i);
-
 
119
            if (item.isSelected()) {
-
 
120
                result.add(item);
-
 
121
            }
-
 
122
        }
-
 
123
        return result;
-
 
124
    }
-
 
125
 
-
 
126
    public final List<T> getCheckedObjects() {
-
 
127
        final List<CheckListItem> checkedItems = this.getCheckedItems();
-
 
128
        final int size = checkedItems.size();
-
 
129
        final List<T> result = new ArrayList<T>(size);
-
 
130
        for (int i = 0; i < size; i++) {
-
 
131
            result.add(this.itemClass.cast(checkedItems.get(i).getObject()));
-
 
132
        }
-
 
133
        return result;
-
 
134
    }
-
 
135
 
-
 
136
    public final List<Object> getCheckedKeys() {
-
 
137
        final List<CheckListItem> checkedItems = this.getCheckedItems();
-
 
138
        final int size = checkedItems.size();
-
 
139
        final List<Object> result = new ArrayList<Object>(size);
-
 
140
        for (int i = 0; i < size; i++) {
-
 
141
            result.add(checkedItems.get(i).getKey());
-
 
142
        }
-
 
143
        return result;
-
 
144
    }
-
 
145
 
-
 
146
    public final Collection<Object> getWantedCheckedKeys(final boolean allowNull) {
-
 
147
        if (allowNull || this.wantedCheckedKeys != null)
-
 
148
            return this.wantedCheckedKeys;
-
 
149
        return this.getCheckedKeys();
-
 
150
    }
-
 
151
 
-
 
152
    public final void setCheckedKeys(final Collection<?> sel) {
-
 
153
        if (this.loadWorker != null || this.neverFilled) {
-
 
154
            this.wantedCheckedKeys = Collections.unmodifiableSet(new HashSet<>(sel));
-
 
155
        } else {
-
 
156
            _setCheckedKeys(sel);
-
 
157
        }
-
 
158
    }
-
 
159
 
-
 
160
    private final void _setCheckedKeys(final Collection<?> sel) {
-
 
161
        for (CheckListItem item : this.getItems()) {
-
 
162
            item.setSelected(sel.contains(item.getKey()));
-
 
163
        }
-
 
164
    }
-
 
165
 
-
 
166
    public final void invertCheckAt(final int index) {
-
 
167
        final CheckListItem item = this.items.get(index);
-
 
168
        item.setSelected(!item.isSelected());
-
 
169
        fireContentsChanged(this, index, index);
-
 
170
    }
-
 
171
 
-
 
172
    public final void checkAllAs(final int index) {
-
 
173
        final boolean newVal = this.items.get(index).isSelected();
-
 
174
        for (final CheckListItem i : this.items) {
-
 
175
            i.setSelected(newVal);
-
 
176
        }
-
 
177
        fireContentsChanged();
-
 
178
    }
-
 
179
 
-
 
180
    @Override
-
 
181
    public String toString() {
-
 
182
        return this.getClass().getSimpleName() + " of " + this.getItemClass();
74
    }
183
    }
75
}
184
}
76
185