Newer
Older
/* GeneComponentTree.java
*
* created: 2006
*
* This file is part of Artemis
*
* Copyright(C) 2006 Genome Research Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or(at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/genebuilder/GeneComponentTree.java,v 1.14 2007-01-30 17:22:46 tjc Exp $
*/
package uk.ac.sanger.artemis.components.genebuilder;
import uk.ac.sanger.artemis.io.ChadoCanonicalGene;
import uk.ac.sanger.artemis.io.Feature;
import uk.ac.sanger.artemis.io.InvalidRelationException;
import uk.ac.sanger.artemis.Selection;
import uk.ac.sanger.artemis.FeatureVector;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
/**
* Tree to display a gene hierarchy.
*/
public class GeneComponentTree extends JTree
{
private ChadoCanonicalGene chado_gene;
private GeneBuilderFrame gene_builder;
private Selection selection;
private GeneTreeSelectionListener selection_listener;
final GeneBuilderFrame gene_builder,
final Selection selection)
this.chado_gene = chado_gene;
this.gene_builder = gene_builder;
this.selection = selection;
final String gene_id;
try
{
gene_id = (String)gene.getQualifierByName("ID").getValues().get(0);
DefaultMutableTreeNode top =
new DefaultMutableTreeNode(gene_id);
createNodes(top, chado_gene);
DefaultTreeModel model = new DefaultTreeModel(top);
setModel(model);
}
catch(InvalidRelationException e)
{
e.printStackTrace();
}
//Listen for when a file is selected
selection_listener = new GeneTreeSelectionListener();
addTreeSelectionListener(selection_listener);
}
/**
* Select the tree nodes based on the features selected.
* @param selection
*/
protected void setSelection(Selection selection)
{
FeatureVector features = selection.getAllFeatures();
TreePath path[] = new TreePath[features.size()];
for(int i=0; i<features.size(); i++)
{
uk.ac.sanger.artemis.Feature feature =
(uk.ac.sanger.artemis.Feature)features.elementAt(i);
try
{
String id =
(String)feature.getQualifierByName("ID").getValues().get(0);
DefaultMutableTreeNode node = getNodeFromName(id);
if(node == null)
return;
path[i] = new TreePath(node.getPath());
}
catch(InvalidRelationException e)
{
e.printStackTrace();
}
}
setSelectionPaths(path);
}
/**
* Build the node hierarchy for this gene, i.e. transcript, exons,
* CDS, polypeptide.
* @param gene_node
* @param chado_gene
* @throws InvalidRelationException
*/
private void createNodes(final DefaultMutableTreeNode gene_node,
final ChadoCanonicalGene chado_gene)
throws InvalidRelationException
{
String transcript_id;
String exon_id;
String protein_id;
DefaultMutableTreeNode transcript_node;
DefaultMutableTreeNode exon_node;
DefaultMutableTreeNode protein_node;
for(int i=0; i<transcripts.size(); i++)
{
transcript = (Feature)transcripts.get(i);
transcript_id =
(String)transcript.getQualifierByName("ID").getValues().get(0);
transcript_node = new DefaultMutableTreeNode(transcript_id);
gene_node.add(transcript_node);
List exons = chado_gene.getSplicedFeaturesOfTranscript(transcript_id);
if(exons == null)
continue;
for(int j=0; j<exons.size(); j++)
{
exon = (Feature)exons.get(j);
exon_id = (String)exon.getQualifierByName("ID").getValues().get(0);
exon_node = new DefaultMutableTreeNode(exon_id);
transcript_node.add(exon_node);
}
// utr & other features
List utrs3 = chado_gene.get3UtrOfTranscript(transcript_id);
List utrs5 = chado_gene.get5UtrOfTranscript(transcript_id);
List others = chado_gene.getOtherFeaturesOfTranscript(transcript_id);
List utrs = new Vector();
if(utrs3 != null)
utrs.addAll(utrs3);
if(utrs5 != null)
utrs.addAll(utrs5);
for(int j=0; j<utrs.size(); j++)
{
Feature utr = (Feature)utrs.get(j);
String utr_id = (String)utr.getQualifierByName("ID").getValues().get(0);
transcript_node.add(new DefaultMutableTreeNode(utr_id));
}
// protein
protein = chado_gene.getProteinOfTranscript(transcript_id);
(String)((Feature)protein).getQualifierByName("ID").getValues().get(0);
protein_node = new DefaultMutableTreeNode(protein_id);
transcript_node.add(protein_node);
}
}
/**
* Change a node name.
* @param old_id the old uniquename of the feature
* @param new_id the new uniquename of the feature
*/
protected void changeNode(String old_id, String new_id)
{
DefaultMutableTreeNode change_node = getNodeFromName(old_id);
if(change_node != null)
{
change_node.setUserObject(new_id);
}
/**
* Get the node in the tree with a given name. If it is not part
* of the tree return null.
* @param name
* @return
*/
private DefaultMutableTreeNode getNodeFromName(final String name)
{
DefaultMutableTreeNode root = (DefaultMutableTreeNode)getModel().getRoot();
if(name.equals((String)root.getUserObject()))
return root;
DefaultMutableTreeNode change_node = searchChildren(root, name);
if(change_node != null)
return change_node;
Enumeration root_children = root.children();
while(root_children.hasMoreElements())
{
DefaultMutableTreeNode child =
(DefaultMutableTreeNode)root_children.nextElement();
change_node = searchChildren(child, name);
}
/**
* Delete a node and all its descendents from the tree.
* @param id the uniquename of the feature being removed
*/
protected void deleteNode(final String id)
{
DefaultMutableTreeNode root = (DefaultMutableTreeNode)getModel().getRoot();
deleteChildNode(id,root);
}
/**
* Recursively check children of the parent node against the ID
* and delete the child that matches the ID.
* @param id
* @param parentNode
*/
private void deleteChildNode(final String id,
final DefaultMutableTreeNode parentNode)
{
Enumeration root_children = parentNode.children();
while(root_children.hasMoreElements())
{
DefaultMutableTreeNode child =
(DefaultMutableTreeNode)root_children.nextElement();
// check children of this node!!
if(child.getSiblingCount() > 0)
deleteChildNode(id, child);
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/**
* Add a new node for the selected feature. It uses the Parent
* qualifier information to work out where it should be added.
* @param feature
*/
protected void addNode(final uk.ac.sanger.artemis.Feature feature)
{
try
{
String parent =
(String)feature.getQualifierByName("Parent").getValues().get(0);
String name =
(String)feature.getQualifierByName("ID").getValues().get(0);
if(getNodeFromName(name) != null)
return;
DefaultMutableTreeNode parentNode = getNodeFromName(parent);
if(parentNode != null)
{
((DefaultTreeModel)getModel()).insertNodeInto(
new DefaultMutableTreeNode(name), parentNode,
parentNode.getChildCount());
}
}
catch(InvalidRelationException e)
{
e.printStackTrace();
}
}
private DefaultMutableTreeNode searchChildren(
final DefaultMutableTreeNode node,
final String id)
{
Enumeration root_children = node.children();
while(root_children.hasMoreElements())
{
DefaultMutableTreeNode child =
(DefaultMutableTreeNode)root_children.nextElement();
if(id.equals((String)child.getUserObject()))
return child;
}
return null;
}
class GeneTreeSelectionListener implements TreeSelectionListener
{
public void valueChanged(TreeSelectionEvent e)
{
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)GeneComponentTree.this.getLastSelectedPathComponent();
if(node == null)
return;
Feature embl_feature =
(Feature)chado_gene.getFeatureFromId((String)node.getUserObject());
uk.ac.sanger.artemis.Feature feature =
(uk.ac.sanger.artemis.Feature)embl_feature.getUserData();
if(feature == null)
feature = new uk.ac.sanger.artemis.Feature(embl_feature);
gene_builder.setActiveFeature(feature);
selection.set(feature);