1 /*******************************************************************************
\r
2 * in Industry THTH ry.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.spreadsheet.ui;
\r
13 import java.awt.Color;
\r
14 import java.awt.Font;
\r
15 import java.util.concurrent.atomic.AtomicBoolean;
\r
17 import javax.swing.table.DefaultTableModel;
\r
19 import org.simantics.spreadsheet.ClientModel;
\r
20 import org.simantics.spreadsheet.ClientModel.ClientModelListener;
\r
21 import org.simantics.spreadsheet.ClientModel.OperationMode;
\r
22 import org.simantics.spreadsheet.graph.SpreadsheetStyle;
\r
23 import org.simantics.spreadsheet.util.SpreadsheetUtils;
\r
24 import org.simantics.ui.colors.Colors;
\r
25 import org.simantics.ui.fonts.Fonts;
\r
26 import org.simantics.utils.threads.AWTThread;
\r
28 final public class ClientTableModel extends DefaultTableModel {
\r
30 private static final long serialVersionUID = 226747623479756815L;
\r
31 private final ClientModel model;
\r
33 public ClientTableModel(ClientModel model) {
\r
37 public void setModel(final SpreadsheetModel model) {
\r
39 final SpreadsheetTable table = model.getTable();
\r
41 this.model.addListener(new ClientModelListener() {
\r
43 private AtomicBoolean dirtyStructure = new AtomicBoolean(false);
\r
44 private AtomicBoolean dirtyHeaderSizes = new AtomicBoolean(false);
\r
45 private AtomicBoolean dirtyValues = new AtomicBoolean(false);
\r
46 private AtomicBoolean dirtySources = new AtomicBoolean(false);
\r
49 public void columnLabels(String[] labels) {
\r
50 dirtyStructure.set(true);
\r
54 public void rowLabels(String[] labels) {
\r
55 dirtyStructure.set(true);
\r
59 public void rows(int amount) {
\r
60 dirtyStructure.set(true);
\r
64 public void columns(int amount) {
\r
65 dirtyStructure.set(true);
\r
69 public void sources(final String[] available, final String current) {
\r
70 dirtySources.set(true);
\r
74 public void columnWidths(int[] widths) {
\r
75 dirtyHeaderSizes.set(true);
\r
79 public void cleared(String location) {
\r
80 dirtyValues.set(true);
\r
84 public void propertyChange(String location, String property, Object value) {
\r
85 dirtyValues.set(true);
\r
89 public void flush() {
\r
91 final boolean structure = dirtyStructure.compareAndSet(true, false);
\r
92 final boolean values = dirtyValues.compareAndSet(true, false);
\r
93 final boolean headerSizes = dirtyHeaderSizes.compareAndSet(true, false);
\r
94 final boolean sources = dirtySources.compareAndSet(true, false);
\r
97 AWTThread.getThreadAccess().asyncExec(new Runnable() {
\r
101 model.setSources();
\r
107 if (Spreadsheet.DEBUG)
\r
108 System.out.println("ClientTableModel.ClientModelListener.flush: structure=" + structure + ", values=" + values + ", headerSizes=" + headerSizes);
\r
110 if(structure || values || headerSizes) {
\r
112 AWTThread.getThreadAccess().asyncExec(new Runnable() {
\r
115 public void run() {
\r
117 int[] cc = table.getSelectedColumns();
\r
118 int[] rc = table.getSelectedRows();
\r
120 if(structure) fireTableStructureChanged();
\r
121 if(values) fireTableDataChanged();
\r
124 table.applyHeaderSizes(ClientTableModel.this.model);
\r
126 if(rc.length == 1 && cc.length == 1) {
\r
127 table.setColumnSelectionInterval(cc[0], cc[0]);
\r
128 table.setRowSelectionInterval(rc[0], rc[0]);
\r
144 public Object getValueAt(int row, int column) {
\r
145 String location = SpreadsheetUtils.cellName(row, column);
\r
147 // System.out.println("CellValue for location " + location);
\r
149 Color foregroundColor = null;
\r
150 Color backgroundColor = null;
\r
152 int borderValue = 0;
\r
153 int alignValue = 0;
\r
154 String formatString = null;
\r
155 int formatIndex = 0;
\r
156 SpreadsheetStyle style = model.getPropertyAt(location, "style");
\r
157 if (style != null) {
\r
158 foregroundColor = style.foreground != null ? Colors.awt(style.foreground) : null;
\r
159 backgroundColor = style.background != null ? Colors.awt(style.background) : null;
\r
160 font = style.font != null ? Fonts.awt(style.font) : null;
\r
161 alignValue = style.align;
\r
162 borderValue = style.border;
\r
164 formatString = style.formatString;
\r
165 formatIndex = style.formatIndex;
\r
168 Boolean editable = model.getPropertyAt(location, "editable");
\r
169 boolean editableValue = editable != null ? editable : false;
\r
171 OperationMode currentMode = model.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
\r
172 if (!OperationMode.OPERATION.equals(currentMode))
\r
173 editableValue = true;
\r
175 return new CellValue(SpreadsheetUtils.getFormattedLabel(model, row, column, formatIndex, formatString), font, foregroundColor, backgroundColor, borderValue, alignValue, editableValue);
\r
179 public int getColumnCount() {
\r
180 return model.getColumns();
\r
184 public String getColumnName(int column) {
\r
185 String[] names = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_LABELS);
\r
186 if(column < names.length) return names[column];
\r
187 else return super.getColumnName(column);
\r
191 public int getRowCount() {
\r
192 //TODO: haxx for initialization
\r
193 if(model == null) return 0;
\r
194 return model.getRows();
\r
197 // void applyHeaderSizes() {
\r
201 //// synchronized void applyDimensions() {
\r
203 //// boolean fitRows = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_FIT_ROWS);
\r
204 //// boolean fitColumns = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_FIT_COLS);
\r
206 //// int currentRows = getRowCount();
\r
207 //// int currentCols = getColumnCount();
\r
209 //// int maxRow = model.getRows();
\r
210 //// int maxColumn = model.getColumns();
\r
212 //// int rowCount = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_ROW_COUNT);
\r
213 //// int columnCount = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_COL_COUNT);
\r
215 //// if(Spreadsheet.DEBUG) {
\r
216 //// System.out.println("SimpleContainerTableModel.applyDimensions " + Thread.currentThread().getName());
\r
217 //// System.out.println("-current model rows " + currentRows);
\r
218 //// System.out.println("-current model cols " + currentCols);
\r
219 ////// if(listener != null) {
\r
220 ////// System.out.println("-current table rows " + table.getRowModel().getSize());
\r
221 ////// System.out.println("-current table cols " + table.getColumnModel().getColumnCount());
\r
223 //// System.out.println("-target rows " + rowCount);
\r
224 //// System.out.println("-target cols " + columnCount);
\r
225 //// System.out.println("-fit rows " + fitRows);
\r
226 //// System.out.println("-fit cols " + fitColumns);
\r
230 //// if(maxRow != currentRows) {
\r
231 //// setRowCount(maxRow);
\r
232 //// if(table != null) table.getRowModel().setSize(maxRow);
\r
233 //// setColumnWidths();
\r
236 //// if(rowCount != currentRows) {
\r
237 //// setRowCount(rowCount);
\r
238 //// if(table != null) table.getRowModel().setSize(rowCount);
\r
239 //// setColumnWidths();
\r
242 //// if(fitColumns) {
\r
243 //// if(maxColumn != currentCols) {
\r
244 //// setColumnCount(maxColumn);
\r
245 ////// applyLabels();
\r
246 //// setColumnWidths();
\r
249 //// if(columnCount != currentCols) {
\r
250 //// setColumnCount(columnCount);
\r
251 ////// applyLabels();
\r
252 //// setColumnWidths();
\r
258 //// private synchronized void applyLabels() {
\r
260 //// if(Spreadsheet.DEBUG) System.out.println("SimpleContainerTableModel.applyLabels");
\r
262 //// for(Map.Entry<String, HashMap<String, Object>> e : cells.entrySet()) {
\r
263 //// String location = e.getKey();
\r
264 //// Range r = SpreadsheetUtils.decodeCellAbsolute(location);
\r
265 //// if(r.startRow >= getRowCount() || r.startColumn >= getColumnCount()) continue;
\r
266 //// String label = (String)e.getValue().get("Label");
\r
267 //// if(Spreadsheet.DEBUG) System.out.println("setLabel '" + label + "' at " + location + " " + getRowCount() + " " + getColumnCount());
\r
268 //// setValueAt(label, r.startRow, r.startColumn);
\r
273 // private synchronized void setColumnWidths() {
\r
275 // if(Spreadsheet.DEBUG) System.out.println("SimpleContainerTableModel.setColumnWidths");
\r
277 // if(table != null) {
\r
279 // int[] columnWidths = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_WIDTHS);
\r
281 // int columnCount = table.getColumnModel().getColumnCount();
\r
283 // for(int i = 0; i < columnWidths.length && i < columnCount ; i++)
\r
285 // TableColumn column = table.getColumnModel().getColumn(i);
\r
286 // int preferred = columnWidths[i];
\r
287 // if(preferred > 0)
\r
288 // column.setPreferredWidth(preferred);
\r
295 // synchronized String[] createColumnIdentifiers(String[] defined) {
\r
297 // int currentCols = getColumnCount();
\r
298 // String[] identifiers = new String[currentCols];
\r
300 // for(;i<defined.length && i<currentCols;i++) {
\r
301 // identifiers[i] = defined[i];
\r
303 // for(;i<currentCols;i++) {
\r
304 // identifiers[i] = SpreadsheetUtils.columnName(i);
\r
306 // return identifiers;
\r
311 // public String getColumnName(int column) {
\r
312 // new Exception("getColumnName " + column).printStackTrace();
\r
313 // String[] names = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_LABELS);
\r
314 // if(column < names.length) return names[column];
\r
315 // else return super.getColumnName(column);
\r
318 // synchronized void applyHeaders() {
\r
320 // AWTThread.getThreadAccess().asyncExec(new Runnable() {
\r
323 // public void run() {
\r
325 // String[] columnLabels = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_LABELS);
\r
326 // String[] filledColumnLabels = createColumnIdentifiers(columnLabels);
\r
327 // String[] rowLabels = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_ROW_LABELS);
\r
329 // if(Spreadsheet.DEBUG) {
\r
330 // System.out.println("SimpleContainerTableModel.applyHeaders");
\r
331 // System.out.println("-columnLabels=" + Arrays.toString(columnLabels));
\r
332 // System.out.println("-filledColumnLabels=" + Arrays.toString(filledColumnLabels));
\r
333 // System.out.println("-rowLabels=" + Arrays.toString(rowLabels));
\r
336 // setColumnIdentifiers(filledColumnLabels);
\r
338 //// if(listener != null) {
\r
339 //// listener.rowLabels(rowLabels);
\r
342 // if(table != null) {
\r
343 // table.getRowModel().ensureCapacity(rowLabels.length);
\r
345 // for(;i<rowLabels.length && i<table.getRowModel().size();i++) {
\r
346 // table.getRowModel().setElementAt(rowLabels[i], i);
\r
348 // for(;i<rowLabels.length;i++) {
\r
349 // table.getRowModel().addElement(rowLabels[i]);
\r
353 //// applyLabels();
\r