1 | package genius.gui.progress;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.LinkedHashMap;
|
---|
5 | import java.util.List;
|
---|
6 | import java.util.Map;
|
---|
7 | import java.util.TreeMap;
|
---|
8 |
|
---|
9 | import javax.swing.table.AbstractTableModel;
|
---|
10 |
|
---|
11 | /**
|
---|
12 | * Table model for showing results that takes {@link DataKey}s to enhance type
|
---|
13 | * checking and support conversion and smart data inserting. This code
|
---|
14 | * determines how data actually is ordered for display. Only adding of rows
|
---|
15 | * (containing one result) is supported.
|
---|
16 | *
|
---|
17 | * @author W.Pasman 16jul15
|
---|
18 | *
|
---|
19 | */
|
---|
20 | public class DataKeyTableModel extends AbstractTableModel {
|
---|
21 | /**
|
---|
22 | *
|
---|
23 | */
|
---|
24 | private static final long serialVersionUID = 49325296249290419L;
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * The column specification - the Integer is the multiplicity of each of the
|
---|
28 | * columns. Note that the default order of the keys is determined by the
|
---|
29 | * order of DataKey.
|
---|
30 | */
|
---|
31 | private final LinkedHashMap<DataKey, Integer> columnSpec;
|
---|
32 |
|
---|
33 | /**
|
---|
34 | * name of the rows
|
---|
35 | */
|
---|
36 | private final List<String> columns = new ArrayList<String>();
|
---|
37 | private final List<List<Object>> rows = new ArrayList<List<Object>>();
|
---|
38 |
|
---|
39 | /**
|
---|
40 | * @param colspec
|
---|
41 | * a {@link TreeMap} containing tuples [DataKey,Integer] that
|
---|
42 | * specifies the columns for the table. The DataKey is the column
|
---|
43 | * to show, the Integer is the maximum multiplicity of that
|
---|
44 | * column. When a column multiplicity has been set to a value
|
---|
45 | * >1, and a row is added that has a {@link List} for that
|
---|
46 | * {@link DataKey}, then the list is expanded to separate
|
---|
47 | * columns. All multiplicities must be ≥ 1.
|
---|
48 | *
|
---|
49 | * The order of the DataKeys determines the order of the columns.
|
---|
50 | */
|
---|
51 | public DataKeyTableModel(LinkedHashMap<DataKey, Integer> colspec) {
|
---|
52 | super();
|
---|
53 | if (colspec.isEmpty()) {
|
---|
54 | throw new IllegalArgumentException("table contains no columns");
|
---|
55 | }
|
---|
56 | columnSpec = colspec;
|
---|
57 | initColumns();
|
---|
58 | }
|
---|
59 |
|
---|
60 | /**
|
---|
61 | * Get the real column names based on the {@link DataKey} and multiplicity
|
---|
62 | * of the {@link #columnSpec}.
|
---|
63 | */
|
---|
64 | private void initColumns() {
|
---|
65 | for (DataKey key : columnSpec.keySet()) {
|
---|
66 | int multiplicity = columnSpec.get(key);
|
---|
67 | if (multiplicity < 1) {
|
---|
68 | throw new IllegalArgumentException("column multiplicity must be >=1, found " + multiplicity);
|
---|
69 | }
|
---|
70 | if (multiplicity > 1) {
|
---|
71 | for (int n = 1; n <= multiplicity; n++) {
|
---|
72 | columns.add(key.getName() + " " + n);
|
---|
73 | }
|
---|
74 | } else {
|
---|
75 | columns.add(key.getName());
|
---|
76 | }
|
---|
77 | }
|
---|
78 | }
|
---|
79 |
|
---|
80 | /**
|
---|
81 | * Adds a row with new values. The values from the [key,value] pairs in the
|
---|
82 | * map are inserted in the correct columns given the headers. When a column
|
---|
83 | * multiplicity has been set to a value >1 for {@link DataKey} K, and the
|
---|
84 | * value for K in the given map is a {@link List}, then the list is expanded
|
---|
85 | * to separate columns.
|
---|
86 | *
|
---|
87 | * @param newValues
|
---|
88 | * a {@link Map} with DataKeys and objects as values.
|
---|
89 | */
|
---|
90 | public void addRow(Map<DataKey, Object> newValues) {
|
---|
91 | List<Object> row = new ArrayList<Object>();
|
---|
92 |
|
---|
93 | for (DataKey key : columnSpec.keySet()) {
|
---|
94 | int multiplicity = columnSpec.get(key);
|
---|
95 | row.addAll(makeColumns(multiplicity, newValues.get(key)));
|
---|
96 | }
|
---|
97 | rows.add(row);
|
---|
98 |
|
---|
99 | fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
|
---|
100 | }
|
---|
101 |
|
---|
102 | /**
|
---|
103 | * Converts an object into exactly #multiplicity objects. if
|
---|
104 | * multiplicity==1, the returned list contains just that object. if
|
---|
105 | * multiplicity>1 but the object is not a list, the list contains the
|
---|
106 | * object as first element and filled out with empty elements.
|
---|
107 | *
|
---|
108 | * If object is a List, then the columns are filled with subsequential
|
---|
109 | * elements from the list. Too short lists lead to empty columns. Too long
|
---|
110 | * lists results in dropped elements.
|
---|
111 | *
|
---|
112 | * @param multiplicity
|
---|
113 | * @param object
|
---|
114 | * @return list with object as first element, or with the contents of object
|
---|
115 | * if object is a list
|
---|
116 | */
|
---|
117 | private ArrayList<Object> makeColumns(int multiplicity, Object object) {
|
---|
118 | List<Object> objList = null;
|
---|
119 | if (object instanceof List) {
|
---|
120 | objList = (List<Object>) object;
|
---|
121 | }
|
---|
122 |
|
---|
123 | ArrayList<Object> result = new ArrayList<Object>();
|
---|
124 | if (multiplicity == 1) {
|
---|
125 | result.add(object);
|
---|
126 | return result;
|
---|
127 | }
|
---|
128 | for (int n = 0; n < multiplicity; n++) {
|
---|
129 | if (objList == null) {
|
---|
130 | if (n == 0) {
|
---|
131 | result.add(object);
|
---|
132 | } else {
|
---|
133 | result.add("");
|
---|
134 | }
|
---|
135 | } else {
|
---|
136 | // object is a list.
|
---|
137 | if (n >= objList.size()) {
|
---|
138 | result.add("");
|
---|
139 | } else {
|
---|
140 | result.add(objList.get(n));
|
---|
141 | }
|
---|
142 | }
|
---|
143 | }
|
---|
144 | return result;
|
---|
145 | }
|
---|
146 |
|
---|
147 | public int getColumnCount() {
|
---|
148 | return columns.size();
|
---|
149 | }
|
---|
150 |
|
---|
151 | public int getRowCount() {
|
---|
152 | return rows.size();
|
---|
153 | }
|
---|
154 |
|
---|
155 | public String getColumnName(int col) {
|
---|
156 | return columns.get(col);
|
---|
157 | }
|
---|
158 |
|
---|
159 | public Object getValueAt(int row, int col) {
|
---|
160 | return rows.get(row).get(col);
|
---|
161 | }
|
---|
162 |
|
---|
163 | }
|
---|