package com.indago.iddea.view.viewer; import javax.swing.JComponent; import com.indago.iddea.view.display.JHotDrawInteractiveDisplay2D; import net.imglib2.RandomAccessible; import net.imglib2.RealRandomAccessible; import net.imglib2.converter.Converter; import net.imglib2.interpolation.InterpolatorFactory; import net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory; import net.imglib2.interpolation.randomaccess.NearestNeighborInterpolatorFactory; import net.imglib2.realtransform.AffineTransform2D; import net.imglib2.type.numeric.ARGBType; import net.imglib2.type.numeric.NumericType; import net.imglib2.ui.*; import net.imglib2.view.Views; import net.imglib2.concatenate.Concatenable; import net.imglib2.realtransform.AffineGet; import net.imglib2.realtransform.AffineSet; import net.imglib2.ui.overlay.BufferedImageOverlayRenderer; import java.awt.*; /** * TODO * * Simple interactive viewer window. It creates a JFrame with the given * {@link InteractiveDisplayCanvas canvas}, and sets up transformation handling * and painting of a given {@link RenderSource source}. * <p> * It implements {@link PainterThread.Paintable} to handle {@link #paint() * repainting} through a {@link PainterThread}. It implements * {@link TransformListener} to be notified about viewer transformation changes * made by the user. * * @author Tobias Pietzsch <tobias.pietzsch@gmail.com> * * @param <T> * pixel type * @param <A> * transform type * @param <C> * canvas component type */ public abstract class InteractiveRealViewer< T, A extends AffineSet & AffineGet & Concatenable< AffineGet >, C extends JComponent & InteractiveDisplayCanvas< A > > implements TransformListener< A >, PainterThread.Paintable { final protected AffineTransformType< A > transformType; /** * Transformation set by the interactive viewer. */ protected A viewerTransform; /** * Canvas used for displaying the rendered. */ final protected C display; /** * Thread that triggers repainting of the display. */ final protected PainterThread painterThread; /** * Underlying source for painting/accessing the data */ protected RealRandomAccessible< T > source; /** * Underlying intervalSource for accessing the data */ protected RandomAccessible< T > intervalSource; protected BufferedImageOverlayRenderer target; protected Renderer< A > imageRenderer; /** * TODO * * Create an interactive viewer window displaying a given * {@link RenderSource <code>source</code>} in the given * <code>interactiveDisplayCanvas</code>. * <p> * A {@link Renderer} is created that paints to a * {@link BufferedImageOverlayRenderer} render target which is displayed on * the canvas as an {@link OverlayRenderer}. A {@link PainterThread} is * created which queues repainting requests from the renderer and * interactive canvas, and triggers {@link #paint() repainting} of the * viewer. * * @param transformType * @param interactiveDisplayCanvas * the canvas {@link JComponent} which will show the rendered * images. * @param rendererFactory * is used to create a {@link Renderer} for the source. */ public InteractiveRealViewer( final AffineTransformType< A > transformType, final C interactiveDisplayCanvas, final RendererFactory< A > rendererFactory ) { this.transformType = transformType; painterThread = new PainterThread( this ); viewerTransform = transformType.createTransform(); display = interactiveDisplayCanvas; display.addTransformListener( this ); target = new BufferedImageOverlayRenderer(); imageRenderer = rendererFactory.create( target, painterThread ); display.addOverlayRenderer( target ); // display.addOverlayRenderer(new SourceInfoOverlay()); // final GraphicsConfiguration gc = GuiUtil.getSuitableGraphicsConfiguration( GuiUtil.ARGB_COLOR_MODEL ); // final GraphicsConfiguration gc = GuiUtil.getSuitableGraphicsConfiguration( GuiUtil.RGB_COLOR_MODEL ); target.setCanvasSize( display.getWidth(), display.getHeight() ); painterThread.start(); } protected void updateRenderConverter( Converter< ? super T, ARGBType > converter ) { ( ( InjectableMultiResolutionRenderer ) imageRenderer ).injectConverter( converter ); } synchronized protected void updateRenderSource( RealRandomAccessible< T > source ) { this.source = source; ( ( InjectableMultiResolutionRenderer ) imageRenderer ).injectSource( source ); imageRenderer.paint( viewerTransform ); display.repaint(); } synchronized protected void updateSourceTransform( A transform ) { ( ( InjectableMultiResolutionRenderer ) imageRenderer ).injectSourceTransform( transform ); } public void updateSource( RealRandomAccessible< T > source ) { this.updateRenderSource( source ); } synchronized public void updateTransform( A transfrm ) { this.updateSourceTransform(transfrm); } public void updateIntervalSource( RandomAccessible< T > interval ) { this.intervalSource = interval; RealRandomAccessible source = Views.interpolate( interval, new NearestNeighborInterpolatorFactory() ); this.updateRenderSource( source ); } public void updateConverter( Converter< ? super T, ARGBType > converter ) { this.updateRenderConverter( converter ); } /** * Render the source using the current viewer transformation and */ @Override public void paint() { imageRenderer.paint( viewerTransform ); display.repaint(); } @Override public void transformChanged( final A transform ) { transformType.set( viewerTransform, transform ); requestRepaint(); } /** * Get the canvas component used for painting * * @return the canvas component used for painting. */ public C getDisplayCanvas() { return display; } /** * Request a repaint of the display. * Calls {@link Renderer#requestRepaint()}. */ public void requestRepaint() { imageRenderer.requestRepaint(); } /** * It returns JHotDrawInteractiveDisplay2D instance. * * @return JHotDrawInteractiveDisplay2D */ public JHotDrawInteractiveDisplay2D getJHotDrawDisplay() { return ( JHotDrawInteractiveDisplay2D ) display; } /** * Get the underlying RealRandomAccessible source. * * @return RealRandomAccessible<T> */ public RealRandomAccessible< T > getSource() { return source; } /** * Get the underlying RandomAccessible source. * * @return RandomAccessible<T> */ public RandomAccessible< T > getIntervalSource() { if ( intervalSource == null ) throw new NullPointerException( "IntervalSource does not exist." ); return intervalSource; } /** * Check the underlying RandomAccessible source available. * * @return boolean */ public boolean isIntervalSourceAvailable() { if ( intervalSource == null ) return false; else return true; } /** * @return the viewerTransform */ public A getViewerTransform() { return viewerTransform; } }