1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package net.sourceforge.hivegui.table; |
16 | |
17 | import java.lang.reflect.Array; |
18 | import java.util.ArrayList; |
19 | import java.util.Arrays; |
20 | import java.util.Collections; |
21 | import java.util.Comparator; |
22 | import java.util.List; |
23 | |
24 | /** |
25 | * @author Jean-Francois Poilpret |
26 | */ |
27 | public class DefaultDataListModel<T> extends AbstractDataListModel<T> |
28 | { |
29 | public DefaultDataListModel(Class<T> beanClass) |
30 | { |
31 | this(beanClass, null); |
32 | } |
33 | |
34 | @SuppressWarnings("unchecked") |
35 | public DefaultDataListModel(Class<T> beanClass, Comparator<T> sorter) |
36 | { |
37 | _beanClass = beanClass; |
38 | _sorter = sorter; |
39 | _emptyItems = (T[]) Array.newInstance(beanClass, 0); |
40 | } |
41 | |
42 | public Class<T> getRowClass() |
43 | { |
44 | return _beanClass; |
45 | } |
46 | |
47 | public void setSorter(Comparator<T> sorter) |
48 | { |
49 | if (_sorter == sorter) |
50 | { |
51 | return; |
52 | } |
53 | _sorter = sorter; |
54 | if (_sorter != null) |
55 | { |
56 | rehash(); |
57 | fireModelReset(); |
58 | } |
59 | } |
60 | |
61 | public void setRows(T[] items) |
62 | { |
63 | _items = new ArrayList<T>(Arrays.asList(items)); |
64 | rehash(); |
65 | fireModelReset(); |
66 | } |
67 | |
68 | public void setRow(int row, T item) |
69 | { |
70 | if (row < 0 || row > _items.size()) |
71 | { |
72 | return; |
73 | } |
74 | if (_sorter == null) |
75 | { |
76 | _items.set(row, item); |
77 | fireRowsModified(row, row); |
78 | } |
79 | else |
80 | { |
81 | // We must remove the previous row then add a new one |
82 | removeRow(row, false); |
83 | int newRow = addRow(0, item, false); |
84 | // Fire specific event |
85 | fireRowModified(row, newRow); |
86 | } |
87 | } |
88 | |
89 | public void addRow(T item) |
90 | { |
91 | addRow(_items.size(), item); |
92 | } |
93 | |
94 | public void addRow(int row, T item) |
95 | { |
96 | addRow(row, item, true); |
97 | } |
98 | |
99 | protected int addRow(int row, T item, boolean fire) |
100 | { |
101 | int actualRow = row; |
102 | if (actualRow < 0) |
103 | { |
104 | actualRow = 0; |
105 | } |
106 | else if (actualRow > _items.size()) |
107 | { |
108 | actualRow = _items.size(); |
109 | } |
110 | |
111 | if (_sorter != null) |
112 | { |
113 | actualRow = Collections.binarySearch(_items, item, _sorter); |
114 | if (actualRow < 0) |
115 | { |
116 | actualRow = -actualRow - 1; |
117 | } |
118 | } |
119 | _items.add(actualRow, item); |
120 | if (fire) |
121 | { |
122 | fireRowsAdded(actualRow, actualRow); |
123 | } |
124 | return actualRow; |
125 | } |
126 | |
127 | public void removeRow(T item) |
128 | { |
129 | removeRow(findRow(item)); |
130 | } |
131 | |
132 | protected int findRow(T item) |
133 | { |
134 | return _items.indexOf(item); |
135 | } |
136 | |
137 | public void removeRow(int row) |
138 | { |
139 | removeRow(row, true); |
140 | } |
141 | |
142 | protected void removeRow(int row, boolean fire) |
143 | { |
144 | if (row >= 0 && row < _items.size()) |
145 | { |
146 | _items.remove(row); |
147 | if (fire) |
148 | { |
149 | fireRowsRemoved(row, row); |
150 | } |
151 | } |
152 | } |
153 | |
154 | public void clear() |
155 | { |
156 | int last = _items.size() - 1; |
157 | if (last >= 0) |
158 | { |
159 | _items.clear(); |
160 | fireRowsRemoved(0, last); |
161 | } |
162 | } |
163 | |
164 | public int getRowCount() |
165 | { |
166 | return _items.size(); |
167 | } |
168 | |
169 | public T getRow(int row) |
170 | { |
171 | if (row < 0 || row >= _items.size()) |
172 | { |
173 | return null; |
174 | } |
175 | else |
176 | { |
177 | return _items.get(row); |
178 | } |
179 | } |
180 | |
181 | public T[] getRows() |
182 | { |
183 | return _items.toArray(_emptyItems); |
184 | } |
185 | |
186 | protected void rehash() |
187 | { |
188 | if (_sorter != null) |
189 | { |
190 | Collections.sort(_items, _sorter); |
191 | } |
192 | } |
193 | |
194 | protected List<T> _items = new ArrayList<T>(); |
195 | protected Comparator<T> _sorter; |
196 | final protected T[] _emptyItems; |
197 | final protected Class<T> _beanClass; |
198 | } |