/* vim: set ts=2: */ /** * Copyright (c) 2006 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions, and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * 3. Redistributions must acknowledge that this software was * originally developed by the UCSF Computer Graphics Laboratory * under support by the NIH National Center for Research Resources, * grant P41-RR01081. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ package ext.edu.ucsf.rbvi.strucviz2; // System imports import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; // Cytoscape imports // StructureViz imports /** * The ChimeraTreeModel class provides the underlying model * for the navigation tree in the ModelNavigatorDialog. * * @author scooter * @see ModelNavigatorDialog */ public class ChimeraTreeModel extends DefaultTreeModel { private ChimeraManager chimeraManager; private JTree navigationTree; private int residueDisplay = ChimeraResidue.THREE_LETTER; /** * Constructor for the ChimeraTreeModel. * * @param chimeraObject the Chimera object that this tree represents * @param tree the JTree used to display the object * @see Chimera */ public ChimeraTreeModel (ChimeraManager chimeraManager, JTree tree) { super(new DefaultMutableTreeNode()); this.chimeraManager = chimeraManager; this.navigationTree = tree; DefaultMutableTreeNode rootNode = buildTree(); this.setRoot(rootNode); } /** * Set the display type for the residues. The display type * must be one of: * * ChimeraResidue.THREE_LETTER * ChimeraResidue.SINGLE_LETTER * ChimeraResidue.FULL_NAME * * @param newDisplay the display type * @see ChimeraResidue */ public void setResidueDisplay(int newDisplay) { this.residueDisplay = newDisplay; } /** * This method is called to rebuild the tree model "from scratch" */ public void reload() { // First, rebuild the tree with the new data DefaultMutableTreeNode rootNode = buildTree(); this.setRoot(rootNode); // Now let the superclass do all of the work super.reload(); } /** * Rebuild an existing tree */ public void rebuildTree() { DefaultMutableTreeNode rootNode = buildTree(); DefaultTreeModel model = (DefaultTreeModel)navigationTree.getModel(); model.setRoot(rootNode); model.reload(); } /** * Build the tree from the current Chimera data * * @return DefaultMutableTreeNode that represents the currently loaded Chimera models */ private DefaultMutableTreeNode buildTree() { int modelCount = chimeraManager.getChimeraModelsCount(true); DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(modelCount+" Open Chimera Models"); TreePath rootPath = new TreePath(rootNode); TreePath path = null; DefaultMutableTreeNode model = null; // Add all of the Chimera models for (ChimeraModel chimeraModel: chimeraManager.getChimeraModels()) { model = new DefaultMutableTreeNode(chimeraModel); path = rootPath.pathByAddingChild(model); chimeraModel.setUserData(path); addChainNodes(chimeraModel, model, path); rootNode.add(model); } return rootNode; } /** * add chains to a tree model * * @param chimeraModel the ChimeraModel to get the chains from * @param treeModel the tree model to add the chains to * @param treePath the tree path where the chains should be added */ private void addChainNodes(ChimeraModel chimeraModel, DefaultMutableTreeNode treeModel, TreePath treePath) { DefaultMutableTreeNode chain = null; TreePath chainPath = null; // Get the list of chains Collection chainList = chimeraModel.getChains(); if (chainList.size() == 0) { // No chains! Just add the residues addResidues(chimeraModel.getResidues(), treeModel, treePath); return; } // Iterate over the chains and add the chain and all of // the chain's residues for (ChimeraChain chimeraChain: chainList) { chain = new DefaultMutableTreeNode(chimeraChain); chainPath = treePath.pathByAddingChild(chain); chimeraChain.setUserData(chainPath); addResidues(chimeraChain.getResidues(), chain, chainPath); treeModel.add(chain); } } /** * add residues to a tree model * * @param residues the residues to add * @param treeModel the tree model to add the residues to * @param treePath the tree path where the residues should be added */ private void addResidues(Collection residues, DefaultMutableTreeNode treeModel, TreePath treePath) { DefaultMutableTreeNode residue = null; TreePath residuePath = null; List sortedResidues = new ArrayList(residues); Collections.sort(sortedResidues); // Iterate over all residues & add them to the tree for (ChimeraResidue res: sortedResidues) { res.setDisplayType(this.residueDisplay); residue = new DefaultMutableTreeNode(res); residuePath = treePath.pathByAddingChild(residue); res.setUserData(residuePath); treeModel.add(residue); } } }