/* ReferenceTable.java created 2007-10-24 * */ package org.signalml.app.view.montage; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.io.IOException; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; import javax.swing.event.TableColumnModelEvent; import javax.swing.table.TableModel; import org.signalml.app.model.montage.ReferenceTableModel; import org.signalml.app.view.common.components.cellrenderers.CenteringTableCellRenderer; import org.signalml.domain.montage.MontageChannel; /** * The table which displays the reference between {@link MontageChannel montage * channels} and original channels. * This table has: * <ul> * <li>no header,</li> * <li>{@link ListSelectionModel#SINGLE_SELECTION single selection} * mode,</li> * <li>{@link #CELL_SIZE} height and width of the cells,</li> * <li>{@link HeaderTable} at the headers of rows and columns,</li> * <li>{@link CornerPanel} at the upper left corner,</li> * <li>{@link ReferenceTableModel} as the model.</li></ul> * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public class ReferenceTable extends JTable implements ActionListener { /** * the default serialization constant */ private static final long serialVersionUID = 1L; /** * the color used if the cell is not editable */ public static final Color DISABLED_COLOR = new Color(220,220,220); /** * the height of the row */ private static final int CELL_SIZE = 35; /** * Constructor. Creates the table: * <ul> * <li>without header,</li> * <li>with the {@link ListSelectionModel#SINGLE_SELECTION single selection} * mode,</li> * <li>with the {@link #CELL_SIZE} height of the row,</li> * <li>without autoresize.</li></ul> * @param model data {@link ReferenceTableModel model} for this table */ public ReferenceTable(ReferenceTableModel model) { super(model); setTableHeader(null); setDefaultRenderer(String.class, new ReferenceTableCellRenderer()); setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); setCellSelectionEnabled(true); setAutoResizeMode(AUTO_RESIZE_OFF); setRowHeight(CELL_SIZE); setToolTipText(""); //hook on 'paste' action KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_V,ActionEvent.CTRL_MASK,false); this.registerKeyboardAction(this,"Paste",paste,JComponent.WHEN_FOCUSED); } /** * Does almost the same as {@link JTable#configureEnclosingScrollPane() * parent method} but: * <ul> * <li>sets {@link HeaderTable} as a column and row header view,</li> * <li>sets the {@link CornerPanel} in the * {@link ScrollPaneConstants#UPPER_LEFT_CORNER upper left corner}.</li> * </ul> */ @Override protected void configureEnclosingScrollPane() { super.configureEnclosingScrollPane(); TableModel model = getModel(); if (!(model instanceof ReferenceTableModel)) { return; } ReferenceTableModel referenceTableModel = (ReferenceTableModel) model; Container p = getParent(); if (p instanceof JViewport) { Container gp = p.getParent(); if (gp instanceof JScrollPane) { JScrollPane scrollPane = (JScrollPane)gp; JViewport viewport = scrollPane.getViewport(); if (viewport == null || viewport.getView() != this) { return; } scrollPane.setColumnHeaderView(new HeaderTable(referenceTableModel.getColumnTableModel())); scrollPane.setRowHeaderView(new HeaderTable(referenceTableModel.getRowTableModel())); scrollPane.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, new CornerPanel()); } } } /** * Does almost the same as {@link JTable#configureEnclosingScrollPane() * parent method} but: * <ul> * <li>sets the row and column headers to {@code null},</li> * <li>sets the corner in * {@link ScrollPaneConstants#UPPER_LEFT_CORNER upper left corner} * to {@code null}.</li> * </ul> */ @Override protected void unconfigureEnclosingScrollPane() { super.unconfigureEnclosingScrollPane(); Container p = getParent(); if (p instanceof JViewport) { Container gp = p.getParent(); if (gp instanceof JScrollPane) { JScrollPane scrollPane = (JScrollPane)gp; JViewport viewport = scrollPane.getViewport(); if (viewport == null || viewport.getView() != this) { return; } scrollPane.setColumnHeaderView(null); scrollPane.setRowHeaderView(null); scrollPane.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, null); } } } /** * Does the same as {@link JTable#columnAdded(TableColumnModelEvent)} and * sets the preferred width of the cell to {@link #CELL_SIZE}. */ @Override public void columnAdded(TableColumnModelEvent e) { super.columnAdded(e); int index = e.getToIndex(); getColumnModel().getColumn(index).setPreferredWidth(CELL_SIZE); } /** * Returns the value of the cell as the text for the tool-tip. */ @Override public String getToolTipText(MouseEvent event) { Point p = event.getPoint(); int row = rowAtPoint(p); int col = columnAtPoint(p); if (row >= 0 && col >= 0) { return (String) getValueAt(row, col); } else { return null; } } /** * The panel used at the corner of the {@link ReferenceTable}. * It is a square with {@link ReferenceTable#DISABLED_COLOR} background * and two lines that separate it from other cells. */ private class CornerPanel extends JPanel { /** * the default serialization constant */ private static final long serialVersionUID = 1L; /** * Constructor. Sets: * <ul><li> the background color to {@link * ReferenceTable#DISABLED_COLOR},</li> * <li>the width and height both to {@link ReferenceTable#CELL_SIZE}. * </li></ul> */ public CornerPanel() { super(); setBackground(DISABLED_COLOR); setPreferredSize(new Dimension(CELL_SIZE,CELL_SIZE)); } /** * {@link JPanel#paintComponents(Graphics) Paints} this component * and two lines that separate it from other cells. */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Dimension size = getSize(); g.setColor(getGridColor()); g.drawLine(0, size.height-1, size.width-1, size.height-1); g.drawLine(size.width-1, 0, size.width-1, size.height-1); } } /** * The table used at the row and column headers in {@link ReferenceTable}. * It has: * <ul> * <li>{@link ReferenceTable#DISABLED_COLOR} as background color,</li> * <li>{@link ListSelectionModel#SINGLE_SELECTION single selection} * mode,</li> * <li>{@link ReferenceTable#CELL_SIZE CELL_SIZE} as the row height and * width,</li> * <li>the values centered in the cell.</li></ul> */ private class HeaderTable extends JTable { /** * the default serialization constant */ private static final long serialVersionUID = 1L; /** * Constructor. Sets: * <ul> * <li>{@link ReferenceTable#DISABLED_COLOR} as background color,</li> * <li>{@link ListSelectionModel#SINGLE_SELECTION single selection} * mode,</li> * <li>that the values are centered,</li> * <li>the row height to {@link ReferenceTable#CELL_SIZE} and no * autoresize.</li> * </ul> * @param dm the data model for the table */ public HeaderTable(TableModel dm) { super(dm); setTableHeader(null); setDefaultRenderer(String.class, new CenteringTableCellRenderer()); setBackground(DISABLED_COLOR); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); setEnabled(false); setAutoResizeMode(AUTO_RESIZE_OFF); setRowHeight(CELL_SIZE); setToolTipText(""); } /** * Returns the value of the cell (the name of the column or the row) * as the tooltip text. */ @Override public String getToolTipText(MouseEvent event) { Point p = event.getPoint(); int row = rowAtPoint(p); int col = columnAtPoint(p); if (row >= 0 && col >= 0) { return (String) getValueAt(row, col); } else { return null; } } /** * Does the same as {@link JTable#columnAdded(TableColumnModelEvent)} and * sets the preferred width of the cell to {@link * ReferenceTable#CELL_SIZE}. */ @Override public void columnAdded(TableColumnModelEvent e) { super.columnAdded(e); int index = e.getToIndex(); getColumnModel().getColumn(index).setPreferredWidth(CELL_SIZE); } /** * Returns the preferred size of this table as: * {@link ReferenceTable#CELL_SIZE CELL_SIZE}{@code * *column_count x CELL_SIZE*row_count} */ @Override public Dimension getPreferredSize() { return new Dimension(getColumnCount()*CELL_SIZE, getRowCount()*CELL_SIZE); } @Override public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } } @Override public void actionPerformed(ActionEvent evt) { //If current action is 'paste' then copy string from the clipboard and paste it to current cell if (evt.getActionCommand().compareTo("Paste")==0) { Clipboard system = Toolkit.getDefaultToolkit().getSystemClipboard(); String trstring=""; try { trstring = (String)(system.getContents(this).getTransferData(DataFlavor.stringFlavor)); } catch (UnsupportedFlavorException e) { return; } catch (IOException e) { return; } int[] cols = this.getSelectedColumns(); int[] rows = this.getSelectedRows(); for (int i = 0; i < rows.length; i++) for (int j = 0; j < cols.length; j++) this.setValueAt(trstring, rows[i], cols[j]); } } }