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.sequence; 023 024import java.awt.Graphics2D; 025import java.awt.Shape; 026import java.awt.event.MouseEvent; 027import java.awt.geom.AffineTransform; 028import java.util.ArrayList; 029import java.util.Iterator; 030import java.util.List; 031 032import org.biojava.bio.seq.Feature; 033import org.biojava.bio.seq.FeatureHolder; 034import org.biojava.utils.AbstractChangeable; 035import org.biojava.utils.ChangeType; 036 037/** 038 * Allows you to stack multiple feature renderers up (for example a label renderer and 039 * a beaded renderer) and have them treated as a single renderer for layout. 040 * 041 * @author Matthew Pocock 042 */ 043public class StackedFeatureRenderer 044extends AbstractChangeable 045implements FeatureRenderer { 046 public static final ChangeType RENDERERS = new ChangeType( 047 "The renderers have changed", 048 StackedFeatureRenderer.class, 049 "RENDERERS", 050 SequenceRenderContext.LAYOUT 051 ); 052 053 private List renderers = new ArrayList(); 054 055 public StackedFeatureRenderer() {} 056 057 // fixme: events? 058 public void addRenderer(FeatureRenderer renderer) { 059 renderers.add(renderer); 060 } 061 062 public void removeRenderer(FeatureRenderer renderer) { 063 renderers.remove(renderer); 064 } 065 066 public double getDepth(SequenceRenderContext src) { 067 double depth = 0.0; 068 069 for(Iterator i = renderers.iterator(); i.hasNext(); ) { 070 FeatureRenderer fr = (FeatureRenderer) i.next(); 071 depth += fr.getDepth(src); 072 } 073 074 return depth; 075 } 076 077 public void renderFeature( 078 Graphics2D g, 079 Feature f, 080 SequenceRenderContext src 081 ) { 082 AffineTransform at = g.getTransform(); 083 Shape oldClip = g.getClip(); 084 085 for(Iterator i = renderers.iterator(); i.hasNext(); ) { 086 FeatureRenderer fr = (FeatureRenderer) i.next(); 087 fr.renderFeature(g, f, src); 088 089 double depth = fr.getDepth(src); 090 g.translate(0.0, depth); 091 } 092 093 g.setClip(oldClip); 094 g.setTransform(at); 095 } 096 097 public FeatureHolder processMouseEvent( 098 FeatureHolder hits, 099 SequenceRenderContext src, 100 MouseEvent me 101 ) { 102 return hits; 103 } 104}