001package org.biojava.bio.gui.sequence; 002 003import java.awt.Graphics2D; 004import java.util.Iterator; 005 006import org.biojava.bio.seq.FeatureHolder; 007import org.biojava.bio.symbol.GappedSymbolList; 008import org.biojava.bio.symbol.Location; 009import org.biojava.bio.symbol.RangeLocation; 010import org.biojava.bio.symbol.SymbolList; 011 012/** 013 * A renderer that will display a gapped sequence as a discontinuous series of 014 * regions. 015 * 016 * <p> 017 * Each ungapped block in the gapped symbol list will be displayed as a 018 * contiguous region by this renderer. Where there are gaps, this renderer 019 * will display nothing. Then, when the gaps are over, it will continue to 020 * render the ungapped sequence. This has the effect of snapping the image 021 * of the ungapped sequence where there are gaps, so as to allow it to be 022 * viewed in the gapped co-ordinate system. 023 * </p> 024 * 025 * @author Matthew Pocock 026 */ 027public class GappedRenderer 028extends SequenceRendererWrapper { 029 public GappedRenderer() { 030 super(); 031 } 032 033 public GappedRenderer(SequenceRenderer renderer) { 034 super(renderer); 035 } 036 037 public double getDepth(SequenceRenderContext src) { 038 if(src.getSymbols() instanceof GappedSymbolList) { 039 GappedSymbolList gsym = (GappedSymbolList) src.getSymbols(); 040 Location ungapped = gsym.getUngappedLocation(); 041 double depth = 0.0; 042 043 Iterator bi = ungapped.blockIterator(); 044 while(bi.hasNext()) { 045 RangeLocation loc = (RangeLocation) bi.next(); 046 depth = Math.max(depth, super.getDepth(makeContext(src, loc))); 047 } 048 049 return depth; 050 } else { 051 return super.getDepth(src); 052 } 053 } 054 055 public double getMinimumLeader(SequenceRenderContext src) { 056 if(src.getSymbols() instanceof GappedSymbolList) { 057 GappedSymbolList gsym = (GappedSymbolList) src.getSymbols(); 058 Location ungapped = gsym.getUngappedLocation(); 059 Iterator bi = ungapped.blockIterator(); 060 if(bi.hasNext()) { 061 return super.getMinimumLeader( 062 makeContext(src, (RangeLocation) bi.next())); 063 } else { 064 return 0.0; 065 } 066 } else { 067 return super.getMinimumLeader(src); 068 } 069 } 070 071 public double getMinimumTrailer(SequenceRenderContext src) { 072 if(src.getSymbols() instanceof GappedSymbolList) { 073 GappedSymbolList gsym = (GappedSymbolList) src.getSymbols(); 074 Location ungapped = gsym.getUngappedLocation(); 075 Iterator bi = ungapped.blockIterator(); 076 RangeLocation loc = null; 077 while(bi.hasNext()) { 078 loc = (RangeLocation) bi.next(); 079 } 080 if(loc == null) { 081 return 0.0; 082 } else { 083 return super.getMinimumTrailer(makeContext(src, loc)); 084 } 085 } else { 086 return super.getMinimumTrailer(src); 087 } 088 } 089 090 public void paint( 091 Graphics2D g, 092 SequenceRenderContext src 093 ) { 094 if(src.getSymbols() instanceof GappedSymbolList) { 095 GappedSymbolList gsym = (GappedSymbolList) src.getSymbols(); 096 Location ungapped = gsym.getUngappedLocation(); 097 Iterator bi = ungapped.blockIterator(); 098 while(bi.hasNext()) { 099 RangeLocation loc = (RangeLocation) bi.next(); 100 super.paint(g, makeContext(src, loc)); 101 } 102 } else { 103 super.paint(g, src); 104 } 105 } 106 107 protected SequenceRenderContext makeContext(SequenceRenderContext src, 108 RangeLocation loc) { 109 GappedSymbolList gsl = (GappedSymbolList) src.getSymbols(); 110 RangeLocation sourceLoc = new RangeLocation( 111 gsl.viewToSource(loc.getMin()), 112 gsl.viewToSource(loc.getMax()) 113 ); 114 int trans = loc.getMin() - sourceLoc.getMin(); 115 SymbolList ugsl = gsl.getSourceSymbolList(); 116 117 return new SubSequenceRenderContext( 118 src, 119 ugsl, 120 (ugsl instanceof FeatureHolder) ? (FeatureHolder) ugsl : null, 121 sourceLoc, 122 trans); 123 } 124}