/rcdkjar/src/org/guha/rcdk/view/ViewMolecule2DDataTable.java
Java | 295 lines | 218 code | 58 blank | 19 comment | 9 complexity | 72457c6c626bf6142705b9a73ea677d8 MD5 | raw file
1package org.guha.rcdk.view; 2 3import org.guha.rcdk.util.Misc; 4import org.guha.rcdk.view.panels.MoleculeCell; 5import org.guha.rcdk.view.table.MyTable; 6import org.guha.rcdk.view.table.StructureTableCellEditor2D; 7import org.guha.rcdk.view.table.StructureTableCellRenderer2D; 8import org.openscience.cdk.aromaticity.CDKHueckelAromaticityDetector; 9import org.openscience.cdk.exception.CDKException; 10import org.openscience.cdk.interfaces.IAtomContainer; 11import org.openscience.cdk.tools.manipulator.AtomContainerManipulator; 12 13import javax.swing.*; 14import javax.swing.event.ChangeEvent; 15import javax.swing.event.ListSelectionEvent; 16import javax.swing.event.TableColumnModelEvent; 17import javax.swing.event.TableColumnModelListener; 18import javax.swing.table.AbstractTableModel; 19import javax.swing.table.DefaultTableCellRenderer; 20import javax.swing.table.TableCellRenderer; 21import javax.swing.table.TableColumn; 22import java.awt.*; 23import java.awt.event.WindowAdapter; 24import java.awt.event.WindowEvent; 25import java.io.IOException; 26 27public class ViewMolecule2DDataTable { 28 29 private static int STRUCTURE_COL = 0; 30 31 private IAtomContainer[] molecules; 32 private String[] cnames; 33 private Object[][] tabledata; 34 private RcdkDepictor depictor; 35 36 private int fontSize = 14; 37 private int cellx = 200; 38 private int celly = 200; 39 private int ncol; 40 private int nrow; 41 42 private JFrame frame; 43 44 class ApplicationCloser extends WindowAdapter { 45 public void windowClosing(WindowEvent e) { 46 frame.dispose(); 47 } 48 } 49 50 class RowLabelRenderer extends DefaultTableCellRenderer { 51 public RowLabelRenderer() { 52 super(); 53 setHorizontalAlignment(javax.swing.SwingConstants.CENTER); 54 setVerticalAlignment(javax.swing.SwingConstants.VERTICAL); 55 } 56 } 57 58 public ViewMolecule2DDataTable(String[] fnames, String[] cnames, 59 Object[][] tabledata, RcdkDepictor depictor) { 60 try { 61 molecules = Misc.loadMolecules(fnames, true, true, true); 62 } catch (CDKException e) { 63 e.printStackTrace(); 64 } catch (IOException e) { 65 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 66 } 67 frame = new JFrame("Table of Molecules"); 68 frame.addWindowListener(new ApplicationCloser()); 69 this.cnames = cnames; 70 this.tabledata = tabledata; 71 this.depictor = depictor; 72 } 73 74 public ViewMolecule2DDataTable(IAtomContainer[] molecules, String[] cnames, 75 Object[][] tabledata, RcdkDepictor depictor) { 76 frame = new JFrame("Table of Molecules"); 77 frame.addWindowListener(new ApplicationCloser()); 78 this.cnames = cnames; 79 this.tabledata = tabledata; 80 this.molecules = molecules; 81 this.depictor = depictor; 82 } 83 84 public void setCellX(int cellx) { 85 this.cellx = cellx; 86 } 87 88 public void setCellY(int celly) { 89 this.celly = celly; 90 } 91 92 public void setFontSize(int f) { 93 fontSize = f; 94 } 95 96 public void display() throws IOException, CDKException { 97 98 if (depictor == null) 99 depictor = Misc.getDefaultDepictor(); 100 101 ncol = cnames.length; 102 nrow = molecules.length; 103 104 Object[][] data = new Object[molecules.length][cnames.length]; 105 106 for (int i = 0; i < molecules.length; i++) { 107 try { 108 CDKHueckelAromaticityDetector.detectAromaticity(molecules[i]); 109 molecules[i] = Misc.getMoleculeWithCoordinates(molecules[i]); 110 molecules[i] = AtomContainerManipulator.removeHydrogens(molecules[i]); 111 } catch (CDKException e) { 112 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 113 } catch (Exception e) { 114 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 115 } 116 data[i][0] = new MoleculeCell(molecules[i], depictor); 117 } 118 // set the data 119 for (int i = 0; i < molecules.length; i++) { 120 for (int j = 1; j < cnames.length; j++) { 121 data[i][j] = tabledata[i][j - 1]; 122 } 123 } 124 125 MyTable mtable = new MyTable(new Render2DPanelJTableModel(data, cnames)); 126 mtable.setShowGrid(true); 127 mtable.getTableHeader().setFont(new Font("Lucida", Font.BOLD, fontSize)); 128 129 // disable movement of columns. This is needed since we 130 // set the CellRenderer and CellEditor for a specific column 131 mtable.getTableHeader().setReorderingAllowed(false); 132 133 // set row heights 134 for (int i = 0; i < molecules.length; i++) { 135 mtable.setRowHeight(i, celly); 136 } 137 mtable.getColumnModel().getColumn(STRUCTURE_COL).setPreferredWidth(cellx); 138 139 // add a TableolumnModelListener so we can catch column 140 // resizes and change row heights accordingly 141 mtable.getColumnModel().addColumnModelListener(new Render2DColumnModelListener(mtable)); 142 143 // allow cell selections 144 mtable.setColumnSelectionAllowed(true); 145 mtable.setRowSelectionAllowed(true); 146 147 // set up scroll bars 148 JScrollPane scrollpane = new JScrollPane(mtable); 149 scrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 150 mtable.setPreferredScrollableViewportSize(new Dimension(ncol * cellx, nrow)); 151 frame.getContentPane().add(scrollpane); 152 153 // set the cell renderer for the structure column 154 // we also set up a TableCellEditor so that events on a JmolPanel 155 // cell get forwarded to the actual JmolPanel 156 TableColumn col = mtable.getColumnModel().getColumn(0); 157 col.setCellRenderer(new StructureTableCellRenderer2D()); 158 col.setCellEditor(new StructureTableCellEditor2D()); 159 160 RowLabelRenderer myRowRenderer = new RowLabelRenderer(); 161 for (int i = 1; i < ncol; i++) { 162 col = mtable.getColumnModel().getColumn(i); 163 col.setCellRenderer(myRowRenderer); 164 } 165 166 // start the show! 167 frame.pack(); 168 frame.setSize(cellx * (ncol > 3 ? 3 : ncol), celly); 169 frame.setVisible(true); 170 171 //mtable.pack(TablePacker.VISIBLE_ROWS, true); 172 } 173 174 static class Render2DColumnModelListener implements TableColumnModelListener { 175 JTable table; 176 177 public Render2DColumnModelListener(JTable t) { 178 this.table = t; 179 } 180 181 public void columnAdded(TableColumnModelEvent e) { 182 } 183 184 public void columnRemoved(TableColumnModelEvent e) { 185 } 186 187 public void columnMoved(TableColumnModelEvent e) { 188 } 189 190 public void columnMarginChanged(ChangeEvent e) { 191// int colwidth = this.table.getColumnModel().getColumn(STRUCTURE_COL).getWidth(); 192// for (int i = 0; i < this.table.getRowCount(); i++) { 193// this.table.setRowHeight(i, colwidth); 194// } 195 196 } 197 198 public void columnSelectionChanged(ListSelectionEvent e) { 199 } 200 } 201 202 static class Render2DPanelJTableModel extends AbstractTableModel { 203 204 private static final long serialVersionUID = -1029080447213047474L; 205 206 private Object[][] rows; 207 208 private String[] columns; 209 210 public Render2DPanelJTableModel(Object[][] objs, String[] cols) { 211 rows = objs; 212 columns = cols; 213 } 214 215 public String getColumnName(int column) { 216 return columns[column]; 217 } 218 219 public int getRowCount() { 220 return rows.length; 221 } 222 223 public int getColumnCount() { 224 return columns.length; 225 } 226 227 public Object getValueAt(int row, int column) { 228 return rows[row][column]; 229 } 230 231 public boolean isCellEditable(int row, int column) { 232 return column == STRUCTURE_COL; 233 } 234 235 public Class getColumnClass(int column) { 236 return getValueAt(0, column).getClass(); 237 } 238 } 239 240 static class Render2DPanelCellRenderer extends JPanel implements 241 TableCellRenderer { 242 243 private static final long serialVersionUID = 3990689120717795379L; 244 245 public Component getTableCellRendererComponent(JTable table, 246 Object value, boolean isSelected, boolean hasFocus, 247 int rowIndex, int vColIndex) { 248 // return plist[rowIndex]; 249 return (MoleculeCell) value; 250 } 251 252 // The following methods override the defaults for performance reasons 253 public void validate() { 254 } 255 256 public void revalidate() { 257 } 258 259 protected void firePropertyChange(String propertyName, Object oldValue, 260 Object newValue) { 261 } 262 263 public void firePropertyChange(String propertyName, boolean oldValue, 264 boolean newValue) { 265 } 266 } 267 268 269 public static void main(String[] args) throws IOException, CDKException { 270 String home = "/Users/rguha/"; 271 String[] fname = {home + "src/R/trunk/rcdk/data/dan001.sdf", 272 home + "src/R/trunk/rcdk/data/dan002.sdf", 273 home + "src/R/trunk/rcdk/data/dan003.sdf"}; 274 IAtomContainer[] acs = null; 275 try { 276 acs = Misc.loadMolecules(fname, true, true, true); 277 } catch (CDKException e) { 278 e.printStackTrace(); 279 } catch (IOException e) { 280 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 281 } 282 283 String[] cnames = {"X", "Y", "Z", "A", "B", "C"}; 284 Object[][] dat = new Object[3][5]; 285 for (int i = 0; i < 3; i++) { 286 dat[i][0] = new Integer(i); 287 dat[i][1] = new Double(i) / 3.4; 288 dat[i][2] = "Hello " + i; 289 dat[i][3] = "By " + i; 290 dat[i][4] = 3; 291 } 292 ViewMolecule2DDataTable d = new ViewMolecule2DDataTable(acs, cnames, dat, Misc.getDefaultDepictor()); 293 d.display(); 294 } 295}