/**
* StructurePanel.java
*/
package jSimMacs.jmol;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JPanel;
import org.biojava.bio.structure.AminoAcidImpl;
import org.biojava.bio.structure.Atom;
import org.biojava.bio.structure.AtomImpl;
import org.biojava.bio.structure.Chain;
import org.biojava.bio.structure.ChainImpl;
import org.biojava.bio.structure.Group;
import org.biojava.bio.structure.Structure;
import org.biojava.bio.structure.StructureImpl;
import org.biojava.bio.structure.io.PDBParseException;
import org.jmol.api.JmolAdapter;
import org.jmol.api.JmolSelectionListener;
import org.jmol.api.JmolStatusListener;
import org.jmol.api.JmolViewer;
import org.jmol.popup.JmolPopup;
/**
* @author sr
* Panel with JMol components
*/
public class StructurePanel extends JPanel implements JmolCommander {
private final Dimension currentSize = new Dimension();
private final Rectangle rectClip = new Rectangle();
private JmolViewer viewer;
private JmolAdapter adapter;
private JmolPopup jmolpopup;
private Structure structure;
public StructurePanel() {
super();
adapter = new JSimJmolAdapter();
initJmolInstance();
initJmolDisplay();
}
/**
* initalizes the JMol instance
*/
private void initJmolInstance() {
viewer = org.jmol.viewer.Viewer.allocateViewer(this, adapter);
//viewer.setSelectionHalos(true);
jmolpopup = JmolPopup.newJmolPopup(viewer, true, null);
// this is important to make Jmol thread -safe !!
viewer.evalString("set scriptQueue on;");
}
/**
* initalizes the display
*/
private void initJmolDisplay() {
Atom a = new AtomImpl();
a.setName("CA");
a.setFullName(" CA ");
a.setCoords(new double[] { 47.866, 28.415, 2.952 });
Group g = new AminoAcidImpl();
g.setPDBCode("9");
try {
g.setPDBName("GLY");
} catch (PDBParseException e) {
e.printStackTrace();
}
g.addAtom(a);
Chain c = new ChainImpl();
c.addGroup(g);
Structure s = new StructureImpl();
s.addChain(c);
setStructure(s);
s.setPDBCode("1AND");
executeCmd("select *; spacefill off;");
}
/** Add a JmolStatus listener to Jmol
*
* @param listener
*/
public void addJmolStatusListener(JmolStatusListener listener) {
viewer.setJmolStatusListener(listener);
// in order to provide a statuslistener for jmol we need to know the popup and viewer..
if ( listener instanceof JSimJmolTranslator) {
JSimJmolTranslator translator = (JSimJmolTranslator)listener;
translator.setViewer(viewer);
translator.setJmolpopup(jmolpopup);
translator.setStructure(structure);
}
}
public void addJmolSelectionListener(JmolSelectionListener listener){
viewer.addSelectionListener(listener);
}
/**
* returns the JmolViewer
*
* @return the viewer
*/
public JmolViewer getViewer() {
return viewer;
}
/** paint Jmol */
public void paint(Graphics g) {
getSize(currentSize);
g.getClipBounds(rectClip);
viewer.renderScreenImage(g, currentSize, rectClip);
}
/*
* (non-Javadoc)
*
* @see jSimMacs.jmol.JmolCommander#executeCmd(java.lang.String)
*/
public void executeCmd(String command) {
viewer.script(command);
}
/**
* sets a new Structure to the display
* @param struct
*/
public void setStructure(Structure struct) {
if (struct == null) {
struct = new StructureImpl();
initJmolDisplay();
}
this.structure = struct;
if (struct.size() < 1) {
viewer.evalString("exit; zap;");
return;
}
if (viewer.isScriptExecuting()) {
// something is going wrong with jmol!
// drop it an get a new instance
initJmolInstance();
}
viewer.evalString("exit");
if (adapter instanceof JSimJmolAdapter) {
JSimJmolAdapter jad = (JSimJmolAdapter) adapter;
jad.setStructure(structure);
/*
* class MyRunnable implements Runnable { Structure structure;
* public MyRunnable(Structure struc){ super(); structure = struc; }
* public void run() { viewer.openClientFile("","",structure);
* jmolpopup.updateComputedMenus();
* executeCmd(StructurePanelListener.INIT_SELECT); } }
*
* new MyRunnable(structure).run();
*
* //SwingUtilities.invokeLater(new MyRunnable(structure));
*/
try{
//viewer.openFile(bfReader.getPath());
//viewer.openReader("", "", bfReader);
// System.out.println(structure.toString());
// Chain chain = structure.getChain(0);
viewer.openClientFile("", structure.getPDBCode(), structure);
//viewer.openFile(file.getAbsolutePath());
viewer.setSelectionHalos(true);
}catch(Exception e){
e.printStackTrace();
}
jmolpopup.updateComputedMenus();
executeCmd("select none");
/*executeCmd("select all; backbone 0.5; colour chain; cpk off; "
+ "cartoon off; wireframe off; select not protein and not solvent; "
+ "spacefill on; select nucleic; spacefill on; backbone off");*/
}
//jmolpopup.updateComputedMenus();
}
/** select a range of sequence.
* only turns selection on
* @param
*/
public void selectedSeqRange(int currentChainNumber, int start, int end) {
String cmd = getSelectStr(currentChainNumber,start+1,end+1);
cmd += " set display selected;";
if ( ! cmd.equals(""))
executeCmd(cmd);
}
/**
* gets the selection as a String
* @param chainNumber
* @param start
* @param end
* @return selected String
*/
private String getSelectStr(int chainNumber, int start, int end) {
Chain chain = structure.getChain(chainNumber) ;
if ( chain == null) return "" ;
String chainid = chain.getName() ;
Group gs = getGroupNext( chain,(start-1), true);
//Group gs = chain.getGroup(start-1);
Group ge = getGroupNext( chain,(end-1), false);
String startpdb = gs.getPDBCode() ;
String endpdb = ge.getPDBCode() ;
String cmd = "select "+startpdb+"-"+endpdb;
if ( ! chainid.equals(" "))
cmd += ":" +chainid + "/1";
else
cmd += "/1";
cmd +=" and protein;";
return cmd ;
}
/**
* gets the next group
* @param chain
* @param startpos
* @param increment
* @return
*/
private Group getGroupNext(Chain chain, int startpos, boolean increment) {
if ( chain == null) return null ;
while ( (startpos >= 0 ) && (startpos < chain.getAtomLength())){
Group g = chain.getAtomGroup(startpos);
//System.out.println("checking " + startpos + " " + g );
if (g.has3D()){
return g ;
}
if ( increment) {
startpos += 1;
} else {
startpos -= 1 ;
}
}
return null ;
}
}