/******************************************************************************* * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.spreadsheet.ui; import java.awt.Color; import java.awt.Font; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.table.DefaultTableModel; import org.simantics.spreadsheet.ClientModel; import org.simantics.spreadsheet.ClientModel.ClientModelListener; import org.simantics.spreadsheet.OperationMode; import org.simantics.spreadsheet.Spreadsheets; import org.simantics.spreadsheet.solver.SpreadsheetStyle; import org.simantics.spreadsheet.util.SpreadsheetUtils; import org.simantics.ui.colors.Colors; import org.simantics.ui.fonts.Fonts; import org.simantics.utils.threads.AWTThread; final public class ClientTableModel extends DefaultTableModel { private static final long serialVersionUID = 226747623479756815L; private final ClientModel model; public ClientTableModel(ClientModel model) { this.model = model; } public void setModel(final SpreadsheetModel model) { final SpreadsheetTable table = model.getTable(); this.model.addListener(new ClientModelListener() { private AtomicBoolean dirtyStructure = new AtomicBoolean(false); private AtomicBoolean dirtyHeaderSizes = new AtomicBoolean(false); private AtomicBoolean dirtyValues = new AtomicBoolean(false); private AtomicBoolean dirtySources = new AtomicBoolean(false); @Override public void columnLabels(String[] labels) { dirtyStructure.set(true); } @Override public void rowLabels(String[] labels) { dirtyStructure.set(true); } @Override public void rows(int amount) { dirtyStructure.set(true); } @Override public void columns(int amount) { dirtyStructure.set(true); } @Override public void sources(final String[] available, final String current) { dirtySources.set(true); } @Override public void columnWidths(int[] widths) { dirtyHeaderSizes.set(true); } @Override public void cleared(String location) { dirtyValues.set(true); } @Override public void propertyChange(String location, String property, Object value) { dirtyValues.set(true); } @Override public void flush() { final boolean structure = dirtyStructure.compareAndSet(true, false); final boolean values = dirtyValues.compareAndSet(true, false); final boolean headerSizes = dirtyHeaderSizes.compareAndSet(true, false); final boolean sources = dirtySources.compareAndSet(true, false); if(sources) { AWTThread.getThreadAccess().asyncExec(new Runnable() { @Override public void run() { model.setSources(); } }); } if (Spreadsheet.DEBUG) System.out.println("ClientTableModel.ClientModelListener.flush: structure=" + structure + ", values=" + values + ", headerSizes=" + headerSizes); if(structure || values || headerSizes) { AWTThread.getThreadAccess().asyncExec(new Runnable() { @Override public void run() { int[] cc = table.getSelectedColumns(); int[] rc = table.getSelectedRows(); if(structure) fireTableStructureChanged(); if(values) fireTableDataChanged(); if (headerSizes) table.applyHeaderSizes(ClientTableModel.this.model); if(rc.length == 1 && cc.length == 1) { table.setColumnSelectionInterval(cc[0], cc[0]); table.setRowSelectionInterval(rc[0], rc[0]); } } }); } } }); } @Override public Object getValueAt(int row, int column) { String location = Spreadsheets.cellName(row, column); // System.out.println("CellValue for location " + location); Color foregroundColor = null; Color backgroundColor = null; Font font = null; int borderValue = 0; int alignValue = 0; String formatString = null; int formatIndex = 0; SpreadsheetStyle style = model.getPropertyAt(location, "style"); if (style != null) { foregroundColor = style.foreground != null ? Colors.awt(style.foreground) : null; backgroundColor = style.background != null ? Colors.awt(style.background) : null; font = style.font != null ? Fonts.awt(style.font) : null; alignValue = style.align; borderValue = style.border; formatString = style.formatString; formatIndex = style.formatIndex; } Boolean editable = model.getPropertyAt(location, "editable"); boolean editableValue = editable != null ? editable : false; OperationMode currentMode = model.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT); if (!OperationMode.OPERATION.equals(currentMode)) editableValue = true; return new CellValue(SpreadsheetUtils.getFormattedLabel(model, row, column, formatIndex, formatString), font, foregroundColor, backgroundColor, borderValue, alignValue, editableValue); } @Override public int getColumnCount() { return model.getColumns(); } @Override public String getColumnName(int column) { String[] names = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_LABELS); if(column < names.length) return names[column]; else return super.getColumnName(column); } @Override public int getRowCount() { //TODO: haxx for initialization if(model == null) return 0; return model.getRows(); } // void applyHeaderSizes() { // // } // //// synchronized void applyDimensions() { //// //// boolean fitRows = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_FIT_ROWS); //// boolean fitColumns = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_FIT_COLS); //// //// int currentRows = getRowCount(); //// int currentCols = getColumnCount(); //// //// int maxRow = model.getRows(); //// int maxColumn = model.getColumns(); //// //// int rowCount = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_ROW_COUNT); //// int columnCount = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_COL_COUNT); //// //// if(Spreadsheet.DEBUG) { //// System.out.println("SimpleContainerTableModel.applyDimensions " + Thread.currentThread().getName()); //// System.out.println("-current model rows " + currentRows); //// System.out.println("-current model cols " + currentCols); ////// if(listener != null) { ////// System.out.println("-current table rows " + table.getRowModel().getSize()); ////// System.out.println("-current table cols " + table.getColumnModel().getColumnCount()); ////// } //// System.out.println("-target rows " + rowCount); //// System.out.println("-target cols " + columnCount); //// System.out.println("-fit rows " + fitRows); //// System.out.println("-fit cols " + fitColumns); //// } //// //// if(fitRows) { //// if(maxRow != currentRows) { //// setRowCount(maxRow); //// if(table != null) table.getRowModel().setSize(maxRow); //// setColumnWidths(); //// } //// } else { //// if(rowCount != currentRows) { //// setRowCount(rowCount); //// if(table != null) table.getRowModel().setSize(rowCount); //// setColumnWidths(); //// } //// } //// if(fitColumns) { //// if(maxColumn != currentCols) { //// setColumnCount(maxColumn); ////// applyLabels(); //// setColumnWidths(); //// } //// } else { //// if(columnCount != currentCols) { //// setColumnCount(columnCount); ////// applyLabels(); //// setColumnWidths(); //// } //// } //// //// } // //// private synchronized void applyLabels() { //// //// if(Spreadsheet.DEBUG) System.out.println("SimpleContainerTableModel.applyLabels"); //// //// for(Map.Entry> e : cells.entrySet()) { //// String location = e.getKey(); //// Range r = SpreadsheetUtils.decodeCellAbsolute(location); //// if(r.startRow >= getRowCount() || r.startColumn >= getColumnCount()) continue; //// String label = (String)e.getValue().get("Label"); //// if(Spreadsheet.DEBUG) System.out.println("setLabel '" + label + "' at " + location + " " + getRowCount() + " " + getColumnCount()); //// setValueAt(label, r.startRow, r.startColumn); //// } //// //// } // // private synchronized void setColumnWidths() { // // if(Spreadsheet.DEBUG) System.out.println("SimpleContainerTableModel.setColumnWidths"); // // if(table != null) { // // int[] columnWidths = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_WIDTHS); // // int columnCount = table.getColumnModel().getColumnCount(); // // for(int i = 0; i < columnWidths.length && i < columnCount ; i++) // { // TableColumn column = table.getColumnModel().getColumn(i); // int preferred = columnWidths[i]; // if(preferred > 0) // column.setPreferredWidth(preferred); // } // // } // // } // // synchronized String[] createColumnIdentifiers(String[] defined) { // // int currentCols = getColumnCount(); // String[] identifiers = new String[currentCols]; // int i=0; // for(;i