001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021 022package org.biojava.bio.gui; 023 024import java.util.ArrayList; 025import java.util.Iterator; 026 027import javax.swing.JTree; 028import javax.swing.event.TreeModelListener; 029import javax.swing.tree.TreeModel; 030import javax.swing.tree.TreePath; 031 032import org.biojava.bio.Annotation; 033import org.biojava.bio.BioException; 034import org.biojava.bio.seq.Feature; 035import org.biojava.bio.seq.FeatureFilter; 036import org.biojava.bio.seq.FeatureHolder; 037import org.biojava.bio.seq.Sequence; 038import org.biojava.bio.seq.SequenceIterator; 039import org.biojava.bio.seq.db.SequenceDB; 040 041/** 042 * FeatureTree is GUI tree to display the features and annotations 043 * of the sequences in a <code>SequenceDB</code> Nested Features are 044 * displayed as expandable leaves. 045 * 046 * <p>Copyright: Copyright (c) 2002</p> 047 * <p>Company: AgResearch</p> 048 * 049 * @author Mark Schreiber 050 * @version 1.0 051 */ 052 053public class FeatureTree extends JTree{ 054 private String root = "DB"; 055 private ArrayList seqs = new ArrayList(); 056 057 /** 058 * Create a new FeatureTree 059 */ 060 public FeatureTree() { 061 super(); 062 this.setModel(new FeatureModel(root)); 063 } 064 065 /** 066 * Use this method to provide the sequences for the tree to work with. 067 * @param db A database of <CODE>Sequence</CODE>s to display 068 * @throws org.biojava.bio.BioException if information cannot be retrieved from <CODE>db</CODE> 069 */ 070 public void setSequenceDB(SequenceDB db) throws BioException{ 071 for(SequenceIterator i = db.sequenceIterator(); i.hasNext();){ 072 seqs.add(i.nextSequence()); 073 } 074 this.expandRow(0); 075 this.repaint(); 076 } 077 078 /** 079 * Labels <code>Sequence</code> objects with their name, <code>Annotations</code> with 080 * the tag Annotations, <code>Features</code> with the tag Features and other objects 081 * with the <code>toString</code> value. 082 */ 083 public String convertValueToText(Object value, boolean selected, 084 boolean expanded, boolean leaf, int row, 085 boolean hasFocus) { 086 if(value instanceof Sequence) return ((Sequence)value).getName(); 087 if(value instanceof Annotation) return "Annotations"; 088 if(value instanceof Feature) return value.toString(); 089 if(value instanceof FeatureHolder) return "Features"; 090 else if(value != null) return value.toString(); 091 return ""; 092 } 093 094 /** 095 * The model used by the FeatureTree 096 */ 097 class FeatureModel implements TreeModel { 098 protected String root; 099 100 public FeatureModel(String root){ 101 this.root = root; 102 } 103 104 public Object getRoot(){ return root;} 105 106 public boolean isLeaf(Object node){ 107 if(node.equals(getRoot())){ 108 if(seqs.size()==0) return true; 109 else return false; 110 } 111 if(node instanceof FeatureHolder){ 112 return false; 113 } 114 if(node.equals(Annotation.EMPTY_ANNOTATION)){ 115 return true; 116 } 117 if(node instanceof String) return true; 118 return false; 119 } 120 121 public int getChildCount(Object parent){ 122 if(parent.equals(this.getRoot())) return seqs.size(); 123 else if(parent instanceof Sequence){ 124 return 3; //annotation + feature holder + SymbolList 125 } 126 if(parent instanceof Annotation){ 127 return ((Annotation)parent).keys().size(); 128 } 129 if(parent instanceof Feature){ 130 return 3;//for annotation + Sequence + Nested Features 131 } 132 if(parent instanceof FeatureHolder){ 133 return ((FeatureHolder)parent).countFeatures(); 134 } 135 136 return 0; 137 } 138 139 public Object getChild(Object parent, int index){ 140 if(parent.equals(getRoot())){ 141 return ((Sequence)seqs.get(index)); 142 }else if(parent instanceof Sequence){ 143 if(index == 0) return ((Sequence)parent).getAnnotation(); 144 if(index == 1) return ((Sequence)parent).filter(FeatureFilter.all,false); 145 else return ((Sequence)parent).seqString(); 146 }else if(parent instanceof Feature){ 147 if(index == 0)return ((Feature)parent).getAnnotation(); 148 if(index == 1)return ((Feature)parent).filter(FeatureFilter.all,false); 149 else return ((Feature)parent).getSymbols().seqString(); 150 151 }else if(parent instanceof FeatureHolder){ 152 ArrayList al = new ArrayList(); 153 for(Iterator i = ((FeatureHolder)parent).features(); i.hasNext();){ 154 al.add(i.next()); 155 } 156 157 Feature f = (Feature)al.get(index); 158 return f; 159 }else{//parent must be Annotation 160 ArrayList al = new ArrayList(); 161 for(Iterator i = ((Annotation)parent).keys().iterator(); i.hasNext();){ 162 Object key = i.next(); 163 Object value = ((Annotation)parent).getProperty(key); 164 al.add(key.toString()+" : "+value.toString()); 165 } 166 return al.get(index); 167 } 168 } 169 170 public int getIndexOfChild(Object parent, Object child){ 171 if(parent.equals(getRoot())){ 172 for(int i = 0; i < seqs.size(); i++){ 173 if(seqs.get(i).equals(child)) return i; 174 } 175 }else if(parent instanceof Sequence || parent instanceof Feature){ 176 if(child instanceof Annotation)return 0; 177 if(child instanceof FeatureHolder)return 1; 178 else return 2; 179 }else if(parent instanceof FeatureHolder){ 180 ArrayList al = new ArrayList(); 181 for(Iterator i = ((FeatureHolder)parent).features(); i.hasNext();){ 182 al.add(i.next()); 183 } 184 for(int i = 0; i < al.size(); i++){ 185 if(al.get(i).equals(child)) return i; 186 } 187 }else if(parent instanceof Annotation){ 188 ArrayList al = new ArrayList(); 189 for(Iterator i = ((Annotation)parent).keys().iterator(); i.hasNext();){ 190 Object key = i.next(); 191 Object value = ((Annotation)parent).getProperty(key); 192 al.add(key.toString()+" : "+value.toString()); 193 } 194 for (int i = 0; i < al.size(); i++) { 195 if(child.equals(al.get(i))) return i; 196 } 197 198 } 199 return -1; 200 } 201 202 public void valueForPathChanged(TreePath path, Object newValue){} 203 public void removeTreeModelListener(TreeModelListener l){} 204 public void addTreeModelListener(TreeModelListener l){} 205 } 206}