1 package fr.ifremer.quadrige2.ui.swing.common.table.state;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import com.google.common.collect.Lists;
28 import com.google.common.collect.Maps;
29 import fr.ifremer.quadrige2.core.dao.technical.Beans;
30 import fr.ifremer.quadrige2.ui.swing.common.table.AbstractTableModel;
31 import fr.ifremer.quadrige2.ui.swing.common.table.CheckTableColumn;
32 import fr.ifremer.quadrige2.ui.swing.common.table.ColumnIdentifier;
33 import jaxx.runtime.swing.session.State;
34 import org.apache.commons.lang3.StringUtils;
35 import org.jdesktop.swingx.JXTable;
36 import org.jdesktop.swingx.table.TableColumnExt;
37
38 import javax.swing.RowSorter;
39 import javax.swing.SortOrder;
40 import java.util.*;
41
42
43
44
45
46
47 public class SwingTableSessionState implements ExtendedState {
48
49 protected static final String SEPARATOR = "|";
50
51 private Map<String, SwingTableState> sessionStates;
52
53
54
55
56 public SwingTableSessionState() {
57 sessionStates = Maps.newHashMap();
58 }
59
60
61
62
63
64
65
66 protected JXTable checkComponent(Object o) {
67 if (o == null) {
68 throw new IllegalArgumentException("null component");
69 }
70 if (!(o instanceof JXTable)) {
71 throw new IllegalArgumentException("invalid component");
72 }
73 return (JXTable) o;
74 }
75
76
77 @Override
78 public State getState(Object o) {
79
80 return getState(o, null, null);
81 }
82
83
84 @Override
85 @SuppressWarnings("unchecked")
86 public State getState(Object o, State previousState, String stateContextToSave) {
87
88 JXTable table = checkComponent(o);
89 if (!(table.getModel() instanceof AbstractTableModel)) {
90 return null;
91 }
92
93 AbstractTableModel tableModel = (AbstractTableModel) table.getModel();
94 String stateContext = stateContextToSave != null ? stateContextToSave : tableModel.getStateContext();
95
96
97 SwingTableSessionState tableSessionState;
98 if (previousState instanceof SwingTableSessionState) {
99 tableSessionState = (SwingTableSessionState) previousState;
100 } else {
101 tableSessionState = new SwingTableSessionState();
102 }
103
104 SwingTableState tableState = tableSessionState.getSessionStates().get(stateContext);
105 if (tableState == null) {
106 tableState = new SwingTableState();
107 tableSessionState.getSessionStates().put(stateContext, tableState);
108 }
109
110
111 List<ColumnIdentifier> identifiers = Beans.getList(tableModel.getIdentifiers());
112
113 Map<Integer, Integer> sortOrderPriority = Maps.newHashMap();
114 if (table.getRowSorter() != null && table.getRowSorter().getSortKeys() != null) {
115 for (int priority = 0; priority < table.getRowSorter().getSortKeys().size(); priority++) {
116 RowSorter.SortKey sortKey = table.getRowSorter().getSortKeys().get(priority);
117 sortOrderPriority.put(sortKey.getColumn(), priority);
118 }
119 }
120
121
122 for (ColumnIdentifier identifier : identifiers) {
123 TableColumnExt column = table.getColumnExt(identifier);
124 if (column == null || column instanceof CheckTableColumn) {
125
126 continue;
127 }
128
129 int columnViewIndex = table.convertColumnIndexToView(column.getModelIndex());
130
131
132 if (tableModel.hasCheckTableColumn() && columnViewIndex > 0) {
133 columnViewIndex--;
134 }
135
136
137 tableState.getVisibility().put(identifier.getPropertyName(), columnViewIndex);
138
139
140 tableState.getWidth().put(identifier.getPropertyName(), column.getPreferredWidth());
141
142
143
144 if (table.getRowSorter() != null) {
145 SortOrder sortOrder = table.getSortOrder(identifier);
146 if (sortOrder != SortOrder.UNSORTED) {
147 String order = sortOrder.name() + SEPARATOR + sortOrderPriority.get(column.getModelIndex());
148 tableState.getSortOrder().put(identifier.getPropertyName(), order);
149 }
150 }
151 }
152
153 return tableSessionState;
154 }
155
156
157 @Override
158 @SuppressWarnings("unchecked")
159 public void setState(Object o, State state) {
160 if (state == null) {
161 return;
162 }
163 if (!(state instanceof SwingTableSessionState)) {
164 throw new IllegalArgumentException("invalid state");
165 }
166 JXTable table = checkComponent(o);
167 if (!(table.getModel() instanceof AbstractTableModel)) {
168 return;
169 }
170
171
172 AbstractTableModel tableModel = (AbstractTableModel) table.getModel();
173 SwingTableSessionState tableSessionState = (SwingTableSessionState) state;
174 SwingTableState tableState = tableSessionState.getSessionStates().get(tableModel.getStateContext());
175 if (tableState == null) {
176
177 return;
178 }
179
180
181 List<ColumnIdentifier> identifiers = Beans.getList(tableModel.getIdentifiers());
182 Map<Integer, SortOrder> sortOrderByModelIndex = Maps.newHashMap();
183 Map<Integer, Integer> sortPriority = Maps.newHashMap();
184 Map<Integer, Integer> deferredMove = Maps.newHashMap();
185
186 for (ColumnIdentifier identifier : identifiers) {
187 TableColumnExt column = table.getColumnExt(identifier);
188 if (column == null || column instanceof CheckTableColumn) {
189
190 continue;
191 }
192
193
194 Integer visibility = tableState.getVisibility().get(identifier.getPropertyName());
195 if (visibility != null && visibility > -1) {
196
197 column.setVisible(true);
198
199 deferredMove.put(column.getModelIndex(), visibility);
200 } else if (column.isHideable()) {
201
202 column.setVisible(false);
203 }
204
205
206 if (column.getResizable()) {
207 Integer width = tableState.getWidth().get(identifier.getPropertyName());
208 if (width != null) {
209 column.setPreferredWidth(width);
210 }
211 }
212
213
214 if (column.isSortable()) {
215 String order = tableState.getSortOrder().get(identifier.getPropertyName());
216 if (order != null) {
217
218 String[] orderAndPriority = StringUtils.split(order, SEPARATOR);
219 SortOrder sortOrder = SortOrder.valueOf(orderAndPriority[0]);
220 Integer priority = Integer.parseInt(orderAndPriority[1]);
221
222 sortOrderByModelIndex.put(column.getModelIndex(), sortOrder);
223 sortPriority.put(priority, column.getModelIndex());
224 }
225 }
226 }
227
228
229 if (!deferredMove.isEmpty()) {
230 List<Integer> columnModelIndexes = Lists.newArrayList(deferredMove.keySet());
231 Collections.sort(columnModelIndexes);
232 for (Integer columnModelIndex : columnModelIndexes) {
233 int columnViewIndex = table.convertColumnIndexToView(columnModelIndex);
234 int newColumnViewIndex = deferredMove.get(columnModelIndex);
235
236
237 if (tableModel.hasCheckTableColumn() && newColumnViewIndex >= 0) {
238 newColumnViewIndex++;
239 }
240 if (newColumnViewIndex >= table.getColumnCount()) {
241 newColumnViewIndex = table.getColumnCount() - 1;
242 }
243
244
245 table.moveColumn(columnViewIndex, newColumnViewIndex);
246 }
247 }
248
249
250 if (!sortOrderByModelIndex.isEmpty()) {
251 SortedSet<Integer> priorityOrder = new TreeSet<>(sortPriority.keySet());
252 List<RowSorter.SortKey> sortKeys = Lists.newArrayList();
253 for (Integer priority : priorityOrder) {
254 Integer modelIndex = sortPriority.get(priority);
255 SortOrder sortOrder = sortOrderByModelIndex.get(modelIndex);
256 RowSorter.SortKey sortKey = new RowSorter.SortKey(modelIndex, sortOrder);
257 sortKeys.add(sortKey);
258 }
259 table.getRowSorter().setSortKeys(sortKeys);
260 }
261
262 }
263
264
265
266
267
268
269 public Map<String, SwingTableState> getSessionStates() {
270 return sessionStates;
271 }
272
273
274
275
276
277
278 public void setSessionStates(Map<String, SwingTableState> sessionStates) {
279 this.sessionStates = sessionStates;
280 }
281
282 }