/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * 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.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.KeyEvent; import java.util.Arrays; import javax.swing.DefaultListModel; import javax.swing.JList; import javax.swing.KeyStroke; import javax.swing.event.ChangeEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.table.TableCellEditor; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.swing.JTableSG; import org.simantics.spreadsheet.CellEditor; import org.simantics.spreadsheet.ClientModel; import org.simantics.spreadsheet.ClientModel.OperationMode; public class SpreadsheetTable extends JTableSG { public static final String uiClassID = "SpreadsheetTableUI"; final private CellEditor cellEditor; private ClientModel clientModel; private final DefaultListModel rowModel; private final JList rowHeader; private static final long serialVersionUID = -4592686559195294773L; @Override public int getRowHeight() { Font font = getFont(); if(font != null) { return font.getSize() + 4; } else { return super.getRowHeight(); } } public SpreadsheetTable(final INode node, final CellEditor cellEditor, final ClientModel clientModel, final DefaultListModel rowModel) { super(new ClientTableModel(clientModel), node); this.rowHeader = null; this.cellEditor = cellEditor; this.clientModel = clientModel; this.rowModel = rowModel; // ((ClientTableModel)getModel()).setTable(this); // // InputMap im = this.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); // Action deleteAction = new AbstractAction() { // public void actionPerformed(ActionEvent ae) { // System.out.println("deleteaction"); // RemoveCellHandler removeHandler = serverInterface.getAdapter(RemoveCellHandler.class); // int[] rowSelection = getSelectedRows(); // int[] columnSelection = getSelectedColumns(); // for (int i = 0; i < columnSelection.length; i++) { // for (int j = 0; j < rowSelection.length; j++) { // int row = rowSelection[j]; // int column = columnSelection[i]; // System.out.println("deleteaction " + row + " " + column); // Object cell = getValueAt(row, column); //// RemoveHandler remove = cell.getAdapter(RemoveHandler.class); //// remove.handle(); // } // } // } // }; // KeyStroke delete = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0); // im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), delete); // getActionMap().put(im.get(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)), deleteAction); setDefaultRenderer(Object.class, new Renderer()); setShowGrid(false); setRowMargin(0); } public SpreadsheetTable(final INode node, final CellEditor cellEditor, final ClientModel clientModel, final DefaultListModel rowModel, JList rowHeader) { super(new ClientTableModel(clientModel), node); this.rowHeader = rowHeader; this.cellEditor = cellEditor; this.clientModel = clientModel; this.rowModel = rowModel; setDefaultRenderer(Object.class, new Renderer()); setShowGrid(false); setRowMargin(0); } @Override public Rectangle getCellRect(int row, int column, boolean includeSpacing) { if (clientModel != null) { Rectangle span = clientModel.getSpan(row, column); if (span != null) { Rectangle rect1 = super.getCellRect(span.y, span.x, includeSpacing); Rectangle rect2 = super.getCellRect(span.y + span.height - 1, span.x + span.width - 1, includeSpacing); return rect1.union(rect2); } } return super.getCellRect(row, column, includeSpacing); } @Override public String getUIClassID() { return uiClassID; } @Override public int rowAtPoint(Point p) { int row = super.rowAtPoint(p); if (row == -1) { return -1; } int column = super.columnAtPoint(p); Rectangle span = clientModel.getSpan(row, column); if (span != null) { return span.y; } else { return row; } } @Override public int columnAtPoint(Point p) { int column = super.columnAtPoint(p); if (column == -1) { return -1; } int row = super.rowAtPoint(p); Rectangle span = clientModel.getSpan(row, column); if (span != null) { return span.x; } else { return column; } } @Override public void valueChanged(ListSelectionEvent e) { super.valueChanged(e); repaint(); } @Override public void columnSelectionChanged(ListSelectionEvent e) { super.columnSelectionChanged(e); repaint(); } public ClientModel getClientModel() { return clientModel; } // wrapper function for SpreadsheetTableUI protected int rowAtPointWithoutSpan(Point p) { return super.rowAtPoint(p); } // wrapper function for SpreadsheetTableUI protected int columnAtPointWithoutSpan(Point p) { return super.columnAtPoint(p); } @Override protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { // turn off edit but still can cause actions if (e.getKeyCode()==KeyEvent.VK_DELETE) { //System.out.println("processKeyBinding delete"); this.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE); boolean retvalue = super.processKeyBinding(ks, e, condition, pressed); this.putClientProperty("JTable.autoStartsEdit", Boolean.TRUE); return retvalue; } boolean retValue = super.processKeyBinding(ks, e, condition, pressed); return retValue; } @Override public TableCellEditor getCellEditor(int row, int column) { // CellEditor editor = serverInterface.getAdapter(CellEditor.class); if(cellEditor == null) return null; boolean editable = false; OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT); if (!OperationMode.OPERATION.equals(mode)) editable = true; CellValue cellValue = (CellValue)getValueAt(row, column); editable = cellValue.editable; if (editable) { String initial = ((CellValue)getValueAt(row, column)).label; return new TextTableCellEditor(row, column, initial, cellEditor, clientModel); } else { return null; } } @Override public void editingStopped(ChangeEvent e) { // Take in the new value SpreadsheetCellEditor editor = (SpreadsheetCellEditor)getCellEditor(); if (editor != null) { int[] rc = getSelectedRows(); editor.commit(); removeEditor(); if(rc.length == 1 && rc[0] < getRowCount() - 1) setRowSelectionInterval(rc[0]+1, rc[0]+1); } } public void applyRowLabels(String[] rowLabels) { if(Spreadsheet.DEBUG) System.out.println("Apply row labels: " + Arrays.toString(rowLabels)); rowModel.ensureCapacity(rowLabels.length); int i=0; for(;i 0) column.setPreferredWidth(preferred); } if(rowHeader!=null) rowHeader.setCellRenderer(new RowHeaderRenderer(this)); for(int i = 0; i 0) { setRowHeight(i, rows[i]); } } } @Override public void createDefaultColumnsFromModel() { super.createDefaultColumnsFromModel(); applyHeaderSizes(clientModel); } @Override protected TableColumnModel createDefaultColumnModel() { TableColumnModel model = super.createDefaultColumnModel(); model.setColumnMargin(0); return model; } }