--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.spreadsheet.ui;\r
+\r
+import java.awt.Font;\r
+import java.awt.Point;\r
+import java.awt.Rectangle;\r
+import java.awt.event.KeyEvent;\r
+import java.util.Arrays;\r
+\r
+import javax.swing.DefaultListModel;\r
+import javax.swing.JList;\r
+import javax.swing.KeyStroke;\r
+import javax.swing.event.ChangeEvent;\r
+import javax.swing.event.ListSelectionEvent;\r
+import javax.swing.table.TableCellEditor;\r
+import javax.swing.table.TableColumn;\r
+import javax.swing.table.TableColumnModel;\r
+\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.swing.JTableSG;\r
+import org.simantics.spreadsheet.CellEditor;\r
+import org.simantics.spreadsheet.ClientModel;\r
+import org.simantics.spreadsheet.ClientModel.OperationMode;\r
+\r
+public class SpreadsheetTable extends JTableSG {\r
+ \r
+ public static final String uiClassID = "SpreadsheetTableUI"; \r
+ \r
+ final private CellEditor cellEditor;\r
+ private ClientModel clientModel;\r
+ private final DefaultListModel rowModel;\r
+ private final JList rowHeader;\r
+ \r
+ private static final long serialVersionUID = -4592686559195294773L;\r
+\r
+ @Override\r
+ public int getRowHeight() {\r
+ Font font = getFont();\r
+ if(font != null) {\r
+ return font.getSize() + 4;\r
+ } else {\r
+ return super.getRowHeight();\r
+ }\r
+ }\r
+ \r
+ \r
+ public SpreadsheetTable(final INode node, final CellEditor cellEditor, final ClientModel clientModel, final DefaultListModel rowModel) {\r
+\r
+ super(new ClientTableModel(clientModel), node);\r
+ \r
+ this.rowHeader = null;\r
+ this.cellEditor = cellEditor;\r
+ this.clientModel = clientModel;\r
+ this.rowModel = rowModel;\r
+ \r
+// ((ClientTableModel)getModel()).setTable(this);\r
+// \r
+// InputMap im = this.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\r
+// Action deleteAction = new AbstractAction() {\r
+// public void actionPerformed(ActionEvent ae) {\r
+// System.out.println("deleteaction");\r
+// RemoveCellHandler removeHandler = serverInterface.getAdapter(RemoveCellHandler.class);\r
+// int[] rowSelection = getSelectedRows();\r
+// int[] columnSelection = getSelectedColumns();\r
+// for (int i = 0; i < columnSelection.length; i++) {\r
+// for (int j = 0; j < rowSelection.length; j++) {\r
+// int row = rowSelection[j];\r
+// int column = columnSelection[i];\r
+// System.out.println("deleteaction " + row + " " + column);\r
+// Object cell = getValueAt(row, column);\r
+//// RemoveHandler remove = cell.getAdapter(RemoveHandler.class);\r
+//// remove.handle();\r
+// }\r
+// }\r
+// }\r
+// };\r
+// KeyStroke delete = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);\r
+// im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), delete);\r
+// getActionMap().put(im.get(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)), deleteAction);\r
+ \r
+ setDefaultRenderer(Object.class, new Renderer());\r
+ \r
+ setShowGrid(false);\r
+ setRowMargin(0);\r
+ \r
+ }\r
+\r
+ public SpreadsheetTable(final INode node, final CellEditor cellEditor, final ClientModel clientModel, final DefaultListModel rowModel, JList rowHeader) {\r
+\r
+ super(new ClientTableModel(clientModel), node);\r
+ \r
+ this.rowHeader = rowHeader;\r
+ this.cellEditor = cellEditor;\r
+ this.clientModel = clientModel;\r
+ this.rowModel = rowModel;\r
+ setDefaultRenderer(Object.class, new Renderer());\r
+ \r
+ setShowGrid(false);\r
+ setRowMargin(0);\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public Rectangle getCellRect(int row, int column, boolean includeSpacing) {\r
+ if (clientModel != null) {\r
+ Rectangle span = clientModel.getSpan(row, column);\r
+ if (span != null) {\r
+ Rectangle rect1 = super.getCellRect(span.y, span.x, includeSpacing);\r
+ Rectangle rect2 = super.getCellRect(span.y + span.height - 1, span.x + span.width - 1, includeSpacing);\r
+ return rect1.union(rect2);\r
+ }\r
+ }\r
+ return super.getCellRect(row, column, includeSpacing);\r
+ }\r
+\r
+ @Override\r
+ public String getUIClassID() {\r
+ return uiClassID;\r
+ } \r
+ \r
+ @Override \r
+ public int rowAtPoint(Point p) {\r
+ int row = super.rowAtPoint(p);\r
+ if (row == -1) {\r
+ return -1;\r
+ }\r
+ int column = super.columnAtPoint(p);\r
+ Rectangle span = clientModel.getSpan(row, column);\r
+ if (span != null) {\r
+ return span.y;\r
+ } else {\r
+ return row;\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public int columnAtPoint(Point p) {\r
+ int column = super.columnAtPoint(p);\r
+ if (column == -1) {\r
+ return -1;\r
+ }\r
+ int row = super.rowAtPoint(p);\r
+ Rectangle span = clientModel.getSpan(row, column);\r
+ if (span != null) {\r
+ return span.x;\r
+ } else {\r
+ return column;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void valueChanged(ListSelectionEvent e) {\r
+ super.valueChanged(e);\r
+ repaint();\r
+ }\r
+\r
+ @Override\r
+ public void columnSelectionChanged(ListSelectionEvent e) {\r
+ super.columnSelectionChanged(e);\r
+ repaint();\r
+ }\r
+\r
+ \r
+ public ClientModel getClientModel() {\r
+ return clientModel;\r
+ }\r
+\r
+ // wrapper function for SpreadsheetTableUI\r
+ protected int rowAtPointWithoutSpan(Point p) {\r
+ return super.rowAtPoint(p);\r
+ } \r
+\r
+ // wrapper function for SpreadsheetTableUI \r
+ protected int columnAtPointWithoutSpan(Point p) {\r
+ return super.columnAtPoint(p);\r
+ } \r
+ \r
+ @Override\r
+ protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {\r
+ // turn off edit but still can cause actions\r
+ if (e.getKeyCode()==KeyEvent.VK_DELETE) {\r
+ //System.out.println("processKeyBinding delete");\r
+ this.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);\r
+ boolean retvalue = super.processKeyBinding(ks, e, condition, pressed);\r
+ this.putClientProperty("JTable.autoStartsEdit", Boolean.TRUE);\r
+ return retvalue;\r
+ }\r
+ boolean retValue = super.processKeyBinding(ks, e, condition, pressed);\r
+ return retValue;\r
+ }\r
+ \r
+ @Override\r
+ public TableCellEditor getCellEditor(int row, int column) {\r
+ \r
+// CellEditor editor = serverInterface.getAdapter(CellEditor.class);\r
+ if(cellEditor == null) return null;\r
+ \r
+ boolean editable = false;\r
+ OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);\r
+ if (!OperationMode.OPERATION.equals(mode))\r
+ editable = true;\r
+ \r
+ \r
+ CellValue cellValue = (CellValue)getValueAt(row, column);\r
+ editable = cellValue.editable;\r
+ if (editable) {\r
+ String initial = ((CellValue)getValueAt(row, column)).label;\r
+ return new TextTableCellEditor(row, column, initial, cellEditor, clientModel);\r
+ } else {\r
+ return null;\r
+ }\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void editingStopped(ChangeEvent e) {\r
+ // Take in the new value\r
+ SpreadsheetCellEditor editor = (SpreadsheetCellEditor)getCellEditor();\r
+ if (editor != null) {\r
+ int[] rc = getSelectedRows();\r
+ editor.commit();\r
+ removeEditor();\r
+ if(rc.length == 1 && rc[0] < getRowCount() - 1)\r
+ setRowSelectionInterval(rc[0]+1, rc[0]+1);\r
+ }\r
+ }\r
+\r
+ public void applyRowLabels(String[] rowLabels) {\r
+ \r
+ if(Spreadsheet.DEBUG) System.out.println("Apply row labels: " + Arrays.toString(rowLabels));\r
+ \r
+ rowModel.ensureCapacity(rowLabels.length);\r
+ int i=0;\r
+ for(;i<rowLabels.length && i<rowModel.size();i++) {\r
+ rowModel.setElementAt(rowLabels[i], i);\r
+ }\r
+ for(;i<rowLabels.length;i++) {\r
+ rowModel.addElement(rowLabels[i]);\r
+ }\r
+ \r
+ }\r
+\r
+ public void applyHeaderSizes(ClientModel clientModel) {\r
+ \r
+ // TODO: initialization haxx\r
+ if(clientModel == null) return;\r
+ \r
+ int[] rows = clientModel.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_ROW_HEIGHTS);\r
+ int[] cols = clientModel.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_WIDTHS);\r
+ \r
+ for(int i = 0; i < getColumnModel().getColumnCount() && i < cols.length ; i++) { \r
+ TableColumn column = getColumnModel().getColumn(i);\r
+ int preferred = cols[i];\r
+ if(preferred > 0)\r
+ column.setPreferredWidth(preferred); \r
+ }\r
+\r
+ if(rowHeader!=null)\r
+ rowHeader.setCellRenderer(new RowHeaderRenderer(this));\r
+ \r
+ for(int i = 0; i<getRowCount() && i<rows.length ;i++) {\r
+ if (rows[i] > 0) {\r
+ setRowHeight(i, rows[i]);\r
+ }\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void createDefaultColumnsFromModel() {\r
+ super.createDefaultColumnsFromModel();\r
+ applyHeaderSizes(clientModel);\r
+ }\r
+ \r
+ @Override\r
+ protected TableColumnModel createDefaultColumnModel() {\r
+ TableColumnModel model = super.createDefaultColumnModel();\r
+ model.setColumnMargin(0);\r
+ return model; \r
+ }\r
+ \r
+}\r