// $Id: StructureStyles.java,v 1.39 2007/05/26 17:07:13 Sasha Buzko Exp $ // // Copyright (c) 2000-2003 San Diego Supercomputer Center (SDSC), // a facility operated jointly by the University of California, // San Diego (UCSD) and General Atomics, San Diego, California, USA. // // Users and possessors of this source code are hereby granted a // nonexclusive, royalty-free copyright and design patent license to // use this code in individual software. License is not granted for // commercial resale, in whole or in part, without prior written // permission from SDSC. This source is provided "AS IS" without express // or implied warranty of any kind. // // For further information, please see: http://mbt.sdsc.edu // // History: // $Log: StructureStyles.java,v $ // Revision 1.39 2007/05/26 17:07:13 Sasha Buzko // *** empty log message *** // // Revision 1.38 2007/05/22 20:55:42 Sasha Buzko // *** empty log message *** // // Revision 1.37 2007/05/18 01:52:06 Sasha Buzko // *** empty log message *** // // Revision 1.36 2007/05/12 16:55:25 Sasha Buzko // *** empty log message *** // // Revision 1.35 2007/05/10 04:27:15 Sasha Buzko // *** empty log message *** // // Revision 1.34 2007/05/03 23:49:02 Sasha Buzko // *** empty log message *** // // Revision 1.33 2007/03/21 23:58:14 Sasha Buzko // *** empty log message *** // // Revision 1.32 2007/03/18 03:30:31 Sasha Buzko // *** empty log message *** // // Revision 1.31 2007/03/13 04:34:00 Sasha Buzko // *** empty log message *** // // Revision 1.30 2007/02/18 05:08:06 Sasha Buzko // *** empty log message *** // // Revision 1.29 2007/02/13 19:08:41 Sasha Buzko // *** empty log message *** // // Revision 1.28 2007/01/29 02:01:03 Sasha Buzko // *** empty log message *** // // Revision 1.27 2007/01/22 22:36:31 Sasha Buzko // Added tree viewer // // Revision 1.26 2006/11/22 04:46:03 Sasha Buzko // *** empty log message *** // // Revision 1.25 2006/11/22 04:29:07 Sasha Buzko // *** empty log message *** // // Revision 1.24 2006/10/23 22:23:06 Sasha Buzko // *** empty log message *** // // Revision 1.23 2006/10/21 18:41:25 Sasha Buzko // *** empty log message *** // // Revision 1.22 2006/10/10 20:46:51 Sasha Buzko // *** empty log message *** // // Revision 1.21 2006/09/30 04:51:30 Sasha Buzko // *** empty log message *** // // Revision 1.20 2006/09/25 19:09:43 Sasha Buzko // *** empty log message *** // // Revision 1.19 2006/09/12 06:33:34 Sasha Buzko // *** empty log message *** // // Revision 1.18 2006/09/12 04:21:15 Sasha Buzko // *** empty log message *** // // Revision 1.17 2006/08/29 19:08:45 Sasha Buzko // *** empty log message *** // // Revision 1.16 2006/08/29 07:25:24 Sasha Buzko // Added bond orders in ball-and-stick // // Revision 1.15 2006/08/24 20:45:03 Sasha Buzko // *** empty log message *** // // Revision 1.14 2006/08/19 06:17:44 Sasha Buzko // *** empty log message *** // // Revision 1.13 2006/08/16 04:36:12 Sasha Buzko // *** empty log message *** // // Revision 1.12 2006/08/14 19:09:48 Sasha Buzko // added ribbons // // Revision 1.11 2006/08/08 05:45:52 Sasha Buzko // *** empty log message *** // // Revision 1.10 2006/07/31 05:34:30 Sasha Buzko // Fixed independent structure motion // // Revision 1.9 2006/07/25 04:08:04 Sasha Buzko // *** empty log message *** // // Revision 1.8 2006/07/07 04:45:27 Sasha Buzko // Added a workaround for the problem replacing amino acids in structures with hidden bound waters // // Revision 1.7 2006/07/06 16:56:08 Sasha Buzko // *** empty log message *** // // Revision 1.6 2006/07/02 17:53:31 Sasha Buzko // *** empty log message *** // // Revision 1.5 2006/06/05 09:15:01 Sasha Buzko // *** empty log message *** // // Revision 1.4 2006/05/29 03:50:09 Sasha Buzko // *** empty log message *** // // Revision 1.3 2006/05/22 06:36:05 Sasha Buzko // *** empty log message *** // // Revision 1.2 2006/05/21 04:31:08 Sasha Buzko // *** empty log message *** // // Revision 1.1 2006/05/20 17:02:01 Sasha Buzko // Updated version // // Revision 1.4 2006/05/20 04:19:46 Sasha Buzko // *** empty log message *** // // Revision 1.3 2006/05/17 07:06:17 Sasha Buzko // *** empty log message *** // // Revision 1.2 2006/05/08 06:11:08 Sasha Buzko // *** empty log message *** // // Revision 1.1 2006/04/30 20:13:58 Sasha Buzko // New version of the app // // Revision 1.1 2006/04/15 19:42:20 Sasha Buzko // Initial commit // // Revision 1.22 2006/04/05 23:59:30 Administrator // *** empty log message *** // // Revision 1.21 2006/03/23 03:06:21 Administrator // *** empty log message *** // // Revision 1.20 2006/03/17 02:17:08 Administrator // *** empty log message *** // // Revision 1.19 2006/03/11 06:17:29 Administrator // *** empty log message *** // // Revision 1.18 2006/03/07 19:15:16 Administrator // *** empty log message *** // // Revision 1.17 2006/02/24 22:26:54 Administrator // *** empty log message *** // // Revision 1.16 2006/02/05 22:01:43 Administrator // *** empty log message *** // // Revision 1.15 2006/01/28 06:52:05 Administrator // *** empty log message *** // // Revision 1.14 2006/01/06 00:40:24 Administrator // *** empty log message *** // // Revision 1.13 2005/12/31 00:55:23 Administrator // *** empty log message *** // // Revision 1.12 2005/12/26 03:53:47 Administrator // *** empty log message *** // // Revision 1.11 2005/12/25 04:44:45 Administrator // *** empty log message *** // // Revision 1.10 2005/11/26 04:36:14 Administrator // *** empty log message *** // // Revision 1.9 2005/11/24 00:38:35 Administrator // *** empty log message *** // // Revision 1.8 2005/11/17 05:53:04 Administrator // *** empty log message *** // // Revision 1.7 2005/11/16 19:35:42 Administrator // *** empty log message *** // // Revision 1.6 2005/11/15 07:24:50 Administrator // *** empty log message *** // // Revision 1.5 2005/11/15 06:14:39 Administrator // *** empty log message *** // // Revision 1.4 2005/11/14 07:58:10 Administrator // *** empty log message *** // // Revision 1.3 2005/11/14 06:33:15 Administrator // *** empty log message *** // // Revision 1.2 2005/11/13 23:44:33 Administrator // *** empty log message *** // // Revision 1.1 2005/11/13 04:35:10 Administrator // *** empty log message *** // // Revision 1.5 2003/04/30 17:58:41 moreland // Added showNucleicAcidAtoms method. // // Revision 1.4 2003/04/23 23:31:52 moreland // Constructor now initializes all of the style RangeMaps. // Constructor now uses utility methods to set default content visibility. // Added "showChains" and "showLigandAtoms" utility methods. // Implemented selection methods and event handling for same. // Added Atom color and radius set and get methods. // Added Residue color set and get methods. // Added fireStructureStylesEvent method. // // Revision 1.3 2003/04/03 22:49:12 moreland // Added residueVisibility RangeMap. // // Revision 1.2 2003/03/19 22:57:41 moreland // Added preliminary support for residue selection. // // Revision 1.1 2003/02/27 21:06:34 moreland // Began adding classes for viewable "Styles" (colors, sizes, forms, etc). // // Revision 1.0 2003/02/18 18:06:54 moreland // First version. // package edu.sdsc.mbt.viewables; // MBT import edu.sdsc.mbt.*; import edu.sdsc.sirius.util.*; // Core import java.util.*; /** * Stores and retrieves styles associated with viewable objects of * a Structure (typically one StructureStyle object is assocated with * each Structure by a StructureDocument class). *

* Note that the StructureStyles class only specifies the STYLES that * should be used to draw visible representations of objects. * It does NOT specify WHAT should be drawn or HOW it should be drawn * (these choices are left up to each Viewer). Also, while the set of * style attributes maintained by this and subsidiary classes can * provide style information for ALL objects that COULD be displayed * by a Viewer, it does NOT mean that a given view MUST display a * representation of ALL objects. That is, this infrastructure simply * provides viewable attributes in case a Viewer chooses to create * a visible representation of certain data. *

* @see edu.sdsc.mbt.viewables.StructureDocument *

* @author John L. Moreland and Oleksandr V. Buzko */ public class StructureStyles implements StructureComponentEventListener, java.io.Serializable { // // Private fields // // private StructureStylesEvent structureStylesEvent = new StructureStylesEvent( ); // Changed attribute flags public static final int ATTRIBUTE_STYLE = 1; public static final int ATTRIBUTE_VISIBILITY = 2; public static final int ATTRIBUTE_RIBBON_VISIBILITY = 3; public static final int ATTRIBUTE_SELECTION = 4; public static final int ATTRIBUTE_QUALITY = 5; public static final int PROPERTY_COLOR = 0; public static final int PROPERTY_RADIUS = 1; public static final int PROPERTY_RENDERING = 2; public static final int PROPERTY_RIBBON_COLOR = 3; public static final int PROPERTY_RIBBON_VISIBILITY = 4; private HashMap ribbonTypes = new HashMap();//Chain -> Integer type (null if no ribbon) private HashMap ribbonQuality = new HashMap();//Chain -> Float type private HashMap ribbonDiameters = new HashMap();//Chain -> Float // Internal flags for special-case visibility and selection states. public static final int FLAG_NONE = 0; public static final int FLAG_SOME = 1; public static final int FLAG_ALL = 2; private Vector ribbonVisible = new Vector();//Chain objects private Vector ribbonInvisible = new Vector(); // private Hashtable invisible = new Hashtable();//for quick access to StructureComponents that are hidden // Holds selected structure components private Hashtable selection = new Hashtable( ); private int selectionFlag = FLAG_NONE; private Vector selectedChains; private short zero = 0; public float ribbonDiameter = 1.0f;//general variable that specifies diameter of the uniform round ribbon // Holds a default style object for a given StructureComponent type. private Hashtable defaultStyle = new Hashtable( ); // Holds hashcode -> Style private HashMap styleReference = new HashMap(); private HashMap atomRadiusStyles = new HashMap(); private HashMap atomRadiusStyleReference = new HashMap(); private HashMap bondRadiusStyles = new HashMap(); private HashMap bondRadiusStyleReference = new HashMap(); private HashMap atomColorStyles = new HashMap(); private HashMap atomColorStyleReference = new HashMap(); private HashMap bondColorStyles = new HashMap(); private HashMap bondColorStyleReference = new HashMap(); private HashMap residueColorStyles = new HashMap(); private HashMap residueColorStyleReference = new HashMap(); private HashMap ribbonColorStyles = new HashMap(); private HashMap ribbonColorStyleReference = new HashMap(); // Reference to our parent object. private StructureMap structureMap = null; // Event listeners. private Vector listeners = new Vector( ); private Vector componentListeners = new Vector(); private AtomRadius defaultAtomRadius = AtomRadiusByConstant.create(); private BondRadius defaultBondRadius = BondRadiusAsStick.create(); private AtomColor defaultAtomColor = AtomColorByElement.create(); private BondColor defaultBondColor = BondColorByAtomColor.create(); private ResidueColor defaultResidueColor = ResidueColorByElement.create(); private RibbonColor defaultRibbonColor = RibbonColorDefault.create(); public Vector selectedAtoms = new Vector(); public Vector selectedResidues = new Vector(); private StructureStyles thisObject; private StructureComponentEvent structureComponentEvent = new StructureComponentEvent(); private Object value = new Object(); /** * This hash contains pairs Chain -> Boolean, which are entered once chain drawing is attempted. * If it's a protein and a chain can be drawn, the value is true. */ private HashMap chainRibbonDrawing = new HashMap(); // // Constructors // /** * Should never be called. */ private StructureStyles( ) { structureStylesEvent.structureStyles = this;//as a template for future calls // structureComponentEvent.structureMap = this.getStructureMap(); thisObject = this; } /** * Primary constructor. */ public StructureStyles( StructureMap structureMap ){ structureStylesEvent.structureStyles = this; thisObject = this; if ( structureMap == null ) throw new NullPointerException( "null StructureMap" ); this.structureMap = structureMap; // ATOMS int residueCount = structureMap.getResidueCount( ); for ( int r=0; r * @param * @return * @throws */ public void setRenderingStyle( StructureComponent structureComponent, short style, short quality, boolean batch) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if ( style < 0 ) return; if (style == StylesPreferences.RENDERING_LINES) quality = StylesPreferences.RENDERING_FAST; if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_ATOM){ Atom atom = (Atom)structureComponent; atom.render = style; atom.quality = quality; structureStylesEvent.structureComponent = atom; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RENDERING; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); Vector bonds = structureMap.getBonds(atom); if (bonds == null || bonds.size() == 0) return; for (int i = 0; i < bonds.size(); i++){ Bond b = (Bond)bonds.get(i); if (b.render == style && b.quality == quality) continue;//bond hasn't changed //if the atom is changed to lines, update the bonds for sure if (style == StylesPreferences.RENDERING_LINES){ b.render = style; b.quality = quality; structureStylesEvent.structureComponent = b; processStructureStylesEvent( structureStylesEvent ); } else{ //if the neighboring atom has rendering style that is lines, //don't update the bond (e.g., if (b.getAtom(0) == atom){ /* if (getRenderingStyle(b.getAtom(1)) == StylesPreferences.RENDERING_LINES){ continue; } */ if (b.getAtom(1).render == style){ //if the style is the same, just assign the bond style and fire an event b.render = style; b.quality = quality; if (style == StylesPreferences.RENDERING_STICK){ setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_BALL_STICK){ setBondRadius(b, BondRadiusAsStick.create()); } //for cpk, the bond will not render, so radius is meaningless structureStylesEvent.structureComponent = b; processStructureStylesEvent( structureStylesEvent ); continue; } //work out the cases for different atom styles //ugly, but effective, and should take care of all cases. Besides, this is done only //for individual atom events, so the overhead is not very high.. if (style == StylesPreferences.RENDERING_BALL_STICK && b.getAtom(1).render == StylesPreferences.RENDERING_STICK){ b.setReferenceAtom(1); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_STICK && b.getAtom(1).render == StylesPreferences.RENDERING_BALL_STICK){ b.setReferenceAtom(0); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_STICK && b.getAtom(1).render == StylesPreferences.RENDERING_CPK){ b.setReferenceAtom(0); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_BALL_STICK && b.getAtom(1).render == StylesPreferences.RENDERING_CPK){ b.setReferenceAtom(0); setBondRadius(b, BondRadiusAsStick.create()); } else if (style == StylesPreferences.RENDERING_CPK && b.getAtom(1).render == StylesPreferences.RENDERING_STICK){ b.setReferenceAtom(1); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_CPK && b.getAtom(1).render == StylesPreferences.RENDERING_BALL_STICK){ b.setReferenceAtom(1); setBondRadius(b, BondRadiusAsStick.create()); } } else if (b.getAtom(1) == atom){ if (b.getAtom(0).render == StylesPreferences.RENDERING_LINES){ continue; } if (b.getAtom(0).render == style){ //if the style is the same, just assign the bond style and fire an event b.render = style; b.quality = quality; if (style == StylesPreferences.RENDERING_STICK){ setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_BALL_STICK){ setBondRadius(b, BondRadiusAsStick.create()); } //for cpk, the bond will not render, so radius is meaningless structureStylesEvent.structureComponent = b; processStructureStylesEvent( structureStylesEvent ); continue; } if (style == StylesPreferences.RENDERING_BALL_STICK && b.getAtom(0).render == StylesPreferences.RENDERING_STICK){ b.setReferenceAtom(0); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_STICK && b.getAtom(0).render == StylesPreferences.RENDERING_BALL_STICK){ b.setReferenceAtom(1); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_STICK && b.getAtom(0).render == StylesPreferences.RENDERING_CPK){ b.setReferenceAtom(1); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_BALL_STICK && b.getAtom(0).render == StylesPreferences.RENDERING_CPK){ b.setReferenceAtom(1); setBondRadius(b, BondRadiusAsStick.create()); } else if (style == StylesPreferences.RENDERING_CPK && b.getAtom(0).render == StylesPreferences.RENDERING_STICK){ b.setReferenceAtom(0); setBondRadius(b, BondRadiusByAtomRadius.create()); } else if (style == StylesPreferences.RENDERING_CPK && b.getAtom(0).render == StylesPreferences.RENDERING_BALL_STICK){ b.setReferenceAtom(0); setBondRadius(b, BondRadiusAsStick.create()); } } //proceed with the bond update if the neighbor is not lines b.render = style; b.quality = quality; structureStylesEvent.structureComponent = b; processStructureStylesEvent( structureStylesEvent ); } } return; } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_BOND){ Bond bond = (Bond)structureComponent; bond.render = style; bond.quality = quality; structureStylesEvent.structureComponent = bond; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RENDERING; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); //this case is usually not called, since rendering events specify atoms and residues //it's here for things like direct calls return; } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_RESIDUE){ Residue residue = (Residue)structureComponent; residue.render = style; residue.quality = quality; //render all atoms and their bonds //first, check if there is already a style with the same value structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RENDERING; structureStylesEvent.batch = true; Vector atoms = residue.getAtoms(); Vector bonds = new Vector(); for (int i = 0; i < atoms.size(); i++){ Atom a = (Atom)atoms.get(i); if (a.render == style && a.quality == quality) continue;//atom hasn't changed a.render = style; a.quality = quality; structureStylesEvent.structureComponent = a; processStructureStylesEvent( structureStylesEvent ); Vector bb = structureMap.getBonds(a); if (bb != null && bb.size() > 0){ for (int j = 0; j < bb.size(); j++){ Bond b = (Bond)bb.get(j); if (!bonds.contains(b)) bonds.add(b); } } } //now go through the Bonds for (int i = 0; i < bonds.size(); i++){ Bond b = (Bond)bonds.get(i); if (b.render == style && b.quality == quality){ continue;//bond hasn't changed } //check whether this is a boundary bond if (atoms.contains(b.getAtom(0)) && atoms.contains(b.getAtom(1))){ b.render = style; b.quality = quality; structureStylesEvent.structureComponent = b; processStructureStylesEvent( structureStylesEvent ); } else{ //if the neighboring residue is rendered as something other than lines //and this residue is solid-rendered as well, use if (atoms.contains(b.getAtom(0))){ //the other atom is in another residue if (b.getAtom(1).render != (short)StylesPreferences.RENDERING_LINES){ if (style == StylesPreferences.RENDERING_LINES){ setRenderingStyle(b, (short)StylesPreferences.RENDERING_LINES, quality, true); } else{ //render this bond as stick, and it should work fine setRenderingStyle(b, (short)StylesPreferences.RENDERING_BALL_STICK, quality, true); } } } else if (atoms.contains(b.getAtom(1))){ //the other atom is in another residue if (b.getAtom(0).render != (short)StylesPreferences.RENDERING_LINES){ if (style == StylesPreferences.RENDERING_LINES){ setRenderingStyle(b, (short)StylesPreferences.RENDERING_LINES, quality, true); } else{ //render this bond as stick, and it should work fine setRenderingStyle(b, (short)StylesPreferences.RENDERING_BALL_STICK, quality, true); } } } } } structureStylesEvent.batch = false; return; } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_CHAIN){ Chain chain = (Chain)structureComponent; //keep track of the overall chain rendering mode chain.render = style; chain.quality = quality; //render all atoms and their bonds structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RENDERING; structureStylesEvent.batch = true; Vector residues = chain.structure.getStructureMap().getResidues(); Vector bonds = new Vector(); for (int i = 0; i < residues.size(); i++){ Residue r = (Residue)residues.get(i); if (!r.getChainId().equals(chain.getChainId()))continue; r.render = style; r.quality = quality; // System.out.println("residue = " + r.getCompoundCode() + r.getResidueId()); Vector atoms = r.getAtoms(); for (int j = 0; j < atoms.size(); j++){ Atom a = (Atom)atoms.get(j); a.render = style; a.quality = quality; structureStylesEvent.structureComponent = a; processStructureStylesEvent( structureStylesEvent ); Vector bb = structureMap.getBonds(a); if (bb != null && bb.size() > 0){ for (int k = 0; k < bb.size(); k++){ Bond b = (Bond)bb.get(k); if (!bonds.contains(b)) bonds.add(b); } } } } //now go through the Bonds for (int i = 0; i < bonds.size(); i++){ Bond b = (Bond)bonds.get(i); if (b.render == style && b.quality == quality){ continue;//bond hasn't changed } //check whether this is a boundary bond b.render = style; b.quality = quality; structureStylesEvent.structureComponent = b; processStructureStylesEvent( structureStylesEvent ); } structureStylesEvent.batch = false; return; } // Fire the event structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RENDERING; processStructureStylesEvent( structureStylesEvent ); } /** * Applies the requested rendering style to the entire structure * @param style */ public void setRenderingStyle(short style, short quality){ if (style == StylesPreferences.RENDERING_LINES) quality = StylesPreferences.RENDERING_FAST; //go by residues for (int i = 0; i < structureMap.getResidueCount(); i++){ Residue r = structureMap.getResidue(i); setRenderingStyle(r, style, quality, true); } structureStylesEvent.batch = false; } public void setRenderingStyle(Enumeration atoms, short style, short quality, boolean batch, boolean forceVisibility){ if (atoms == null) return; if (style == StylesPreferences.RENDERING_LINES) quality = StylesPreferences.RENDERING_FAST; Vector atomList = new Vector(); Vector bonds = new Vector(); structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RENDERING; structureStylesEvent.batch = batch; while (atoms.hasMoreElements()){ try{ Atom a = (Atom)atoms.nextElement(); // System.out.println("firing for atom = " + a); atomList.add(a); a.render = style; a.quality = quality; if (forceVisibility) a.visible = true; structureStylesEvent.structureComponent = a; processStructureStylesEvent( structureStylesEvent ); Vector bb = structureMap.getBonds(a); if (bb == null) continue; for (int j = 0; j < bb.size(); j++){ Bond b = (Bond)bb.get(j); if (!bonds.contains(b)) bonds.add(b); } } catch (ClassCastException ex){ // ex.printStackTrace(); continue; } } if (bonds.size() == 0) return; //now go through the Bonds for (int i = 0; i < bonds.size(); i++){ Bond b = (Bond)bonds.get(i); b.visible = b.getAtom(0).visible && b.getAtom(1).visible; if (b.render == style && b.quality == quality){ continue;//bond hasn't changed } //check whether this is a boundary bond if (atomList.contains(b.getAtom(0)) && atomList.contains(b.getAtom(1))){ b.render = style; b.quality = quality; structureStylesEvent.structureComponent = b; processStructureStylesEvent( structureStylesEvent ); } else{ //if the neighboring residue is rendered as something other than lines if (style == StylesPreferences.RENDERING_LINES){ setRenderingStyle(b, StylesPreferences.RENDERING_LINES, quality, true); continue; } //if this residue is solid-rendered as well if (atomList.contains(b.getAtom(0))){ //the other atom is in another residue if (b.getAtom(1).render != StylesPreferences.RENDERING_LINES){ //render this bond as stick, and it should work fine setRenderingStyle(b, StylesPreferences.RENDERING_BALL_STICK, quality, true); } } else if (atomList.contains(b.getAtom(1))){ //the other atom is in another residue if (b.getAtom(0).render != StylesPreferences.RENDERING_LINES){ //render this bond as stick, and it should work fine setRenderingStyle(b, StylesPreferences.RENDERING_BALL_STICK, quality, true); } } } } } /* *//** * Set the style for the given structure component and then fire an event * to all listeners. *

* @param * @return * @throws *//* public void setRenderingQuality( StructureComponent structureComponent, int style ) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if ( style >= 0 ) { //first, check if there is already a style with the same value Integer key = new Integer(style); if (renderingQualityStyleReference.containsKey(key)){ renderingQualityStyles.put(structureComponent, renderingQualityStyleReference.get(key)); } else{ RenderingQualityStyle rqs = new RenderingQualityStyle(style); renderingQualityStyles.put(structureComponent, rqs); renderingQualityStyleReference.put(key, rqs); } } */ // Fire the event // processStructureStylesEvent( structureStylesEvent ); // } //radius styles public AtomRadius getAtomRadius( StructureComponent structureComponent ) { // First try to get the object-specific style. AtomRadius style = (AtomRadius) atomRadiusStyles.get( structureComponent ); // Otherwise try to get the default style for the type. if ( style == null ) return defaultAtomRadius; // The style still might be null. return style; } public void setAtomRadius( StructureComponent structureComponent, AtomRadius atomRadius ) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if ( atomRadius != null ) { //first, check if there is already a style with the same hashcode int hash = atomRadius.hashCode(); // System.out.println("new style has hash = " + hash); Set set = styleReference.keySet(); Iterator it = set.iterator(); while (it.hasNext()){ Integer h = (Integer)it.next(); // System.out.println(h.intValue() + ":" + (Style)styleReference.get(h)); if (hash == h.intValue()){ AtomRadius s = (AtomRadius)styleReference.get(h); atomRadiusStyles.put(structureComponent, s); return; } } /** * TODO how to remove Styles from styleReference that are no longer used by any * structure components * Also, need to figure out why identical style objects still give different hash codes * on subsequent passes with the same rendering style!!! */ //at this point, we know there is no existing style with the same attributes //so a new one will be added to the hash atomRadiusStyles.put( structureComponent, atomRadius ); atomRadiusStyleReference.put(new Integer(hash), atomRadius); } } public BondRadius getBondRadius( StructureComponent structureComponent ) { // First try to get the object-specific style. BondRadius style = (BondRadius) bondRadiusStyles.get( structureComponent ); // Otherwise try to get the default style for the type. if ( style == null ) return defaultBondRadius; // The style still might be null. return style; } public void setBondRadius( StructureComponent structureComponent, BondRadius bondRadius ) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if ( bondRadius != null ) { //first, check if there is already a style with the same hashcode int hash = bondRadius.hashCode(); // System.out.println("new style has hash = " + hash); Set set = bondRadiusStyleReference.keySet(); Iterator it = set.iterator(); while (it.hasNext()){ Integer h = (Integer)it.next(); // System.out.println(h.intValue() + ":" + (BondRadius)bondRadiusStyleReference.get(h)); if (hash == h.intValue()){ BondRadius s = (BondRadius)bondRadiusStyleReference.get(h); //check if structureComponent already had another style // if (bondRadiusStyles.containsKey(structureComponent)){ //find out whether its old style is still being used // if (bondRadiusStyle) // } bondRadiusStyles.put(structureComponent, s); Bond b = (Bond)structureComponent; return; } } //at this point, we know there is no existing style with the same attributes //so a new one will be added to the hash bondRadiusStyles.put( structureComponent, bondRadius ); bondRadiusStyleReference.put(new Integer(hash), bondRadius); } } public AtomColor getAtomColor( StructureComponent structureComponent ) { // First try to get the object-specific style. AtomColor color = (AtomColor) atomColorStyles.get( structureComponent ); // Otherwise try to get the default style for the type. if ( color == null ){ return defaultAtomColor; } // The style still might be null. return color; } public void setAtomColor( StructureComponent structureComponent, AtomColor atomColor, boolean fire, boolean batch ) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if ( atomColor != null ) { //first, check if there is already a style with the same hashcode int hash = atomColor.hashCode(); // System.out.println("new style has hash = " + hash); Set set = styleReference.keySet(); Iterator it = set.iterator(); while (it.hasNext()){ Integer h = (Integer)it.next(); // System.out.println(h.intValue() + ":" + (Style)styleReference.get(h)); if (hash == h.intValue()){ AtomColor s = (AtomColor)styleReference.get(h); atomColorStyles.put(structureComponent, s); return; } } //at this point, we know there is no existing style with the same attributes //so a new one will be added to the hash atomColorStyles.put( structureComponent, atomColor ); atomColorStyleReference.put(new Integer(hash), atomColor); if (fire){ structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.batch = batch; structureStylesEvent.property = PROPERTY_COLOR; processStructureStylesEvent( structureStylesEvent ); } } } /** * This method sets all bookkeeping values for colors for atoms and residues in the given * structure and fires one structure-wide event to the viewers. * The structure viewer then runs through all atoms and reads the newly set values, and * the sequence viewer checks all residue color values. * @param residueColor * @param atomColor */ public void setStructureColor(ResidueColor residueColor, AtomColor atomColor){ if (residueColor == null) return; for (int i = 0; i < structureMap.getResidueCount(); i++){ Residue r = structureMap.getResidue(i); this.setResidueColor(r, residueColor, true, true);//fire the event if there is no atomColor event to follow up if (atomColor != null){ for (int j = 0; j < r.getAtomCount(); j++){ this.setAtomColor((Atom)r.getAtom(j), atomColor, true, true); } } } } public BondColor getBondColor( StructureComponent structureComponent ) { // First try to get the object-specific style. BondColor color = (BondColor) atomColorStyles.get( structureComponent ); // Otherwise try to get the default style for the type. if ( color == null ) return defaultBondColor; // The style still might be null. return color; } public void setBondColor( StructureComponent structureComponent, BondColor bondColor ) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if ( bondColor != null ) { //first, check if there is already a style with the same hashcode int hash = bondColor.hashCode(); // System.out.println("new style has hash = " + hash); Set set = styleReference.keySet(); Iterator it = set.iterator(); while (it.hasNext()){ Integer h = (Integer)it.next(); // System.out.println(h.intValue() + ":" + (Style)styleReference.get(h)); if (hash == h.intValue()){ BondColor s = (BondColor)styleReference.get(h); bondColorStyles.put(structureComponent, s); return; } } //at this point, we know there is no existing style with the same attributes //so a new one will be added to the hash bondColorStyles.put( structureComponent, bondColor ); bondColorStyleReference.put(new Integer(hash), bondColor); } } public ResidueColor getResidueColor( StructureComponent structureComponent ) { // First try to get the object-specific style. ResidueColor color = (ResidueColor) residueColorStyles.get( structureComponent ); // Otherwise try to get the default style for the type. if ( color == null ) return defaultResidueColor; // The style still might be null. return color; } /** * Flag "batch" indicates that the event being fired from this method should contain this flag: * the viewers will then refrain from repainting after every residue until further update notice * @param structureComponent * @param residueColor * @param fire */ public void setResidueColor( StructureComponent structureComponent, ResidueColor residueColor, boolean fire, boolean batch ) { if ( structureComponent == null ) return; if ( residueColor != null ) { //first, check if there is already a style with the same hashcode int hash = residueColor.hashCode(); // System.out.println("new style has hash = " + hash); Set set = styleReference.keySet(); Iterator it = set.iterator(); boolean exists = false; while (it.hasNext()){ Integer h = (Integer)it.next(); // System.out.println(h.intValue() + ":" + (Style)styleReference.get(h)); if (hash == h.intValue()){ ResidueColor s = (ResidueColor)styleReference.get(h); residueColorStyles.put(structureComponent, s); exists = true; break; } } //at this point, we know there is no existing style with the same attributes //so a new one will be added to the hash if (!exists){ residueColorStyles.put( structureComponent, residueColor ); residueColorStyleReference.put(new Integer(hash), residueColor); } if (fire){ structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_COLOR; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } } } public RibbonColor getRibbonColor( StructureComponent structureComponent ) { // First try to get the object-specific style. RibbonColor color = (RibbonColor) ribbonColorStyles.get( structureComponent ); // Otherwise try to get the default style for the type. if ( color == null ){ return defaultRibbonColor; } // The style still might be null. return color; } public void setRibbonColor( StructureComponent structureComponent, RibbonColor ribbonColor, boolean fire, boolean batch ) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if ( ribbonColor != null ) { //first, check if there is already a style with the same hashcode int hash = ribbonColor.hashCode(); // System.out.println("new style has hash = " + hash); Set set = styleReference.keySet(); Iterator it = set.iterator(); while (it.hasNext()){ Integer h = (Integer)it.next(); // System.out.println(h.intValue() + ":" + (Style)styleReference.get(h)); if (hash == h.intValue()){ RibbonColor s = (RibbonColor)styleReference.get(h); ribbonColorStyles.put(structureComponent, s); return; } } //at this point, we know there is no existing style with the same attributes //so a new one will be added to the hash ribbonColorStyles.put( structureComponent, ribbonColor ); ribbonColorStyleReference.put(new Integer(hash), ribbonColor); if (fire){ structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RIBBON_COLOR; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } } } public void setRibbonColor( StructureComponent structureComponent, ResidueColor residueColor, boolean fire, boolean batch ) { if ( structureComponent == null ) return; if ( residueColor != null ) { //get a RibbonColor with the same appearance as the residueColor RibbonColor rc = RibbonColorFactory.getRibbonColor(structureComponent, residueColor); //first, check if there is already a style with the same hashcode int hash = rc.hashCode(); // System.out.println("new style has hash = " + hash); Set set = styleReference.keySet(); Iterator it = set.iterator(); while (it.hasNext()){ Integer h = (Integer)it.next(); // System.out.println(h.intValue() + ":" + (Style)styleReference.get(h)); if (hash == h.intValue()){ RibbonColor s = (RibbonColor)styleReference.get(h); ribbonColorStyles.put(structureComponent, s); return; } } //at this point, we know there is no existing style with the same attributes //so a new one will be added to the hash ribbonColorStyles.put( structureComponent, rc ); ribbonColorStyleReference.put(new Integer(hash), rc); if (fire){ structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RIBBON_COLOR; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } } } public void getRibbonColor( Residue residue, float color[] ) throws IllegalArgumentException { if ( residue == null ) throw new IllegalArgumentException( "null residue" ); if ( color == null ) throw new IllegalArgumentException( "null color" ); RibbonColor residueColor = getRibbonColor( residue ); // System.out.println("residueColor = " + residueColor); // ResidueColor residueColor = ResidueColorFactory.getResidueColor(Color.red); residueColor.getRibbonColor( residue, color ); } /** * This method determines whether the chain has any ribbon and whether its residues are * selected. This is used to keep track of which ribbons are selected and which are not * @param chain */ public void updateChain(Chain chain, boolean fire){ //check chain selection status by checking its residues boolean selected = false; for (int i = 0; i < chain.getResidueCount(); i++){ Residue residue = chain.getResidue(i); if (residue.ribbon && isSelected(residue)){ selected = true; break; } else{ //check backbone atoms if (residue.ribbon){ boolean flag = true; for (int j = 0; j < residue.getAtomCount(); j++){ Atom a = residue.getAtom(j); if (a.backbone){ if (!isSelected(a)){ flag = false; break;//selected remains false } } } if (!selected) selected = flag; if (selected) break; } } } // System.out.println("selected = " + selected); if (selected){ if (!selectedChains.contains(chain)) selectedChains.add(chain); } else{ if (selectedChains.contains(chain)){ selectedChains.remove(chain); } else{ //the chain was deselected and remained deselected: no need to fire an event // System.out.println("was deselected and stayed deselected: " + chain.getChainId()); return; } } // System.out.println(chain.getChainId() + ": updateChains = " + selectedChains.size()); if (!fire) return; structureStylesEvent.structureComponent = chain; structureStylesEvent.attribute = ATTRIBUTE_STYLE; structureStylesEvent.property = PROPERTY_RIBBON_COLOR; structureStylesEvent.batch = false; processStructureStylesEvent( structureStylesEvent ); } // // Visibility methods // /** * Set the visibility state for the given structure component and then * fire an event to all listeners. *

* @param * @return * @throws */ public void setVisible( StructureComponent structureComponent, boolean newState, boolean fire, boolean batch ) { if ( structureComponent == null ) throw new NullPointerException( "null structureComponent" ); if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_ATOM){ Atom a = (Atom)structureComponent; if (a.visible == newState) return; a.visible = newState; Vector bb = structureMap.getBonds(a); if (bb != null){ for (int j = 0; j < bb.size(); j++){ Bond b = (Bond)bb.get(j); //check whether the other atom is visible b.visible = b.getAtom(0).visible && b.getAtom(1).visible; } } } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_BOND){ Bond b = (Bond)structureComponent; if (b.visible == newState) return; b.visible = newState; } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_RESIDUE){ Vector bonds = new Vector(); Residue residue = (Residue)structureComponent; residue.visible = newState; Vector atoms = residue.getAtoms(); for (int i = 0; i < atoms.size(); i++){ Atom a = (Atom)atoms.get(i); a.visible = newState; } //now, once all atoms were set, walk over the bonds for (int i = 0; i < atoms.size(); i++){ Atom a = (Atom)atoms.get(i); Vector bb = structureMap.getBonds(a); if (bb == null) continue; for (int j = 0; j < bb.size(); j++){ Bond b = (Bond)bb.get(j); if (!bonds.contains(b)){ b.visible = b.getAtom(0).visible && b.getAtom(1).visible; bonds.add(b); } } } bonds.clear(); } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_CHAIN){ Vector bonds = new Vector(); Chain chain = (Chain)structureComponent; Vector residues = chain.structure.getStructureMap().getResidues(); chain.visible = newState; for (int i = 0; i < residues.size(); i++){ Residue r = (Residue)residues.get(i); if (!r.getChainId().equals(chain.getChainId()))continue; //else scan through the atoms of this residue Vector atoms = r.getAtoms(); for (int j = 0; j < atoms.size(); j++){ Atom a = (Atom)atoms.get(j); a.visible = newState; } for (int j = 0; j < atoms.size(); j++){ Atom a = (Atom)atoms.get(j); Vector bb = structureMap.getBonds(a); if (bb == null) continue; for (int k = 0; k < bb.size(); k++){ Bond b = (Bond)bb.get(k); if (!bonds.contains(b)){ b.visible = b.getAtom(0).visible && b.getAtom(1).visible; bonds.add(b); } } } r.visible = newState; } } // Fire the event if (fire){ structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_VISIBILITY; structureStylesEvent.property = -1; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } } public void setRibbonVisible(Chain chain, boolean visible, boolean fire, boolean batch){ if (visible){ ribbonVisible.add(chain); ribbonInvisible.remove(chain); } else{ ribbonVisible.remove(chain); ribbonInvisible.add(chain); } if (fire){ structureStylesEvent.structureComponent = chain; structureStylesEvent.attribute = ATTRIBUTE_VISIBILITY; structureStylesEvent.property = PROPERTY_RIBBON_VISIBILITY; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } } public boolean isRibbonVisible(Chain chain){ return ribbonVisible.contains(chain); } public int getRibbonType(Chain chain){ if (ribbonTypes.containsKey(chain) && ribbonTypes.get(chain) != null){ return ((Integer)ribbonTypes.get(chain)).intValue(); } return -1; } public void setRibbonType(Chain chain, int type){ ribbonTypes.put(chain, new Integer(type)); } public void removeRibbonType(Chain chain){ //ribbon gets removed if (chain == null) return; ribbonTypes.remove(chain); } public float getRibbonDiameter(Chain chain){ if (ribbonDiameters.containsKey(chain) && ribbonDiameters.get(chain) != null){ return ((Float)ribbonDiameters.get(chain)).floatValue(); } return -1; } public void setRibbonDiameter(Chain chain, float diameter){ ribbonDiameters.put(chain, new Float(diameter)); } public void removeRibbonDiameter(Chain chain){ //ribbon gets removed if (chain == null) return; ribbonDiameters.remove(chain); } public void clearRibbon(Chain chain){ ribbonTypes.remove(chain); ribbonQuality.remove(chain); ribbonDiameters.remove(chain); } public float getRibbonQuality(Chain chain){ if (ribbonQuality.containsKey(chain) && ribbonQuality.get(chain) != null){ return ((Float)ribbonQuality.get(chain)).floatValue(); } return 1.0f; } public void setRibbonQuality(Chain chain, float q){ ribbonQuality.put(chain, new Float(q)); } public void removeRibbonQuality(Chain chain){ //ribbon gets removed if (chain == null) return; ribbonQuality.remove(chain); } /** * Set the visibility state for the entire structure to true * and then fire an event to all listeners. *

* @param * @return * @throws */ public void showAll( boolean batch ) { // System.out.println("Show all"); //walk through all chains for (int i = 0; i < structureMap.getChainCount(); i++){ Chain chain = structureMap.getChain(i); chain.visible = true; for (int j = 0; j < chain.getResidueCount(); j++){ Residue r = chain.getResidue(j); r.visible = true; for (int k = 0; k < r.getAtomCount(); k++){ ((Atom)r.getAtom(k)).visible = true; } } } for (int i = 0; i < structureMap.getBondCount(); i++){ structureMap.getBond(i).visible = true; } // Fire the event structureStylesEvent.structureComponent = null; structureStylesEvent.attribute = ATTRIBUTE_VISIBILITY; structureStylesEvent.property = -1; structureStylesEvent.flag = FLAG_ALL; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } /** * Set the visibility state for the entire structure to false * and then fire an event to all listeners. *

* @param * @return * @throws */ public void hideAll( boolean batch ){ //walk through all chains for (int i = 0; i < structureMap.getChainCount(); i++){ Chain chain = structureMap.getChain(i); chain.visible = false; for (int j = 0; j < chain.getResidueCount(); j++){ Residue r = chain.getResidue(j); r.visible = false; for (int k = 0; k < r.getAtomCount(); k++){ ((Atom)r.getAtom(k)).visible = false; } } } for (int i = 0; i < structureMap.getBondCount(); i++){ structureMap.getBond(i).visible = false; } // Fire the event structureStylesEvent.structureComponent = null; structureStylesEvent.attribute = ATTRIBUTE_VISIBILITY; structureStylesEvent.property = -1; structureStylesEvent.flag = FLAG_NONE; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } // // Selection methods // /** * Set the selection state for the given structure component and then * fire an event to all listeners. *

* @param stuctureComponent The StrucureComponent to be selected. * @param newState The new selection state for the object. * @return NONE. * @throws NullPointerException if StructureComponent is null. */ public void setSelected( StructureComponent structureComponent, boolean newState, boolean fire, boolean batch ) { if ( structureComponent == null ) return; // Set the state for this component. if ( newState ){ selection.put( structureComponent, value); } else{ selection.remove( structureComponent ); } if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_CHAIN){ Chain chain = (Chain)structureComponent; //break it up into residues and handle their selection separately: this will simplify recursion problems, //since there will be no need to recursively update subtree three levels down for (int i = 0; i < chain.getResidueCount(); i++){ setSelected(chain.getResidue(i), newState, true, true); } } // System.out.println("selection for " + structureComponent); // Update selection state for all children updateSelectionSubTree( structureComponent, newState ); // If necessary, set special case flags. if ( selection.size() == 0) selectionFlag = FLAG_NONE; else selectionFlag = FLAG_SOME; // Fire the event if (fire){ structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_SELECTION; structureStylesEvent.property = -1; structureStylesEvent.batch = batch; processStructureStylesEvent( structureStylesEvent ); } structureStylesEvent.batch = false; } /** * Recursively clear selection hash for the the specified sub-tree. */ private void updateSelectionSubTree( StructureComponent structureComponent, boolean newState ) { Vector children = structureMap.getChildren( structureComponent ); if ( children != null ) { for ( int i=0; i * @param * @return * @throws */ public boolean isSelected( StructureComponent structureComponent ) { // Check special cases (for entire Structure object). if ( selectionFlag == FLAG_NONE ){ return false; } else if ( selectionFlag == FLAG_ALL ){ return true; } // If the entire structure is not selected/unselected // and no component was specified, then return false // because the structure is not entirely selected. if ( structureComponent == null ) return false; // Is the component in the hash? if (selection.containsKey(structureComponent)){ return true; } // Check bonds if ( structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_BOND ) { // The Bond is not in the hash, but are both atoms selected? Bond bond = (Bond) structureComponent; Atom atom0 = bond.getAtom( 0 ); Atom atom1 = bond.getAtom( 1 ); if ( isSelected( atom0 ) && isSelected( atom1 ) ) return true; else return false; } // If all else fails, it's not selected. return false; } /** * Set the selection state for the entire structure to true * and then fire an event to all listeners. *

* @param * @return * @throws */ public void selectAll( ) { selection.clear( ); selectionFlag = FLAG_ALL; //walk through all chains for (int i = 0; i < structureMap.getChainCount(); i++){ Chain chain = structureMap.getChain(i); selection.put(chain, value); boolean select = false; for (int j = 0; j < chain.getResidueCount(); j++){ Residue r = chain.getResidue(j); selection.put(r, value); if (r.ribbon) select = true; for (int k = 0; k < r.getAtomCount(); k++){ selection.put(r.getAtom(k), value); } } if (select && !selectedChains.contains(chain)) selectedChains.add(chain); } // System.out.println("selected chains = " + selectedChains); for (int i = 0; i < structureMap.getBondCount(); i++){ selection.put(structureMap.getBond(i), value); } // Fire the event structureStylesEvent.structureComponent = null; structureStylesEvent.attribute = ATTRIBUTE_SELECTION; structureStylesEvent.property = -1; structureStylesEvent.flag = selectionFlag; processStructureStylesEvent( structureStylesEvent ); } /** * Set the selection state for the entire structure to false * and then fire an event to all listeners. aux flag is designed for communication between sequence and structure viewers. * if true, it instructs the structure viewer to include selected chains in the selectNone procedure as well. *

* @param * @return * @throws */ public void selectNone(boolean batch, boolean aux){ if (selection.size() == 0 && selectionFlag == FLAG_NONE) return; //check how many structure components need to be updated. if not many, just call them //indivudually float ratio = ((float)selection.size()/(float)(structureMap.getAtomCount() + structureMap.getBondCount())); //only walk through those components that need to be cleared if (ratio < .3){ Enumeration keys = selection.keys(); Vector items = new Vector(); while (keys.hasMoreElements()){ StructureComponent c = (StructureComponent)keys.nextElement(); items.add(c); } for (int i = 0; i < items.size(); i++){ setSelected((StructureComponent)items.get(i), false, true, batch); } selection.clear(); selectedResidues.clear(); // selectedChains.clear(); selectionFlag = FLAG_NONE; //update chains since no direct call to structure viewer handler is being made structureStylesEvent.aux = aux; for (int i = 0; i < structureMap.getChainCount(); i++){ Chain c = structureMap.getChain(i); // System.out.println("calling update chain = " + c.getChainId()); updateChain(c, true); } } else{ selection.clear(); selectedResidues.clear(); selectionFlag = FLAG_NONE; for (int i = 0; i < structureMap.getChainCount(); i++){ updateChain(structureMap.getChain(i), false); } // System.out.println("firing event with selection = " + selectedChains.size()); // Fire the event structureStylesEvent.structureComponent = null; structureStylesEvent.attribute = ATTRIBUTE_SELECTION; structureStylesEvent.property = -1; structureStylesEvent.flag = selectionFlag; structureStylesEvent.batch = batch; structureStylesEvent.aux = aux; processStructureStylesEvent( structureStylesEvent ); } } public int getSelectionFlag(){ return selectionFlag; } // // StructureStyleEvent methods // /** * Informs all registered listeners that a style has changed. * Called explictly when setStyle is called, or, implictly when * any individual style changes state. *

* @param * @return * @throws */ public void processStructureStylesEvent( StructureStylesEvent structureStylesEvent ) { // Loop through and call all StructureStylesEventListener objects. int listenerCount = listeners.size( ); for ( int i = 0; i < listenerCount; i++ ){ StructureStylesEventListener listener = (StructureStylesEventListener) listeners.elementAt( i ); listener.processStructureStylesEvent( thisObject.structureStylesEvent ); } } /** * Please complete the missing tags for main *

* @param * @return * @throws */ public void addStructureStylesEventListener( StructureStylesEventListener structureStylesEventListener ) { listeners.add( structureStylesEventListener ); } public void addStructureComponentEventListener( StructureComponentEventListener structureComponentEventListener ){ componentListeners.add( structureComponentEventListener ); } /** * Please complete the missing tags for main *

* @param * @return * @throws */ public void removeStructureStylesEventListener( StructureStylesEventListener structureStylesEventListener ) { listeners.remove( structureStylesEventListener ); } public void removeStructureComponentEventListener( StructureComponentEventListener structureComponentEventListener ) { componentListeners.remove( structureComponentEventListener ); } // // StructureComponentEvent methods // public void registerStructureComponentRemoval(StructureComponent structureComponent){ if (structureComponent == null) return; if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_RESIDUE){ Residue r = (Residue)structureComponent; selection.remove( structureComponent ); selectedResidues.remove(structureComponent); } } /** * TODO * temporarily use StructureStyles as a handler of component events. */ public void deleteStructureComponent(StructureComponent structureComponent, boolean fire, boolean batch){ if (structureComponent == null) return; if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_RESIDUE){ Residue r = (Residue)structureComponent; selection.remove( structureComponent ); selectedResidues.remove(structureComponent); Vector bonds = new Vector(); //take care of the constituents: Atoms and Bonds for (int i = 0; i < r.getAtomCount(); i++){ Atom a = r.getAtom(i); selection.remove( a ); selectedAtoms.remove(a); atomColorStyles.remove(structureComponent); atomRadiusStyles.remove(structureComponent); Vector bb = structureMap.getBonds(a); if (bb == null || bb.size() == 0) continue; for (int j = 0; j < bb.size(); j++){ if (!bonds.contains(bb.get(j)))bonds.add(bb.get(j)); } } for (int i = 0; i < bonds.size(); i++){ Bond b = (Bond)bonds.get(i); selection.remove( b ); bondColorStyles.remove(b); bondRadiusStyles.remove(b); } //fire the event if (fire){ structureComponentEvent.structureComponent = r; structureComponentEvent.batch = batch; structureComponentEvent.changeType = StructureComponentEvent.TYPE_REMOVE; structureComponentEvent.changeExtent = StructureComponentEvent.EXTENT_GLOBAL; fireStructureComponentEvent(structureComponentEvent); } } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_ATOM){ Atom a = (Atom)structureComponent; selection.remove( a ); selectedAtoms.remove(a); atomColorStyles.remove(a); atomRadiusStyles.remove(a); if (fire){ structureComponentEvent.structureComponent = a; structureComponentEvent.batch = batch; structureComponentEvent.changeType = StructureComponentEvent.TYPE_REMOVE; structureComponentEvent.changeExtent = StructureComponentEvent.EXTENT_GLOBAL; fireStructureComponentEvent(structureComponentEvent); } } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_BOND){ Bond b = (Bond)structureComponent; selection.remove( b ); bondColorStyles.remove(b); bondRadiusStyles.remove(b); if (fire){ structureComponentEvent.structureComponent = b; structureComponentEvent.batch = batch; structureComponentEvent.changeType = StructureComponentEvent.TYPE_REMOVE; structureComponentEvent.changeExtent = StructureComponentEvent.EXTENT_GLOBAL; fireStructureComponentEvent(structureComponentEvent); } } } public void fireGeometryChangeEvent(Residue r){ structureComponentEvent.structureComponent = r; structureComponentEvent.batch = false; structureComponentEvent.changeType = StructureComponentEvent.TYPE_GEOMETRY_CHANGE; structureComponentEvent.changeExtent = StructureComponentEvent.EXTENT_GLOBAL; fireStructureComponentEvent(structureComponentEvent); } public void replaceStructureComponent(StructureComponent structureComponent, String replacement){ if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_RESIDUE){ Residue residue = (Residue)structureComponent; //check replacement if (ProteinProperties.isAminoAcid(replacement) || replacement.equals("undo")){ StructureComponentEvent event = new StructureComponentEvent(); event.structureComponent = structureComponent; event.batch = false; event.data = replacement; if (replacement.equals("undo")){ event.changeType = StructureComponentEvent.TYPE_UNDO_REPLACE; } else{ event.changeType = StructureComponentEvent.TYPE_REPLACE; } event.changeExtent = StructureComponentEvent.EXTENT_GLOBAL; fireStructureComponentEvent(event); } } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_ATOM){ Atom atom = (Atom)structureComponent; String el = atom.getElement(); atom.name = atom.name.replaceFirst(el, replacement); //get the element atom.setElement(replacement); //reset its hybridization atom.hybridization = Atom.SP3; atom.formalCharge = 0; StructureComponentEvent event = new StructureComponentEvent(); event.structureComponent = structureComponent; event.batch = false; event.data = replacement; event.changeExtent = StructureComponentEvent.EXTENT_GLOBAL; event.changeType = StructureComponentEvent.TYPE_REPLACE; fireStructureComponentEvent(event); } } public void addStructureComponent(StructureComponent structureComponent, short inputStyle, short inputQuality, boolean batch){ if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_BOND){ setSelected( structureComponent, false, false, false ); //get the rendering style and quality of the atoms that are connected by this bond Atom a0 = ((Bond)structureComponent).getAtom(0); Atom a1 = ((Bond)structureComponent).getAtom(1); short style = 0; if (inputStyle > -1){ style = inputStyle; } else{ short style0 = a0.render; short style1 = a1.render; style = (short)Math.min(style0, style1); } //set the appropriate bond radius if (style == StylesPreferences.RENDERING_STICK){ setBondRadius(structureComponent, BondRadiusByAtomRadius.create()); } if (inputQuality > -1){ setRenderingStyle(structureComponent, style, inputQuality, batch); } else{ short q0 = a0.quality; short q1 = a1.quality; if (q0 == q1){ setRenderingStyle(structureComponent, style, q0, batch); } else if (q0 > q1){ setRenderingStyle(structureComponent, style, q1, batch); } else { setRenderingStyle(structureComponent, style, q0, batch); } } structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.batch = batch; structureStylesEvent.attribute = StructureStyles.ATTRIBUTE_STYLE; structureStylesEvent.property = StructureStyles.PROPERTY_RENDERING; fireStructureStylesEvent(structureStylesEvent); } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_ATOM){ setSelected( structureComponent, false, false, false ); short style = 0; if (inputStyle > -1){ style = inputStyle; } if (inputQuality > -1){ setRenderingStyle(structureComponent, style, inputQuality, batch); } else{ setRenderingStyle(structureComponent, style, zero, batch); } structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.batch = batch; structureStylesEvent.attribute = StructureStyles.ATTRIBUTE_STYLE; structureStylesEvent.property = StructureStyles.PROPERTY_RENDERING; fireStructureStylesEvent(structureStylesEvent); } else if (structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_RESIDUE){ // Residue residue = (Residue)structureComponent; //this is a newly added residue structureComponentEvent.structureComponent = structureComponent; structureComponentEvent.batch = batch; structureComponentEvent.changeType = StructureComponentEvent.TYPE_ADD; structureComponentEvent.changeExtent = StructureComponentEvent.EXTENT_GLOBAL; fireStructureComponentEvent(structureComponentEvent); } } /** * Please complete the missing tags for main *

* @param * @return * @throws */ public void processStructureComponentEvent( StructureComponentEvent sce ) { StructureComponent structureComponent = sce.structureComponent; if ( sce.changeType == StructureComponentEvent.TYPE_REMOVE ) { // Remove all style references to the given StructureComponent. selection.remove( structureComponent ); selectedAtoms.remove(structureComponent); selectedResidues.remove(structureComponent); // System.out.println("removed " + structureComponent + ", visibility size = " + visibility.size()); //check if it's an atom, bond, etc. and remove the entry from the corresponding style hash if ( structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_BOND ) { bondColorStyles.remove(structureComponent); bondRadiusStyles.remove(structureComponent); } if ( structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_ATOM ) { atomColorStyles.remove(structureComponent); atomRadiusStyles.remove(structureComponent); } } if ( sce.changeType == StructureComponentEvent.TYPE_ADD ) { // Remove all style references to the given StructureComponent. setVisible( structureComponent, true, true, false ); setSelected( structureComponent, false, false, false ); // System.out.println("before handler"); //check if it's an atom, bond, etc. and remove the entry from the corresponding style hash if ( structureComponent.getStructureComponentType() == StructureComponentRegistry.TYPE_BOND ){ // System.out.println("adding bond in styles"); //get the rendering style and quality of the atoms that are connected by this bond Atom a0 = ((Bond)structureComponent).getAtom(0); Atom a1 = ((Bond)structureComponent).getAtom(1); short style0 = a0.render; short style1 = a1.render; short q0 = a0.quality; short q1 = a1.quality; short style = (short)Math.min(style0, style1); //set the appropriate bond radius if (style == StylesPreferences.RENDERING_STICK){ setBondRadius(structureComponent, BondRadiusByAtomRadius.create()); } if (q0 == q1){ setRenderingStyle(structureComponent, style, q0, false); } else if (q0 > q1){ setRenderingStyle(structureComponent, style, q1, false); } else { setRenderingStyle(structureComponent, style, q0, false); } } // Fire a style event to viewers structureStylesEvent.structureComponent = structureComponent; structureStylesEvent.attribute = ATTRIBUTE_VISIBILITY; structureStylesEvent.property = -1; processStructureStylesEvent( structureStylesEvent ); } } /** * Fire a StructureStylesEvent to all listeners. */ private void fireStructureStylesEvent( StructureStylesEvent structureStylesEvent ) { for ( int i=0; i 0) selectionFlag = FLAG_SOME; if (selection.size() == 0) selectionFlag = FLAG_NONE; // System.out.println("size of selection = " + selection.size()); // Fire the event structureStylesEvent.structureComponent = null; structureStylesEvent.attribute = ATTRIBUTE_SELECTION; structureStylesEvent.property = -1; structureStylesEvent.flag = selectionFlag; processStructureStylesEvent( structureStylesEvent ); } // // Residue Styles // /** * This method imports styles from a different StructureStyles object */ public void addStyles(StructureStyles s){ atomColorStyleReference.putAll(s.getAtomColorStyleReference()); atomColorStyles.putAll(s.getAtomColorStyles()); atomRadiusStyleReference.putAll(s.getAtomRadiusStyleReference()); atomRadiusStyles.putAll(s.getAtomRadiusStyles()); bondColorStyleReference.putAll(s.getBondColorStyleReference()); bondColorStyles.putAll(s.getBondColorStyles()); bondRadiusStyleReference.putAll(s.getBondRadiusStyleReference()); bondRadiusStyles.putAll(s.getBondRadiusStyles()); residueColorStyleReference.putAll(s.getResidueColorStyleReference()); residueColorStyles.putAll(s.getResidueColorStyles()); ribbonColorStyleReference.putAll(s.getRibbonColorStyleReference()); ribbonColorStyles.putAll(s.getRibbonColorStyles()); selection.putAll(s.getSelection()); styleReference.putAll(s.getStyleReference()); } /** * @return Returns the atomColorStyleReference. */ public final HashMap getAtomColorStyleReference() { return atomColorStyleReference; } /** * @return Returns the atomColorStyles. */ public final HashMap getAtomColorStyles() { return atomColorStyles; } /** * @return Returns the atomRadiusStyleReference. */ public final HashMap getAtomRadiusStyleReference() { return atomRadiusStyleReference; } /** * @return Returns the atomRadiusStyles. */ public final HashMap getAtomRadiusStyles() { return atomRadiusStyles; } /** * @return Returns the bondColorStyleReference. */ public final HashMap getBondColorStyleReference() { return bondColorStyleReference; } /** * @return Returns the bondColorStyles. */ public final HashMap getBondColorStyles() { return bondColorStyles; } /** * @return Returns the bondRadiusStyleReference. */ public final HashMap getBondRadiusStyleReference() { return bondRadiusStyleReference; } /** * @return Returns the bondRadiusStyles. */ public final HashMap getBondRadiusStyles() { return bondRadiusStyles; } /** * @return Returns the residueColorStyleReference. */ public final HashMap getResidueColorStyleReference() { return residueColorStyleReference; } /** * @return Returns the residueColorStyles. */ public final HashMap getResidueColorStyles() { return residueColorStyles; } /** * @return Returns the ribbonColorStyleReference. */ public final HashMap getRibbonColorStyleReference() { return ribbonColorStyleReference; } /** * @return Returns the ribbonColorStyles. */ public final HashMap getRibbonColorStyles() { return ribbonColorStyles; } /** * @return Returns the selection. */ public final Hashtable getSelection() { return selection; } /** * @return Returns the styleReference. */ public final HashMap getStyleReference() { return styleReference; } public void setSelectedChains(Vector chains){ selectedChains = chains; } }