1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.spreadsheet.ui;
15 import java.awt.Point;
16 import java.awt.Rectangle;
17 import java.awt.event.KeyEvent;
18 import java.util.Arrays;
20 import javax.swing.DefaultListModel;
21 import javax.swing.JList;
22 import javax.swing.KeyStroke;
23 import javax.swing.event.ChangeEvent;
24 import javax.swing.event.ListSelectionEvent;
25 import javax.swing.table.TableCellEditor;
26 import javax.swing.table.TableColumn;
27 import javax.swing.table.TableColumnModel;
29 import org.simantics.scenegraph.INode;
30 import org.simantics.scenegraph.swing.JTableSG;
31 import org.simantics.spreadsheet.CellEditor;
32 import org.simantics.spreadsheet.ClientModel;
33 import org.simantics.spreadsheet.ClientModel.OperationMode;
35 public class SpreadsheetTable extends JTableSG {
37 public static final String uiClassID = "SpreadsheetTableUI";
39 final private CellEditor cellEditor;
40 private ClientModel clientModel;
41 private final DefaultListModel rowModel;
42 private final JList rowHeader;
44 private static final long serialVersionUID = -4592686559195294773L;
47 public int getRowHeight() {
48 Font font = getFont();
50 return font.getSize() + 4;
52 return super.getRowHeight();
57 public SpreadsheetTable(final INode node, final CellEditor cellEditor, final ClientModel clientModel, final DefaultListModel rowModel) {
59 super(new ClientTableModel(clientModel), node);
61 this.rowHeader = null;
62 this.cellEditor = cellEditor;
63 this.clientModel = clientModel;
64 this.rowModel = rowModel;
66 // ((ClientTableModel)getModel()).setTable(this);
68 // InputMap im = this.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
69 // Action deleteAction = new AbstractAction() {
70 // public void actionPerformed(ActionEvent ae) {
71 // System.out.println("deleteaction");
72 // RemoveCellHandler removeHandler = serverInterface.getAdapter(RemoveCellHandler.class);
73 // int[] rowSelection = getSelectedRows();
74 // int[] columnSelection = getSelectedColumns();
75 // for (int i = 0; i < columnSelection.length; i++) {
76 // for (int j = 0; j < rowSelection.length; j++) {
77 // int row = rowSelection[j];
78 // int column = columnSelection[i];
79 // System.out.println("deleteaction " + row + " " + column);
80 // Object cell = getValueAt(row, column);
81 //// RemoveHandler remove = cell.getAdapter(RemoveHandler.class);
87 // KeyStroke delete = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
88 // im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), delete);
89 // getActionMap().put(im.get(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)), deleteAction);
91 setDefaultRenderer(Object.class, new Renderer());
98 public SpreadsheetTable(final INode node, final CellEditor cellEditor, final ClientModel clientModel, final DefaultListModel rowModel, JList rowHeader) {
100 super(new ClientTableModel(clientModel), node);
102 this.rowHeader = rowHeader;
103 this.cellEditor = cellEditor;
104 this.clientModel = clientModel;
105 this.rowModel = rowModel;
106 setDefaultRenderer(Object.class, new Renderer());
114 public Rectangle getCellRect(int row, int column, boolean includeSpacing) {
115 if (clientModel != null) {
116 Rectangle span = clientModel.getSpan(row, column);
118 Rectangle rect1 = super.getCellRect(span.y, span.x, includeSpacing);
119 Rectangle rect2 = super.getCellRect(span.y + span.height - 1, span.x + span.width - 1, includeSpacing);
120 return rect1.union(rect2);
123 return super.getCellRect(row, column, includeSpacing);
127 public String getUIClassID() {
132 public int rowAtPoint(Point p) {
133 int row = super.rowAtPoint(p);
137 int column = super.columnAtPoint(p);
138 Rectangle span = clientModel.getSpan(row, column);
147 public int columnAtPoint(Point p) {
148 int column = super.columnAtPoint(p);
152 int row = super.rowAtPoint(p);
153 Rectangle span = clientModel.getSpan(row, column);
162 public void valueChanged(ListSelectionEvent e) {
163 super.valueChanged(e);
168 public void columnSelectionChanged(ListSelectionEvent e) {
169 super.columnSelectionChanged(e);
174 public ClientModel getClientModel() {
178 // wrapper function for SpreadsheetTableUI
179 protected int rowAtPointWithoutSpan(Point p) {
180 return super.rowAtPoint(p);
183 // wrapper function for SpreadsheetTableUI
184 protected int columnAtPointWithoutSpan(Point p) {
185 return super.columnAtPoint(p);
189 protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
190 // turn off edit but still can cause actions
191 if (e.getKeyCode()==KeyEvent.VK_DELETE) {
192 //System.out.println("processKeyBinding delete");
193 this.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
194 boolean retvalue = super.processKeyBinding(ks, e, condition, pressed);
195 this.putClientProperty("JTable.autoStartsEdit", Boolean.TRUE);
198 boolean retValue = super.processKeyBinding(ks, e, condition, pressed);
203 public TableCellEditor getCellEditor(int row, int column) {
205 // CellEditor editor = serverInterface.getAdapter(CellEditor.class);
206 if(cellEditor == null) return null;
208 boolean editable = false;
209 OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
210 if (!OperationMode.OPERATION.equals(mode))
214 CellValue cellValue = (CellValue)getValueAt(row, column);
215 editable = cellValue.editable;
217 String initial = ((CellValue)getValueAt(row, column)).label;
218 return new TextTableCellEditor(row, column, initial, cellEditor, clientModel);
226 public void editingStopped(ChangeEvent e) {
227 // Take in the new value
228 SpreadsheetCellEditor editor = (SpreadsheetCellEditor)getCellEditor();
229 if (editor != null) {
230 int[] rc = getSelectedRows();
233 if(rc.length == 1 && rc[0] < getRowCount() - 1)
234 setRowSelectionInterval(rc[0]+1, rc[0]+1);
238 public void applyRowLabels(String[] rowLabels) {
240 if(Spreadsheet.DEBUG) System.out.println("Apply row labels: " + Arrays.toString(rowLabels));
242 rowModel.ensureCapacity(rowLabels.length);
244 for(;i<rowLabels.length && i<rowModel.size();i++) {
245 rowModel.setElementAt(rowLabels[i], i);
247 for(;i<rowLabels.length;i++) {
248 rowModel.addElement(rowLabels[i]);
253 public void applyHeaderSizes(ClientModel clientModel) {
255 // TODO: initialization haxx
256 if(clientModel == null) return;
258 int[] rows = clientModel.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_ROW_HEIGHTS);
259 int[] cols = clientModel.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_WIDTHS);
261 for(int i = 0; i < getColumnModel().getColumnCount() && i < cols.length ; i++) {
262 TableColumn column = getColumnModel().getColumn(i);
263 int preferred = cols[i];
265 column.setPreferredWidth(preferred);
269 rowHeader.setCellRenderer(new RowHeaderRenderer(this));
271 for(int i = 0; i<getRowCount() && i<rows.length ;i++) {
273 setRowHeight(i, rows[i]);
279 public void createDefaultColumnsFromModel() {
280 super.createDefaultColumnsFromModel();
281 applyHeaderSizes(clientModel);
285 protected TableColumnModel createDefaultColumnModel() {
286 TableColumnModel model = super.createDefaultColumnModel();
287 model.setColumnMargin(0);