package studio.ui; import studio.kdb.DictTableModel; import studio.kdb.K; import studio.kdb.FlipTableModel; import studio.kdb.K.Dict; import studio.kdb.K.Flip; import studio.kdb.TableHeaderRenderer; import studio.kdb.TableRowHeader; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.ToolTipManager; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableModel; import studio.kdb.Config; public class QGrid extends JPanel { private UserAction copyExcelFormatAction; private TableModel model; private JTable table; private final WidthAdjuster wa; public JTable getTable() { return table; } public WidthAdjuster getWa() { return wa; } public static String newline = System.getProperty("line.separator"); public int getRowCount() { return model.getRowCount(); } // public QGrid(){super();} public float factor = 1; private JPopupMenu popupMenu = new JPopupMenu(); class MYJTable extends JTable { public MYJTable(TableModel m) { super(m); } Color col = new Color(0xff,0xff,0xcc); //Color col = UIManager.getColor("Table.selectionBackground").brighter(); Color bgSelCache = UIManager.getColor("Table.selectionBackground"); Color fgSelCache = UIManager.getColor("Table.selectionForeground"); Color bgCache = UIManager.getColor("Table.background"); public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) { Color bg = null; //Color fg= UIManager.getColor("Table.foreground");; Component c = super.prepareRenderer(renderer,rowIndex,vColIndex); c.setFont(this.getFont()); if (isCellSelected(rowIndex,vColIndex)) bg = bgSelCache; return c; } private Font originalFont; private int originalRowHeight; private float zoomFactor = 1.0f; public void setFont(Font font) { originalFont = font; // When setFont() is first called, zoomFactor is 0. if (zoomFactor != 0.0 && zoomFactor != 1.0) { float scaledSize = originalFont.getSize2D() * zoomFactor; font = originalFont.deriveFont(scaledSize); } super.setFont(font); } public void setRowHeight(int rowHeight) { originalRowHeight = rowHeight; // When setRowHeight() is first called, zoomFactor is 0. if (zoomFactor != 0.0 && zoomFactor != 1.0) rowHeight = (int) Math.ceil(originalRowHeight * zoomFactor); super.setRowHeight(rowHeight); } public float getZoom() { return zoomFactor; } public void setZoom(float zoomFactor) { if (this.zoomFactor == zoomFactor) return; if (originalFont == null) originalFont = getFont(); if (originalRowHeight == 0) originalRowHeight = getRowHeight(); float oldZoomFactor = this.zoomFactor; this.zoomFactor = zoomFactor; Font font = originalFont; if (zoomFactor != 1.0) { float scaledSize = originalFont.getSize2D() * zoomFactor; font = originalFont.deriveFont(scaledSize); } super.setFont(font); super.setRowHeight((int) Math.ceil(originalRowHeight * zoomFactor)); ((TableHeaderRenderer) getTableHeader().getDefaultRenderer()).setFont(font); firePropertyChange("zoom",oldZoomFactor,zoomFactor); WidthAdjuster wa = new WidthAdjuster(this); wa.resizeAllColumns(); invalidate(); } public Component prepareEditor(TableCellEditor editor,int row,int column) { Component comp = super.prepareEditor(editor,row,column); comp.setFont(this.getFont()); return comp; } }; public QGrid(K.KBase obj) { super(); if (obj instanceof K.Flip) model = new FlipTableModel((K.Flip) obj); else model = new DictTableModel((K.Dict) obj); table = new MYJTable(model); DefaultTableCellRenderer dhr = new TableHeaderRenderer(); table.getTableHeader().setDefaultRenderer(dhr); table.setShowHorizontalLines(true); table.setDragEnabled(true); // table.setRowSelectionAllowed(true); // table.setColumnSelectionAllowed(false); // table.setCellSelectionEnabled(true); table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); table.setCellSelectionEnabled(true); // table.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C,Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), // TransferHandler.getCopyAction().getValue(Action.NAME)); ToolTipManager.sharedInstance().unregisterComponent(table); ToolTipManager.sharedInstance().unregisterComponent(table.getTableHeader()); DefaultTableCellRenderer dcr = new CellRenderer(table); // dcr.setHorizontalAlignment(SwingConstants.RIGHT); // dcr.setVerticalAlignment(SwingConstants.CENTER); for (int i = 0;i < model.getColumnCount();i++) { TableColumn col = table.getColumnModel().getColumn(i); col.setCellRenderer(dcr); } table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // AutoFitTableColumns.autoResizeTable(table, true); table.getTableHeader().setReorderingAllowed(true); final JScrollPane scrollPane = new JScrollPane(table); if (table.getRowCount() > 0) { TableRowHeader trh = new TableRowHeader(table); scrollPane.setRowHeaderView(trh); scrollPane.getRowHeader().addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ev) { Point header_pt = ((JViewport) ev.getSource()).getViewPosition(); Point main_pt = main.getViewPosition(); if (header_pt.y != main_pt.y) { main_pt.y = header_pt.y; main.setViewPosition(main_pt); } } JViewport main = scrollPane.getViewport(); }); } wa = new WidthAdjuster(table); wa.resizeAllColumns(); scrollPane.setWheelScrollingEnabled(true); scrollPane.getViewport().setBackground(UIManager.getColor("Table.background")); // scrollPane.setBorder(null); // scrollPane.setViewportBorder(null); JLabel rowCountLabel = new JLabel(""); rowCountLabel.setHorizontalAlignment(SwingConstants.RIGHT); rowCountLabel.setVerticalAlignment(SwingConstants.CENTER); rowCountLabel.setOpaque(true); rowCountLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder")); rowCountLabel.setFont(UIManager.getFont("Table.font")); rowCountLabel.setBackground(UIManager.getColor("TableHeader.background")); rowCountLabel.setForeground(UIManager.getColor("TableHeader.foreground")); scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,rowCountLabel); rowCountLabel = new JLabel(""); rowCountLabel.setHorizontalAlignment(SwingConstants.RIGHT); rowCountLabel.setVerticalAlignment(SwingConstants.CENTER); rowCountLabel.setOpaque(true); rowCountLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder")); rowCountLabel.setFont(UIManager.getFont("Table.font")); rowCountLabel.setBackground(UIManager.getColor("TableHeader.background")); rowCountLabel.setForeground(UIManager.getColor("TableHeader.foreground")); scrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER,rowCountLabel); setLayout(new BorderLayout()); this.add(scrollPane,BorderLayout.CENTER); copyExcelFormatAction = new UserAction("Copy (Excel format)", Util.getImage(Config.imageBase2 + "copy.png"), "Copy the selected cells to the clipboard using Excel format", new Integer(KeyEvent.VK_E), null) { public void actionPerformed(ActionEvent e) { StringBuffer sb = new StringBuffer(); int numcols = table.getSelectedColumnCount(); int numrows = table.getSelectedRowCount(); int[] rowsselected = table.getSelectedRows(); int[] colsselected = table.getSelectedColumns(); if (!((numrows - 1 == rowsselected[rowsselected.length - 1] - rowsselected[0] && numrows == rowsselected.length) && (numcols - 1 == colsselected[colsselected.length - 1] - colsselected[0] && numcols == colsselected.length))) { JOptionPane.showMessageDialog(null, "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE); return; } if (table.getSelectedRowCount() == table.getRowCount()) { for (int col = 0;col < numcols;col++) { sb.append(table.getColumnName(colsselected[col])); if (col < numcols - 1) sb.append("\t"); } sb.append(newline); } for (int row = 0;row < numrows;row++) { if (row > 0) sb.append(newline); for (int col = 0;col < numcols;col++) { boolean symColumn = table.getColumnClass(col) == K.KSymbolVector.class; if (symColumn) sb.append("\""); K.KBase b = (K.KBase) table.getValueAt(rowsselected[row],colsselected[col]); if (!b.isNull()) sb.append(b.toString(false)); if (symColumn) sb.append("\""); if (col < numcols - 1) sb.append("\t"); } } StringSelection ss = new StringSelection(sb.toString()); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,null); } }; popupMenu.add(new JMenuItem(copyExcelFormatAction)); table.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { maybeShowPopup(e); } public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) popupMenu.show(e.getComponent(), e.getX(),e.getY()); } }); } private boolean scrollToEnd = false; public void append(K.KBase upd) { int n = table.getRowCount(); if (model instanceof FlipTableModel) { K.Flip flip=(Flip) upd; ((FlipTableModel) model).append(flip); ((AbstractTableModel) model).fireTableRowsInserted(n,table.getRowCount() - n); if (scrollToEnd) table.scrollRectToVisible(new Rectangle(0, table.getRowHeight() * (table.getRowCount()), 100, table.getRowHeight())); }else if (model instanceof DictTableModel) { K.Dict dict=(Dict) upd; ((DictTableModel) model).upsert(dict); ((AbstractTableModel) model).fireTableRowsInserted(0,table.getRowCount()); if (scrollToEnd) table.scrollRectToVisible(new Rectangle(0, table.getRowHeight() * (table.getRowCount()), 100, table.getRowHeight())); } } }