Line 16... |
Line 16... |
16 |
import org.openconcerto.ui.Log;
|
16 |
import org.openconcerto.ui.Log;
|
17 |
import org.openconcerto.ui.TM;
|
17 |
import org.openconcerto.ui.TM;
|
18 |
import org.openconcerto.ui.table.XTableColumnModel;
|
18 |
import org.openconcerto.ui.table.XTableColumnModel;
|
19 |
import org.openconcerto.utils.ExceptionHandler;
|
19 |
import org.openconcerto.utils.ExceptionHandler;
|
20 |
import org.openconcerto.utils.TableSorter;
|
20 |
import org.openconcerto.utils.TableSorter;
|
- |
|
21 |
import org.openconcerto.utils.TableSorter.Directive;
|
21 |
|
22 |
|
22 |
import java.io.File;
|
23 |
import java.io.File;
|
23 |
import java.io.IOException;
|
24 |
import java.io.IOException;
|
24 |
import java.util.ArrayList;
|
25 |
import java.util.ArrayList;
|
25 |
import java.util.Collections;
|
26 |
import java.util.Collections;
|
26 |
import java.util.List;
|
27 |
import java.util.List;
|
- |
|
28 |
import java.util.logging.Level;
|
27 |
|
29 |
|
28 |
import javax.swing.JTable;
|
30 |
import javax.swing.JTable;
|
29 |
import javax.swing.event.AncestorEvent;
|
31 |
import javax.swing.event.AncestorEvent;
|
30 |
import javax.swing.event.AncestorListener;
|
32 |
import javax.swing.event.AncestorListener;
|
31 |
import javax.swing.table.TableColumn;
|
33 |
import javax.swing.table.TableColumn;
|
32 |
import javax.swing.table.TableColumnModel;
|
34 |
import javax.swing.table.TableColumnModel;
|
33 |
import javax.swing.table.TableModel;
|
35 |
import javax.swing.table.TableModel;
|
- |
|
36 |
import javax.xml.XMLConstants;
|
34 |
import javax.xml.parsers.DocumentBuilder;
|
37 |
import javax.xml.parsers.DocumentBuilder;
|
35 |
import javax.xml.parsers.DocumentBuilderFactory;
|
38 |
import javax.xml.parsers.DocumentBuilderFactory;
|
36 |
import javax.xml.parsers.ParserConfigurationException;
|
39 |
import javax.xml.parsers.ParserConfigurationException;
|
- |
|
40 |
import javax.xml.transform.OutputKeys;
|
37 |
import javax.xml.transform.Transformer;
|
41 |
import javax.xml.transform.Transformer;
|
38 |
import javax.xml.transform.TransformerException;
|
42 |
import javax.xml.transform.TransformerException;
|
39 |
import javax.xml.transform.TransformerFactory;
|
43 |
import javax.xml.transform.TransformerFactory;
|
40 |
import javax.xml.transform.dom.DOMSource;
|
44 |
import javax.xml.transform.dom.DOMSource;
|
41 |
import javax.xml.transform.stream.StreamResult;
|
45 |
import javax.xml.transform.stream.StreamResult;
|
Line 52... |
Line 56... |
52 |
* @author Sylvain
|
56 |
* @author Sylvain
|
53 |
*/
|
57 |
*/
|
54 |
public class JTableStateManager extends ListenerXMLStateManager<JTable, AncestorListener> {
|
58 |
public class JTableStateManager extends ListenerXMLStateManager<JTable, AncestorListener> {
|
55 |
|
59 |
|
56 |
private static final String VERSION = "20100810";
|
60 |
private static final String VERSION = "20100810";
|
- |
|
61 |
private static final String IDENTIFIER_ATTR = "identifier";
|
- |
|
62 |
private static final String MODEL_INDEX_ATTR = "modelIndex";
|
- |
|
63 |
private static final String SORT_ATTR = "sort";
|
57 |
|
64 |
|
58 |
public JTableStateManager(JTable table) {
|
65 |
public JTableStateManager(JTable table) {
|
59 |
this(table, null);
|
66 |
this(table, null);
|
60 |
}
|
67 |
}
|
61 |
|
68 |
|
Line 70... |
Line 77... |
70 |
@Override
|
77 |
@Override
|
71 |
protected AncestorListener createListener() {
|
78 |
protected AncestorListener createListener() {
|
72 |
return new AncestorListener() {
|
79 |
return new AncestorListener() {
|
73 |
|
80 |
|
74 |
public void ancestorAdded(AncestorEvent event) {
|
81 |
public void ancestorAdded(AncestorEvent event) {
|
- |
|
82 |
// nothing
|
75 |
}
|
83 |
}
|
76 |
|
84 |
|
77 |
public void ancestorMoved(AncestorEvent event) {
|
85 |
public void ancestorMoved(AncestorEvent event) {
|
- |
|
86 |
// nothing
|
78 |
}
|
87 |
}
|
79 |
|
88 |
|
80 |
public void ancestorRemoved(AncestorEvent event) {
|
89 |
public void ancestorRemoved(AncestorEvent event) {
|
81 |
try {
|
90 |
try {
|
82 |
saveState();
|
91 |
saveState();
|
Line 111... |
Line 120... |
111 |
final Element elem = doc.createElement("liste");
|
120 |
final Element elem = doc.createElement("liste");
|
112 |
elem.setAttribute("version", VERSION);
|
121 |
elem.setAttribute("version", VERSION);
|
113 |
doc.appendChild(elem);
|
122 |
doc.appendChild(elem);
|
114 |
|
123 |
|
115 |
final TableColumnModel model = this.getSrc().getColumnModel();
|
124 |
final TableColumnModel model = this.getSrc().getColumnModel();
|
- |
|
125 |
final XTableColumnModel visibilityModel = model instanceof XTableColumnModel ? (XTableColumnModel) model : null;
|
116 |
final TableModel tModel = this.getSrc().getModel();
|
126 |
final TableModel tModel = this.getSrc().getModel();
|
117 |
if (model instanceof XTableColumnModel) {
|
127 |
if (visibilityModel != null) {
|
118 |
final XTableColumnModel visibilityModel = (XTableColumnModel) model;
|
- |
|
119 |
for (final TableColumn col : visibilityModel.getColumns(false)) {
|
128 |
for (final TableColumn col : visibilityModel.getColumns(false)) {
|
120 |
writeCol(elem, col, tModel).setAttribute("visible", String.valueOf(visibilityModel.isColumnVisible(col)));
|
129 |
writeCol(elem, col, tModel).setAttribute("visible", String.valueOf(visibilityModel.isColumnVisible(col)));
|
121 |
}
|
130 |
}
|
122 |
} else {
|
131 |
} else {
|
123 |
final int nCol = this.getSrc().getColumnCount();
|
132 |
final int nCol = this.getSrc().getColumnCount();
|
Line 125... |
Line 134... |
125 |
final TableColumn col = model.getColumn(i);
|
134 |
final TableColumn col = model.getColumn(i);
|
126 |
writeCol(elem, col, tModel);
|
135 |
writeCol(elem, col, tModel);
|
127 |
}
|
136 |
}
|
128 |
}
|
137 |
}
|
129 |
|
138 |
|
- |
|
139 |
if (tModel instanceof TableSorter) {
|
- |
|
140 |
TableSorter sorter = (TableSorter) tModel;
|
- |
|
141 |
final Element sortingColsElem = doc.createElement("sortingColumns");
|
- |
|
142 |
elem.appendChild(sortingColsElem);
|
- |
|
143 |
for (final Directive d : sorter.getSortingColumns()) {
|
- |
|
144 |
final Element colElem = doc.createElement("sortCol");
|
- |
|
145 |
sortingColsElem.appendChild(colElem);
|
- |
|
146 |
final TableColumn col;
|
- |
|
147 |
if (visibilityModel != null) {
|
- |
|
148 |
col = visibilityModel.getColumnByModelIndex(d.getColumn());
|
- |
|
149 |
} else {
|
- |
|
150 |
col = model.getColumn(getSrc().convertColumnIndexToView(d.getColumn()));
|
- |
|
151 |
}
|
- |
|
152 |
colElem.setAttribute(IDENTIFIER_ATTR, String.valueOf(col.getIdentifier()));
|
- |
|
153 |
final int status = d.getDirection();
|
- |
|
154 |
setSortAttribute(colElem, status);
|
- |
|
155 |
}
|
- |
|
156 |
}
|
- |
|
157 |
|
130 |
// Use a Transformer for output
|
158 |
// Use a Transformer for output
|
131 |
final TransformerFactory tFactory = TransformerFactory.newInstance();
|
159 |
final TransformerFactory tFactory = TransformerFactory.newInstance();
|
132 |
try {
|
160 |
try {
|
- |
|
161 |
tFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
133 |
final Transformer transformer = tFactory.newTransformer();
|
162 |
final Transformer transformer = tFactory.newTransformer();
|
- |
|
163 |
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
134 |
transformer.transform(new DOMSource(elem), new StreamResult(out));
|
164 |
transformer.transform(new DOMSource(elem), new StreamResult(out));
|
135 |
} catch (TransformerException e) {
|
165 |
} catch (TransformerException e) {
|
136 |
throw new IOException("Couldn't output " + doc, e);
|
166 |
throw new IOException("Couldn't output " + doc, e);
|
137 |
}
|
167 |
}
|
138 |
}
|
168 |
}
|
Line 144... |
Line 174... |
144 |
int max = col.getMaxWidth();
|
174 |
int max = col.getMaxWidth();
|
145 |
int width = col.getWidth();
|
175 |
int width = col.getWidth();
|
146 |
res.setAttribute("min", String.valueOf(min));
|
176 |
res.setAttribute("min", String.valueOf(min));
|
147 |
res.setAttribute("max", String.valueOf(max));
|
177 |
res.setAttribute("max", String.valueOf(max));
|
148 |
res.setAttribute("width", String.valueOf(width));
|
178 |
res.setAttribute("width", String.valueOf(width));
|
149 |
res.setAttribute("identifier", String.valueOf(col.getIdentifier()));
|
179 |
res.setAttribute(IDENTIFIER_ATTR, String.valueOf(col.getIdentifier()));
|
150 |
res.setAttribute("modelIndex", String.valueOf(col.getModelIndex()));
|
180 |
res.setAttribute(MODEL_INDEX_ATTR, String.valueOf(col.getModelIndex()));
|
151 |
if (tModel instanceof TableSorter) {
|
181 |
return res;
|
152 |
TableSorter sorter = (TableSorter) tModel;
|
182 |
}
|
- |
|
183 |
|
153 |
int status = sorter.getSortingStatus(col.getModelIndex());
|
184 |
protected final void setSortAttribute(final Element res, final int status) {
|
154 |
if (status == TableSorter.ASCENDING) {
|
185 |
if (status == TableSorter.ASCENDING) {
|
155 |
res.setAttribute("sort", "ascending");
|
186 |
res.setAttribute(SORT_ATTR, "ascending");
|
156 |
} else if (status == TableSorter.DESCENDING) {
|
187 |
} else if (status == TableSorter.DESCENDING) {
|
157 |
res.setAttribute("sort", "descending");
|
188 |
res.setAttribute(SORT_ATTR, "descending");
|
158 |
}
|
189 |
}
|
159 |
}
|
190 |
}
|
- |
|
191 |
|
- |
|
192 |
protected final int getSortAttribute(final NamedNodeMap attrs) {
|
- |
|
193 |
final Node sortNode = attrs.getNamedItem(SORT_ATTR);
|
- |
|
194 |
if (sortNode != null) {
|
- |
|
195 |
final String sort = sortNode.getNodeValue();
|
- |
|
196 |
if (sort.equals("ascending")) {
|
- |
|
197 |
return TableSorter.ASCENDING;
|
- |
|
198 |
} else if (sort.equals("descending")) {
|
- |
|
199 |
return TableSorter.DESCENDING;
|
160 |
return res;
|
200 |
} else {
|
- |
|
201 |
Log.get().log(Level.INFO, "ignore unknown sort value : {0}", sort);
|
- |
|
202 |
}
|
- |
|
203 |
}
|
- |
|
204 |
return TableSorter.NOT_SORTED;
|
161 |
}
|
205 |
}
|
162 |
|
206 |
|
163 |
/**
|
207 |
/**
|
164 |
* Met les colonnes comme spécifier dans <code>file</code>. Ne fait rien si <code>file</code>
|
208 |
* Met les colonnes comme spécifier dans <code>file</code>. Ne fait rien si <code>file</code>
|
165 |
* n'existe pas.
|
209 |
* n'existe pas.
|
Line 193... |
Line 237... |
193 |
for (int i = 0; i < colsCount; i++) {
|
237 |
for (int i = 0; i < colsCount; i++) {
|
194 |
visibilityModel.setColumnVisible(visibilityModel.getColumn(i, false), true);
|
238 |
visibilityModel.setColumnVisible(visibilityModel.getColumn(i, false), true);
|
195 |
}
|
239 |
}
|
196 |
}
|
240 |
}
|
197 |
final TableModel tModel = this.getSrc().getModel();
|
241 |
final TableModel tModel = this.getSrc().getModel();
|
198 |
final List<TableColumn> invisibleCols = new ArrayList<TableColumn>();
|
242 |
final List<TableColumn> invisibleCols = new ArrayList<>();
|
199 |
for (int i = 0; i < colsCount; i++) {
|
243 |
for (int i = 0; i < colsCount; i++) {
|
200 |
final NamedNodeMap attrs = listOfCol.item(i).getAttributes();
|
244 |
final NamedNodeMap attrs = listOfCol.item(i).getAttributes();
|
201 |
// index
|
245 |
// index
|
202 |
final int modelIndex = Integer.parseInt(attrs.getNamedItem("modelIndex").getNodeValue());
|
246 |
final int modelIndex = Integer.parseInt(attrs.getNamedItem(MODEL_INDEX_ATTR).getNodeValue());
|
203 |
// move from the current index to the final view index
|
247 |
// move from the current index to the final view index
|
204 |
model.moveColumn(this.getSrc().convertColumnIndexToView(modelIndex), i);
|
248 |
model.moveColumn(this.getSrc().convertColumnIndexToView(modelIndex), i);
|
205 |
|
249 |
|
206 |
final TableColumn modelCol = model.getColumn(i);
|
250 |
final TableColumn modelCol = model.getColumn(i);
|
207 |
|
251 |
|
Line 232... |
Line 276... |
232 |
// don't call setColumnVisible() now since it removes the column and this offsets
|
276 |
// don't call setColumnVisible() now since it removes the column and this offsets
|
233 |
// indexes, only deal will invisible since by now all columns are visible
|
277 |
// indexes, only deal will invisible since by now all columns are visible
|
234 |
if (visible != null && !Boolean.parseBoolean(visible.getNodeValue()))
|
278 |
if (visible != null && !Boolean.parseBoolean(visible.getNodeValue()))
|
235 |
invisibleCols.add(modelCol);
|
279 |
invisibleCols.add(modelCol);
|
236 |
|
280 |
|
- |
|
281 |
// Better not to restore sorting at all, than to restore wrong sorting. So remove
|
- |
|
282 |
// the code that was here since it didn't restore the order of the sorting columns
|
- |
|
283 |
// (e.g. first sort by country, then by age).
|
- |
|
284 |
}
|
- |
|
285 |
|
237 |
// Sorting
|
286 |
// Sorting
|
- |
|
287 |
final NodeList listOfSortCol = doc.getElementsByTagName("sortCol");
|
- |
|
288 |
final int sortColCount = listOfSortCol.getLength();
|
- |
|
289 |
if (tModel instanceof TableSorter && sortColCount > 0) {
|
- |
|
290 |
final List<Directive> sortingCols = new ArrayList<>();
|
- |
|
291 |
for (int i = 0; i < sortColCount; i++) {
|
- |
|
292 |
final NamedNodeMap attrs = listOfSortCol.item(i).getAttributes();
|
238 |
|
293 |
|
239 |
if (tModel instanceof TableSorter) {
|
- |
|
240 |
final TableSorter sorter = (TableSorter) tModel;
|
294 |
final String colID = attrs.getNamedItem(IDENTIFIER_ATTR).getNodeValue();
|
241 |
final Node sortNode = attrs.getNamedItem("sort");
|
295 |
final int colIndex;
|
242 |
if (sortNode != null) {
|
296 |
try {
|
243 |
String sort = sortNode.getNodeValue();
|
297 |
colIndex = model.getColumnIndex(colID);
|
244 |
if (sort != null) {
|
298 |
} catch (Exception e) {
|
245 |
if (sort.equals("ascending")) {
|
299 |
Log.get().log(Level.INFO, "ignore unknown identifier : " + colID, e);
|
246 |
sorter.setSortingStatus(modelIndex, TableSorter.ASCENDING);
|
300 |
continue;
|
247 |
} else if (sort.equals("descending")) {
|
301 |
}
|
248 |
sorter.setSortingStatus(modelIndex, TableSorter.DESCENDING);
|
302 |
final int modelIndex = model.getColumn(colIndex).getModelIndex();
|
249 |
} else {
|
303 |
final int direction = getSortAttribute(attrs);
|
250 |
sorter.setSortingStatus(modelIndex, TableSorter.NOT_SORTED);
|
304 |
if (direction == TableSorter.NOT_SORTED) {
|
251 |
}
|
305 |
Log.get().info("ignore sort value for column " + colID);
|
252 |
}
|
306 |
continue;
|
253 |
}
|
307 |
}
|
- |
|
308 |
sortingCols.add(new Directive(modelIndex, direction));
|
254 |
}
|
309 |
}
|
255 |
|
- |
|
- |
|
310 |
((TableSorter) tModel).setSortingColumns(sortingCols);
|
256 |
}
|
311 |
}
|
257 |
if (visibilityModel != null) {
|
312 |
if (visibilityModel != null) {
|
258 |
for (final TableColumn toRm : invisibleCols) {
|
313 |
for (final TableColumn toRm : invisibleCols) {
|
259 |
visibilityModel.setColumnVisible(toRm, false);
|
314 |
visibilityModel.setColumnVisible(toRm, false);
|
260 |
}
|
315 |
}
|
Line 269... |
Line 324... |
269 |
// be wrongfully restored in the first step.
|
324 |
// be wrongfully restored in the first step.
|
270 |
private boolean checkIdentifiers(NodeList listOfCol, List<TableColumn> uiCols) {
|
325 |
private boolean checkIdentifiers(NodeList listOfCol, List<TableColumn> uiCols) {
|
271 |
final int colsCount = listOfCol.getLength();
|
326 |
final int colsCount = listOfCol.getLength();
|
272 |
for (int i = 0; i < colsCount; i++) {
|
327 |
for (int i = 0; i < colsCount; i++) {
|
273 |
final NamedNodeMap attrs = listOfCol.item(i).getAttributes();
|
328 |
final NamedNodeMap attrs = listOfCol.item(i).getAttributes();
|
274 |
final int modelIndex = Integer.parseInt(attrs.getNamedItem("modelIndex").getNodeValue());
|
329 |
final int modelIndex = Integer.parseInt(attrs.getNamedItem(MODEL_INDEX_ATTR).getNodeValue());
|
275 |
final String xmlID = attrs.getNamedItem("identifier").getNodeValue();
|
330 |
final String xmlID = attrs.getNamedItem(IDENTIFIER_ATTR).getNodeValue();
|
276 |
final String uiID = String.valueOf(uiCols.get(modelIndex).getIdentifier());
|
331 |
final String uiID = String.valueOf(uiCols.get(modelIndex).getIdentifier());
|
277 |
if (!uiID.equals(xmlID))
|
332 |
if (!uiID.equals(xmlID))
|
278 |
return false;
|
333 |
return false;
|
279 |
}
|
334 |
}
|
280 |
return true;
|
335 |
return true;
|