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.event.MouseEvent; 026import java.io.Serializable; 027import java.util.List; 028 029import org.biojava.utils.AbstractChangeable; 030import org.biojava.utils.ChangeEvent; 031import org.biojava.utils.ChangeForwarder; 032import org.biojava.utils.ChangeSupport; 033import org.biojava.utils.ChangeType; 034import org.biojava.utils.ChangeVetoException; 035import org.biojava.utils.Changeable; 036 037/** 038 * An implementation of SequenceRenderer that delegates rendering to another 039 * renderer. 040 * 041 * <p> 042 * This takes care of all event notification and method invocation for you. 043 * Subclass this and over-ride methods, and then possibly call the method on 044 * super to forward the call on to the wrapped renderer. 045 * </p> 046 * 047 * @author Matthew Pocock 048 */ 049public class SequenceRendererWrapper 050extends AbstractChangeable 051implements SequenceRenderer, Serializable { 052 public static ChangeType RENDERER = new ChangeType( 053 "The renderer used to render the filtered features has changed", 054 "org.biojava.bio.gui.sequence.FilteringRenderer", 055 "RENDERER", 056 SequenceRenderContext.LAYOUT 057 ); 058 059 private SequenceRenderer renderer; 060 private transient ChangeForwarder rendForwarder; 061 062 /** 063 * Create a new renderer with no wrapped renderer. 064 * 065 * It is important that you call setRenderer() on this instance before 066 * trying to use it to display anything. 067 */ 068 public SequenceRendererWrapper() {} 069 070 /** 071 * Create a new wrapper with a wrapped renderer 072 * 073 * @param renderer the SequenceRenderer to wrap up 074 */ 075 public SequenceRendererWrapper(SequenceRenderer renderer) { 076 this.renderer = renderer; 077 } 078 079 protected ChangeSupport getChangeSupport(ChangeType ct) { 080 ChangeSupport cs = super.getChangeSupport(ct); 081 082 if(rendForwarder == null) { 083 rendForwarder = new SequenceRenderer.RendererForwarder(this, cs); 084 if((renderer != null) && (renderer instanceof Changeable)) { 085 Changeable c = (Changeable) this.renderer; 086 c.addChangeListener( 087 rendForwarder, 088 SequenceRenderContext.REPAINT 089 ); 090 } 091 } 092 093 return cs; 094 } 095 096 public void setRenderer(SequenceRenderer renderer) 097 throws ChangeVetoException { 098 if(hasListeners()) { 099 ChangeEvent ce = new ChangeEvent( 100 this, RENDERER, 101 renderer, this.renderer 102 ); 103 ChangeSupport cs = getChangeSupport(RENDERER); 104 synchronized(cs) { 105 cs.firePreChangeEvent(ce); 106 if((this.renderer != null) && (this.renderer instanceof Changeable)) { 107 Changeable c = (Changeable) this.renderer; 108 c.removeChangeListener(rendForwarder); 109 } 110 this.renderer = renderer; 111 if(renderer instanceof Changeable) { 112 Changeable c = (Changeable) renderer; 113 c.addChangeListener(rendForwarder); 114 } 115 cs.firePostChangeEvent(ce); 116 } 117 } else { 118 this.renderer = renderer; 119 } 120 } 121 122 public SequenceRenderer getRenderer() { 123 return this.renderer; 124 } 125 126 public double getDepth(SequenceRenderContext src) { 127 SequenceRenderer sr = getRenderer(); 128 if(sr == null) { 129 return 0.0; 130 } else { 131 return sr.getDepth(src); 132 } 133 } 134 135 public double getMinimumLeader(SequenceRenderContext src) { 136 SequenceRenderer sr = getRenderer(); 137 if(sr == null) { 138 return 0.0; 139 } else { 140 return sr.getMinimumLeader(src); 141 } 142 } 143 144 public double getMinimumTrailer(SequenceRenderContext src) { 145 SequenceRenderer sr = getRenderer(); 146 if(sr == null) { 147 return 0.0; 148 } else { 149 return sr.getMinimumTrailer(src); 150 } 151 } 152 153 public void paint( 154 Graphics2D g, 155 SequenceRenderContext src 156 ) { 157 SequenceRenderer sr = getRenderer(); 158 if(sr != null) { 159 sr.paint(g, src); 160 } 161 } 162 163 public SequenceViewerEvent processMouseEvent( 164 SequenceRenderContext src, 165 MouseEvent me, 166 List path 167 ) { 168 path.add(this); 169 return getRenderer().processMouseEvent(src, me, path); 170 } 171} 172