JAL-3438 spotless for 2.11.2.0
[jalview.git] / src / ext / edu / ucsf / rbvi / strucviz2 / ChimeraTreeModel.java
1 /* vim: set ts=2: */
2 /**
3  * Copyright (c) 2006 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *   1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions, and the following disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions, and the following
13  *      disclaimer in the documentation and/or other materials provided
14  *      with the distribution.
15  *   3. Redistributions must acknowledge that this software was
16  *      originally developed by the UCSF Computer Graphics Laboratory
17  *      under support by the NIH National Center for Research Resources,
18  *      grant P41-RR01081.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 package ext.edu.ucsf.rbvi.strucviz2;
34
35 // System imports
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.List;
40
41 import javax.swing.JTree;
42 import javax.swing.tree.DefaultMutableTreeNode;
43 import javax.swing.tree.DefaultTreeModel;
44 import javax.swing.tree.TreePath;
45 // Cytoscape imports
46 // StructureViz imports
47
48 /**
49  * The ChimeraTreeModel class provides the underlying model for the navigation
50  * tree in the ModelNavigatorDialog.
51  *
52  * @author scooter
53  * @see ModelNavigatorDialog
54  */
55 public class ChimeraTreeModel extends DefaultTreeModel
56 {
57   private ChimeraManager chimeraManager;
58
59   private JTree navigationTree;
60
61   private int residueDisplay = ChimeraResidue.THREE_LETTER;
62
63   /**
64    * Constructor for the ChimeraTreeModel.
65    *
66    * @param chimeraObject
67    *          the Chimera object that this tree represents
68    * @param tree
69    *          the JTree used to display the object
70    * @see Chimera
71    */
72   public ChimeraTreeModel(ChimeraManager chimeraManager, JTree tree)
73   {
74     super(new DefaultMutableTreeNode());
75     this.chimeraManager = chimeraManager;
76     this.navigationTree = tree;
77     DefaultMutableTreeNode rootNode = buildTree();
78     this.setRoot(rootNode);
79   }
80
81   /**
82    * Set the display type for the residues. The display type must be one of:
83    *
84    * ChimeraResidue.THREE_LETTER ChimeraResidue.SINGLE_LETTER
85    * ChimeraResidue.FULL_NAME
86    *
87    * @param newDisplay
88    *          the display type
89    * @see ChimeraResidue
90    */
91   public void setResidueDisplay(int newDisplay)
92   {
93     this.residueDisplay = newDisplay;
94   }
95
96   /**
97    * This method is called to rebuild the tree model "from scratch"
98    */
99   public void reload()
100   {
101     // First, rebuild the tree with the new data
102     DefaultMutableTreeNode rootNode = buildTree();
103     this.setRoot(rootNode);
104
105     // Now let the superclass do all of the work
106     super.reload();
107   }
108
109   /**
110    * Rebuild an existing tree
111    */
112   public void rebuildTree()
113   {
114     DefaultMutableTreeNode rootNode = buildTree();
115     DefaultTreeModel model = (DefaultTreeModel) navigationTree.getModel();
116     model.setRoot(rootNode);
117     model.reload();
118   }
119
120   /**
121    * Build the tree from the current Chimera data
122    *
123    * @return DefaultMutableTreeNode that represents the currently loaded Chimera
124    *         models
125    */
126   private DefaultMutableTreeNode buildTree()
127   {
128     int modelCount = chimeraManager.getChimeraModelsCount(true);
129     DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
130             modelCount + " Open Chimera Models");
131     TreePath rootPath = new TreePath(rootNode);
132
133     TreePath path = null;
134     DefaultMutableTreeNode model = null;
135
136     // Add all of the Chimera models
137     for (ChimeraModel chimeraModel : chimeraManager.getChimeraModels())
138     {
139       model = new DefaultMutableTreeNode(chimeraModel);
140       path = rootPath.pathByAddingChild(model);
141       chimeraModel.setUserData(path);
142       addChainNodes(chimeraModel, model, path);
143       rootNode.add(model);
144     }
145     return rootNode;
146   }
147
148   /**
149    * add chains to a tree model
150    *
151    * @param chimeraModel
152    *          the ChimeraModel to get the chains from
153    * @param treeModel
154    *          the tree model to add the chains to
155    * @param treePath
156    *          the tree path where the chains should be added
157    */
158   private void addChainNodes(ChimeraModel chimeraModel,
159           DefaultMutableTreeNode treeModel, TreePath treePath)
160   {
161     DefaultMutableTreeNode chain = null;
162     TreePath chainPath = null;
163
164     // Get the list of chains
165     Collection<ChimeraChain> chainList = chimeraModel.getChains();
166
167     if (chainList.size() == 0)
168     {
169       // No chains! Just add the residues
170       addResidues(chimeraModel.getResidues(), treeModel, treePath);
171       return;
172     }
173
174     // Iterate over the chains and add the chain and all of
175     // the chain's residues
176     for (ChimeraChain chimeraChain : chainList)
177     {
178       chain = new DefaultMutableTreeNode(chimeraChain);
179       chainPath = treePath.pathByAddingChild(chain);
180       chimeraChain.setUserData(chainPath);
181       addResidues(chimeraChain.getResidues(), chain, chainPath);
182       treeModel.add(chain);
183     }
184   }
185
186   /**
187    * add residues to a tree model
188    *
189    * @param residues
190    *          the residues to add
191    * @param treeModel
192    *          the tree model to add the residues to
193    * @param treePath
194    *          the tree path where the residues should be added
195    */
196   private void addResidues(Collection<ChimeraResidue> residues,
197           DefaultMutableTreeNode treeModel, TreePath treePath)
198   {
199     DefaultMutableTreeNode residue = null;
200     TreePath residuePath = null;
201
202     List<ChimeraResidue> sortedResidues = new ArrayList<ChimeraResidue>(
203             residues);
204     Collections.sort(sortedResidues);
205
206     // Iterate over all residues & add them to the tree
207     for (ChimeraResidue res : sortedResidues)
208     {
209       res.setDisplayType(this.residueDisplay);
210       residue = new DefaultMutableTreeNode(res);
211       residuePath = treePath.pathByAddingChild(residue);
212       res.setUserData(residuePath);
213       treeModel.add(residue);
214     }
215   }
216 }