001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.gui; 022 023import org.biojava.nbio.structure.Structure; 024import org.biojava.nbio.structure.align.gui.MenuCreator; 025import org.slf4j.Logger; 026import org.slf4j.LoggerFactory; 027 028import javax.swing.*; 029import java.awt.*; 030import java.awt.event.WindowAdapter; 031import java.awt.event.WindowEvent; 032import java.lang.reflect.Constructor; 033import java.lang.reflect.InvocationTargetException; 034import java.lang.reflect.Method; 035 036public class JmolViewerImpl implements StructureViewer { 037 038 private static final Logger logger = LoggerFactory.getLogger(JmolViewerImpl.class); 039 040 public static final String viewer = "org.jmol.api.JmolSimpleViewer"; 041 public static final String adapter = "org.jmol.api.JmolAdapter"; 042 public static final String smartAdapter = "org.jmol.adapter.smarter.SmarterJmolAdapter"; 043 Structure structure; 044 JmolPanel jmolPanel; 045 JFrame frame; 046 047 public JmolViewerImpl() { 048 049 frame = new JFrame(); 050 051 JMenuBar menu = MenuCreator.initJmolMenu(frame, null, null, null); 052 053 frame.setJMenuBar(menu); 054 055 frame.addWindowListener(new WindowAdapter() { 056 057 @Override 058 public void windowClosing(WindowEvent e) { 059 frame.dispose(); 060 //System.exit(0); 061 } 062 }); 063 064 Container contentPane = frame.getContentPane(); 065 066 Box vBox = Box.createVerticalBox(); 067 068 try { 069 070 jmolPanel = new JmolPanel(); 071 072 } catch (ClassNotFoundException e) { 073 e.printStackTrace(); 074 System.err.println("Could not find Jmol in classpath, please install first. http://www.jmol.org"); 075 return; 076 } 077 jmolPanel.setPreferredSize(new Dimension(500, 500)); 078 vBox.add(jmolPanel); 079 080 081 JTextField field = new JTextField(); 082 083 field.setMaximumSize(new Dimension(Short.MAX_VALUE, 30)); 084 field.setText("enter RASMOL like command..."); 085// RasmolCommandListener listener = new RasmolCommandListener(jmolPanel, field); 086 087// field.addActionListener(listener); 088// field.addMouseListener(listener); 089// field.addKeyListener(listener); 090 vBox.add(field); 091 092 contentPane.add(vBox); 093 094 095 096 frame.pack(); 097 frame.setVisible(true); 098 099 } 100 101 public void setTitle(String label) { 102 frame.setTitle(label); 103 frame.repaint(); 104 } 105 106 @Override 107 public void setStructure(Structure structure) { 108 if (jmolPanel == null) { 109 System.err.println("please install Jmol first"); 110 return; 111 } 112 113 setTitle(structure.getPDBCode()); 114 115 // actually this is very simple 116 // just convert the structure to a PDB file 117 118 String pdb = structure.toPDB(); 119 //System.out.println(s.isNmr()); 120 121 //System.out.println(pdb); 122 // Jmol could also read the file directly from your file system 123 //viewer.openFile("/Path/To/PDB/1tim.pdb"); 124 125 //System.out.println(pdb); 126 jmolPanel.openStringInline(pdb); 127 128 // send the PDB file to Jmol. 129 // there are also other ways to interact with Jmol, e.g make it directly 130 // access the biojava structure object, but they require more 131 // code. See the SPICE code repository for how to do this. 132 } 133 134 @Override 135 public void clear() { 136 // TODO Auto-generated method stub 137 } 138 139 @Override 140 public Color getColor() { 141 // TODO Auto-generated method stub 142 return null; 143 } 144 145 @Override 146 public Selection getSelection() { 147 // TODO Auto-generated method stub 148 return null; 149 } 150 151 @Override 152 public void repaint() { 153 // TODO Auto-generated method stub 154 } 155 156 @Override 157 public void setColor(Color red) { 158 // TODO Auto-generated method stub 159 } 160 161 @Override 162 public void setSelection(Selection selection) { 163 // TODO Auto-generated method stub 164 } 165 166 @Override 167 public void setStyle(RenderStyle wireframe) { 168 // TODO Auto-generated method stub 169 } 170 171 @Override 172 public void setZoom(int i) { 173 // TODO Auto-generated method stub 174 } 175 @SuppressWarnings("rawtypes") 176 static class JmolPanel extends JPanel { 177 178 /** 179 * 180 */ 181 private static final long serialVersionUID = -3661941083797644242L; 182 183 Class viewerC; 184 185 Class adapterC; 186 187 188 Class smartAdapterC; 189 Object viewerO; 190 Object adapterO; 191 Method evalString; 192 Method renderScreenImage; 193 Method openStringInline; 194 195 //JmolSimpleViewer viewer; 196 //JmolAdapter adapter; 197 @SuppressWarnings("unchecked") 198 JmolPanel() throws ClassNotFoundException { 199 200 try { 201 viewerC = Class.forName(viewer); 202 203 adapterC = Class.forName(adapter); 204 smartAdapterC = Class.forName(smartAdapter); 205 206 Method m = viewerC.getMethod("allocateSimpleViewer", new Class[]{Component.class, adapterC}); 207 208 Constructor constructor = smartAdapterC.getConstructor(new Class[]{}); 209 adapterO = constructor.newInstance(new Object[]{}); 210 211 //viewerC = JmolSimpleViewer.allocateSimpleViewer(this, adapter); 212 viewerO = m.invoke(viewerC, this, adapterO); 213 214 evalString = viewerC.getMethod("evalString", String.class); 215 216 renderScreenImage = viewerC.getMethod("renderScreenImage", 217 new Class[]{Graphics.class, Dimension.class, Rectangle.class}); 218 219 openStringInline = viewerC.getMethod("openStringInline", new Class[]{String.class}); 220 221 } catch (InstantiationException ex) { 222 logger.error("Exception caught", ex); 223 } catch (IllegalAccessException ex) { 224 logger.error("Exception caught", ex); 225 } catch (IllegalArgumentException ex) { 226 logger.error("Exception caught", ex); 227 } catch (InvocationTargetException ex) { 228 logger.error("Exception caught", ex); 229 } catch (NoSuchMethodException e) { 230 logger.error("Exception caught", e); 231 } 232 233 evalString("set scriptQueue on;"); 234 235 } 236 237 238 public Class getViewer() { 239 return viewerC; 240 } 241 242 public void evalString(String rasmolScript) { 243 try { 244 evalString.invoke(viewerO, rasmolScript); 245 } catch (Exception e) { 246 e.printStackTrace(); 247 } 248 } 249 250 public void openStringInline(String pdbFile) { 251 try { 252 openStringInline.invoke(viewerO, pdbFile); 253 } catch (Exception e) { 254 e.printStackTrace(); 255 } 256 } 257 258 public void executeCmd(String rasmolScript) { 259 try { 260 evalString.invoke(viewerO, rasmolScript); 261 } catch (Exception e) { 262 e.printStackTrace(); 263 } 264 } 265 final Dimension currentSize = new Dimension(); 266 final Rectangle rectClip = new Rectangle(); 267 268 @Override 269 public void paint(Graphics g) { 270 getSize(currentSize); 271 g.getClipBounds(rectClip); 272 //viewer.renderScreenImage(g, currentSize, rectClip); 273 274 try { 275 renderScreenImage.invoke(viewerO, g, currentSize, rectClip); 276 } catch (Exception e) { 277 e.printStackTrace(); 278 } 279 } 280 } 281}