/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2016 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.imviewer.view; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Point; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.swing.Action; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import org.openmicroscopy.shoola.agents.events.iviewer.ChannelSelection; import org.openmicroscopy.shoola.agents.events.iviewer.ImageRendered; import org.openmicroscopy.shoola.agents.events.iviewer.MeasurePlane; import org.openmicroscopy.shoola.agents.events.iviewer.MeasurementTool; import org.openmicroscopy.shoola.agents.events.iviewer.ResetRndSettings; import org.openmicroscopy.shoola.agents.events.iviewer.RndSettingsCopied; import org.openmicroscopy.shoola.agents.events.iviewer.SaveRelatedData; import org.openmicroscopy.shoola.agents.events.iviewer.ViewImage; import org.openmicroscopy.shoola.agents.events.iviewer.ViewImageObject; import org.openmicroscopy.shoola.agents.events.iviewer.ViewerCreated; import org.openmicroscopy.shoola.agents.events.iviewer.ViewerState; import org.openmicroscopy.shoola.agents.events.treeviewer.NodeToRefreshEvent; import org.openmicroscopy.shoola.agents.imviewer.ImViewerAgent; import org.openmicroscopy.shoola.agents.imviewer.actions.ColorModelAction; import org.openmicroscopy.shoola.agents.imviewer.actions.PlayMovieAction; import org.openmicroscopy.shoola.agents.imviewer.actions.UnitBarSizeAction; import org.openmicroscopy.shoola.agents.imviewer.actions.ZoomAction; import org.openmicroscopy.shoola.agents.imviewer.util.PreferencesDialog; import org.openmicroscopy.shoola.agents.imviewer.util.proj.ProjSavingDialog; import org.openmicroscopy.shoola.agents.imviewer.util.proj.ProjectionRef; import org.openmicroscopy.shoola.agents.imviewer.util.UnitBarSizeDialog; import org.openmicroscopy.shoola.agents.imviewer.util.player.MoviePlayerDialog; import org.openmicroscopy.shoola.agents.metadata.rnd.Renderer; import org.openmicroscopy.shoola.agents.util.EditorUtil; import org.openmicroscopy.shoola.env.config.Registry; import org.openmicroscopy.shoola.env.data.model.ProjectionParam; import omero.gateway.SecurityContext; import org.openmicroscopy.shoola.env.event.EventBus; import omero.log.LogMessage; import omero.log.Logger; import omero.model.Length; import omero.model.LengthI; import omero.model.enums.UnitsLength; import org.openmicroscopy.shoola.env.rnd.RenderingControl; import org.openmicroscopy.shoola.env.rnd.RndProxyDef; import org.openmicroscopy.shoola.env.rnd.data.Tile; import org.openmicroscopy.shoola.env.ui.SaveEventBox; import org.openmicroscopy.shoola.env.ui.UserNotifier; import org.openmicroscopy.shoola.util.image.geom.Factory; import org.openmicroscopy.shoola.util.ui.MessageBox; import org.openmicroscopy.shoola.util.ui.UIUtilities; import org.openmicroscopy.shoola.util.ui.component.AbstractComponent; import org.openmicroscopy.shoola.util.ui.drawingtools.canvas.DrawingCanvasView; import omero.gateway.model.ChannelData; import omero.gateway.model.DataObject; import omero.gateway.model.ExperimenterData; import omero.gateway.model.FileAnnotationData; import omero.gateway.model.ImageAcquisitionData; import omero.gateway.model.ImageData; /** * Implements the {@link ImViewer} interface to provide the functionality * required of the hierarchy viewer component. * This class is the component hub and embeds the component's MVC triad. * It manages the component's state machine and fires state change * notifications as appropriate, but delegates actual functionality to the * MVC sub-components. * * @see org.openmicroscopy.shoola.agents.imviewer.view.ImViewerModel * @see org.openmicroscopy.shoola.agents.imviewer.view.ImViewerUI * @see org.openmicroscopy.shoola.agents.imviewer.view.ImViewerControl * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Andrea Falconi      * <a href="mailto:a.falconi@dundee.ac.uk">a.falconi@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * @since OME2.2 */ class ImViewerComponent extends AbstractComponent implements ImViewer { /** The message if rendering setting to save. */ static final String RND = "The last rendering settings"; /** The message if rendering setting to annotation. */ static final String ANNOTATION = "The annotations"; /** The Model sub-component. */ private ImViewerModel model; /** The Control sub-component. */ private ImViewerControl controller; /** The View sub-component. */ private ImViewerUI view; /** Collection of events to display. */ private Map<String, SaveRelatedData> events; /** Flag indicating that a new z-section or timepoint is selected. */ private boolean newPlane; /** * Flag indicating that the rendering settings have been saved * before copying. */ private boolean saveBeforeCopy; /** The color model used. */ private String colorModel; /** The projection dialog. */ private ProjSavingDialog projDialog; /** The list of component added to the main viewer. */ private List<JComponent> layers; /** The color changes preview.*/ private Map<Integer, Color> colorChanges; /** Flag indicating that it was not possible to save the settings.*/ private boolean failureToSave; /** The ImageAcquisitionData */ private ImageAcquisitionData acquisitionData; /** * Creates and returns an image including the ROI * * @param image The image to handle. * @return See above. */ private BufferedImage createImageWithROI(BufferedImage image) { Iterator<JComponent> i = layers.iterator(); JComponent c; BufferedImage img = Factory.copyBufferedImage(image); DrawingCanvasView canvas; while (i.hasNext()) { c = i.next(); if (c instanceof DrawingCanvasView) { canvas = (DrawingCanvasView) c; canvas.print(img.getGraphics()); } } return img; } /** * Brings up the dialog used to set the parameters required for the * projection. */ private void showProjectionDialog() { if (projDialog == null) { projDialog = new ProjSavingDialog(view, model.getParent(), model.getGrandParent()); projDialog.initialize(view.getProjectionType(), model.getRealT(), model.getPixelsType(), model.getImageName(), model.getContainers(), model.getMaxZ()+1, view.getProjectionStartZ()+1, view.getProjectionEndZ()+1); projDialog.addPropertyChangeListener(controller); projDialog.pack(); Dimension minimumSize = new Dimension(projDialog.getWidth(), projDialog.getHeight()); projDialog.setMinimumSize(minimumSize); } else { projDialog.setProjectionInterval(view.getProjectionStartZ()+1, view.getProjectionEndZ()+1); } UIUtilities.centerAndShow(projDialog); } /** * Posts a {@link MeasurePlane} event to indicate that a new plane is * rendered or a new magnification factor has been selected. */ private void postMeasurePlane() { EventBus bus = ImViewerAgent.getRegistry().getEventBus(); double f = model.getZoomFactor()*model.getOriginalRatio(); if (model.isBigImage()) { f = view.getBigImageMagnificationFactor(); } MeasurePlane event = new MeasurePlane(model.getPixelsID(), model.getDefaultZ(), model.getDefaultT(), f); if (model.isBigImage()) { event.setSize(model.getTiledImageSizeX(), model.getTiledImageSizeY()); } bus.post(event); } /** * Posts an {@link ViewerState} event to indicate that the frame state * of this component has changed. * * @param index One of the constants defined by {@link ViewerState}. */ private void postViewerState(int index) { EventBus bus = ImViewerAgent.getRegistry().getEventBus(); ViewerState event = new ViewerState(model.getPixelsID(), index); bus.post(event); } /** * Posts an {@link ChannelSelection} event to indicate that the * a new channel is selected or unselected; or that a channel is mapped * to a new color. * * @param index One of the constants defined by {@link ChannelSelection}. */ private void postActiveChannelSelection(int index) { EventBus bus = ImViewerAgent.getRegistry().getEventBus(); ChannelSelection event = new ChannelSelection(model.getPixelsID(), model.getActiveChannelsColorMap(), index); bus.post(event); view.setPlaneInfoStatus(); } /** Saves the plane quietly i.e. no question asked to the user. */ private void savePlane() { if (model.isOriginalPlane()) return; try { saveRndSettings(true); } catch (Exception e) { LogMessage logMsg = new LogMessage(); logMsg.println("Cannot save rendering settings. "); logMsg.print(e); ImViewerAgent.getRegistry().getLogger().error(this, logMsg); } } /** * Displays message before closing the viewer. * Returns <code>true</code> if we need to close the viewer, * <code>false</code> otherwise. * * @param notifyUser Pass <code>true</code> to notify the user, * <code>false</code> otherwise. * @return See above. */ private boolean saveOnClose(boolean notifyUser) { if (!canAnnotate()) return true; if (failureToSave) return true; if (!notifyUser) { saveRndSettings(true); return true; } boolean showBox = false; JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); JCheckBox rndBox = null; if (!model.isOriginalSettings(false)) { rndBox = new JCheckBox(RND); rndBox.setSelected(true); p.add(rndBox); showBox = true; } JCheckBox annotationBox = null; if (model.hasMetadataToSave()) { annotationBox = new JCheckBox(ANNOTATION); annotationBox.setSelected(true); p.add(annotationBox); showBox = true; } List<SaveEventBox> boxes = null; SaveEventBox box; Iterator j; if (events != null) { boxes = new ArrayList<SaveEventBox>(events.size()); j = events.keySet().iterator(); SaveRelatedData value; while (j.hasNext()) { value = events.get(j.next()); if (value.isToSave()) { showBox = true; box = new SaveEventBox(value); boxes.add(box); p.add(box); } } } if (!showBox) { if (saveBeforeCopy) { try { model.saveRndSettings(false); } catch (Exception e) { LogMessage logMsg = new LogMessage(); logMsg.println("Cannot save rendering settings. "); logMsg.print(e); ImViewerAgent.getRegistry().getLogger().error(this, logMsg); } } return true; } MessageBox msg = new MessageBox(view, "Save Data", "Before closing the viewer, do you want to save: "); msg.addCancelButton(); msg.addBodyComponent(p); int option = msg.centerMsgBox(); if (option == MessageBox.YES_OPTION) { if (saveBeforeCopy) { try { model.saveRndSettings(false); } catch (Exception e) { LogMessage logMsg = new LogMessage(); logMsg.println("Cannot save rendering settings. "); logMsg.print(e); ImViewerAgent.getRegistry().getLogger().error(this, logMsg); } } if (rndBox != null && rndBox.isSelected()) { try { saveRndSettings(true); } catch (Exception e) { LogMessage logMsg = new LogMessage(); logMsg.println("Cannot save rendering settings. "); logMsg.print(e); ImViewerAgent.getRegistry().getLogger().error(this, logMsg); } } if (rndBox == null) { savePlane(); } if (annotationBox != null && annotationBox.isSelected()) model.saveMetadata(); if (boxes != null) { j = boxes.iterator(); EventBus bus = ImViewerAgent.getRegistry().getEventBus(); SaveRelatedData event; while (j.hasNext()) { box = (SaveEventBox) j.next(); if (box.isSelected()) { event = (SaveRelatedData) box.getEvent(); if (event.isToSave()) { bus.post(event.getSaveEvent()); } } } } return true; } else if (option == MessageBox.CANCEL) { return false; } else if (option == MessageBox.NO_OPTION) { if (saveBeforeCopy) { try { model.saveRndSettings(false); } catch (Exception e) { LogMessage logMsg = new LogMessage(); logMsg.println("Cannot save rendering settings. "); logMsg.print(e); ImViewerAgent.getRegistry().getLogger().error(this, logMsg); } } //post an event ResetRndSettings evt = new ResetRndSettings(model.getImageID(), model.getOriginalDef()); ImViewerAgent.getRegistry().getEventBus().post(evt); model.resetMappingSettings(model.getOriginalDef()); } return true; } /** * Notifies that the projected image has been created and asks if the * user wants to launch a viewer with the projected image. * * @param message The message to display. * @param image The projected image. */ private void notifyProjection(String message, ImageData image) { model.setState(READY); String text = message; text += "\n"; text += "Do you want to launch a viewer for the projected image?"; MessageBox msg = new MessageBox(view, "Projection", text); int option = msg.centerMsgBox(); if (option == MessageBox.YES_OPTION) { EventBus bus = ImViewerAgent.getRegistry().getEventBus(); bus.post(new ViewImage(model.getSecurityContext(), new ViewImageObject(image), null)); } } /** Fires an asynchronous call to preview the projection. */ private void previewProjection() { switch (model.getState()) { case DISCARDED: case PROJECTING: case PROJECTION_PREVIEW: return; } model.fireRenderProjected(view.getProjectionStartZ(), view.getProjectionEndZ(), view.getProjectionStepping(), view.getProjectionType()); fireStateChange(); } /** * Returns <code>true</code> if it is the same projection parameters, * <code>false</code> otherwise. * * @return See above. */ private boolean isSameProjectionParam() { ProjectionParam ref = model.getLastProjRef(); if (ref == null) return true; if (ref.getStartZ() != view.getProjectionStartZ()) return false; if (ref.getEndZ() != view.getProjectionEndZ()) return false; if (ref.getAlgorithm() != view.getProjectionType()) return false; if (ref.getStepping() != view.getProjectionStepping()) return false; return true; } /** * Posts an event to bring up the measurement tool. * * @param measurements The measurements to load. */ private void postMeasurementEvent(List<FileAnnotationData> measurements) { EventBus bus = ImViewerAgent.getRegistry().getEventBus(); double f = model.getZoomFactor()*model.getOriginalRatio(); if (model.isBigImage()) f = view.getBigImageMagnificationFactor(); MeasurementTool request = new MeasurementTool( model.getSecurityContext(), model.getImageID(), model.getPixelsData(), model.getImageName(), model.getDefaultZ(), model.getDefaultT(), model.getActiveChannelsColorMap(),f, view.getBounds(), model.getChannelData()); if (model.isBigImage()) { request.setSize(model.getTiledImageSizeX(), model.getTiledImageSizeY()); } request.setThumbnail(model.getImageIcon()); request.setRenderedImage(model.getBrowser().getRenderedImage()); request.setMeasurements(measurements); request.setHCSData(model.isHCSImage()); request.setBigImage(model.isBigImage()); bus.post(request); int tabbedIndex = model.getTabbedIndex(); if (tabbedIndex != ImViewer.VIEW_INDEX) { view.selectTabbedPane(ImViewer.VIEW_INDEX); renderXYPlane(); } } /** * Posts an event to indicate to embed the image viewer. * * @param toAdd Pass <code>true</code> to embed it, <code>false</code> * to remove it. * @param detach Pass <code>true</code> to detach it, <code>false</code> * otherwise. */ private void postViewerCreated(boolean toAdd, boolean detach) { JComponent c = null; if (toAdd) { showView(RENDERER_INDEX); c = view.asComponent(); } ViewerCreated evt = new ViewerCreated(c, model.getMetadataViewer().getEditorUI(), toAdd); evt.setDetach(detach); EventBus bus = ImViewerAgent.getRegistry().getEventBus(); bus.post(evt); } /** * Creates a new instance. * The {@link #initialize() initialize} method should be called straight * after to complete the MVC set up. * * @param model The Model sub-component. Mustn't be <code>null</code>. */ ImViewerComponent(ImViewerModel model) { if (model == null) throw new NullPointerException("No model."); this.model = model; controller = new ImViewerControl(); view = new ImViewerUI(model.getImageTitle()); } /** Links up the MVC triad. */ void initialize() { model.initialize(this); controller.initialize(this, view); view.initialize(controller, model); if (model.getMetadataViewer() != null) model.getMetadataViewer().addPropertyChangeListener(controller); } /** * Returns the Model sub-component. * * @return See above. */ ImViewerModel getModel() { return model; } /** Sets the image to copy the rendering settings from. */ void copyRndSettings() { view.enablePasteButton(true); firePropertyChange(RND_SETTINGS_PROPERTY, Boolean.FALSE, Boolean.TRUE); } /** * Stored the event to display. * * @param evt The event to store. */ void storeEvent(SaveRelatedData evt) { if (events == null) events = new HashMap<String, SaveRelatedData>(); events.put(evt.toString(), evt); } /** * Returns a map with events to save. * * @return See above. */ Map<String, SaveRelatedData> getSaveEvents() { return events; } /** * Returns the title associated to the viewer. * * @return See above. */ String getTitle() { return view.getTitle(); } /** * Invokes when the rendering settings has been saved using another way. * * @param settings The save rendering settings. */ void onRndSettingsSaved(RndProxyDef settings) { if (settings == null) return; model.resetOriginalSettings(settings); refresh(); fireStateChange(); } /** * Returns <code>true</code> if some settings to save, <code>false</code> * otherwise. * * @return See above. */ boolean hasSettingsToSave() { if (failureToSave) return false; return !isOriginalSettings(); } /** * Sets the display mode. * * @param displayMode The value to set. */ void setDisplayMode(int displayMode) { } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#activate(RndProxyDef, long, int, long) */ public void activate(RndProxyDef settings, long userID, int displayMode, long selectedRndDefID) { model.setDisplayMode(displayMode); model.setSelectedRndDef(selectedRndDefID); switch (model.getState()) { case NEW: model.setAlternativeSettings(settings, userID); if (!model.isImageLoaded()) { model.fireImageLoading(); } else { model.setState(ImViewer.LOADING_IMAGE_DATA); setImageData(model.getImage()); } fireStateChange(); break; case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED state."); default: if (view != null) { if (model.isSeparateWindow()) { UIUtilities.centerOnScreen(view); view.toFront(); view.requestFocusInWindow(); } else { postViewerCreated(true, false); } } } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#discard() */ public void discard() { model.discard(); fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#changeUserGroup(long, long) */ public void changeUserGroup(long groupID, long oldGroupID) { } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getState() */ public int getState() { return model.getState(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setStatus(String, int) */ public void setStatus(String description, int perc) { if (model.getState() == DISCARDED) return; view.setLeftStatus(description); if (perc == 100) view.setLeftStatus(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setZoomFactor(double, int) */ public void setZoomFactor(double factor, int zoomIndex) { if (factor != ZoomAction.ZOOM_FIT_FACTOR && (factor > ZoomAction.MAX_ZOOM_FACTOR || factor < ZoomAction.MIN_ZOOM_FACTOR)) throw new IllegalArgumentException("The zoom factor is a value " + "between "+ZoomAction.MIN_ZOOM_FACTOR+" and "+ ZoomAction.MAX_ZOOM_FACTOR); switch (model.getState()) { case NEW: case LOADING_IMAGE: case LOADING_TILES: case DISCARDED: return; } if (model.isBigImage()) { double ox = (double) model.getTiledImageSizeX(); double oy = (double) model.getTiledImageSizeY(); model.setSelectedResolutionLevel(zoomIndex); view.setZoomFactor(factor, zoomIndex); int w = model.getTiledImageSizeX(); int h = model.getTiledImageSizeY(); double nx = (double) w/ox; double ny = (double) h/oy; model.getBrowser().setComponentsSize(w, h); model.getBrowser().setViewLocation(nx, ny); postMeasurePlane(); return; } double oldFactor = model.getZoomFactor(); if (oldFactor == factor && factor != ZoomAction.ZOOM_FIT_FACTOR) return; try { model.setZoomFactor(factor, false); } catch (Exception e) { Logger logger = ImViewerAgent.getRegistry().getLogger(); logger.debug(this, "Cannot zoom image. Magnification: "+factor); model.setZoomFactor(factor, true); } view.setZoomFactor(factor, zoomIndex); if (view.isLensVisible()) { switch (model.getTabbedIndex()) { case ImViewer.VIEW_INDEX: case ImViewer.PROJECTION_INDEX: view.setImageZoomFactor((float) model.getZoomFactor()); view.scrollLens(); } } controller.setPreferences(); postMeasurePlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isZoomFitToWindow() */ public boolean isZoomFitToWindow() { return model.isZoomFitToWindow(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isRendererLoaded() */ public boolean isRendererLoaded() { return model.isRendererLoaded(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setColorModel(int) */ public void setColorModel(int key) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED, " + "NEW or LOADING_RENDERING_CONTROL state."); } switch (key) { case ColorModelAction.GREY_SCALE_MODEL: model.setColorModel(GREY_SCALE_MODEL, true); break; case ColorModelAction.RGB_MODEL: model.setColorModel(RGB_MODEL, true); break; default: throw new IllegalArgumentException("Color Model not supported"); } view.onColorModelChanged(); //Remove 21/09 //firePropertyChange(COLOR_MODEL_CHANGED_PROPERTY, // Integer.valueOf(1), Integer.valueOf(-1)); view.setColorModel(key); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setSelectedXYPlane(int, int, int) */ public void setSelectedXYPlane(int z, int t, int bin) { boolean enableSave = z != model.getDefaultZ() || t != model.getDefaultT(); if (z < 0) z = model.getDefaultZ(); if (t < 0) t = model.getRealSelectedT(); switch (model.getState()) { case NEW: case DISCARDED: return; } int defaultZ = model.getDefaultZ(); int defaultT = model.getRealSelectedT(); if (bin >= 0) { //lifetime int v = model.getSelectedBin(); firePropertyChange(ImViewer.BIN_SELECTED_PROPERTY, Integer.valueOf(v), Integer.valueOf(bin)); if (defaultT != t) { firePropertyChange(ImViewer.T_SELECTED_PROPERTY, Integer.valueOf(defaultT), Integer.valueOf(t)); } if (defaultZ != z) { firePropertyChange(ImViewer.Z_SELECTED_PROPERTY, Integer.valueOf(defaultZ), Integer.valueOf(z)); } } else { if (defaultZ == z && defaultT == t) return; if (defaultZ != z) { firePropertyChange(ImViewer.Z_SELECTED_PROPERTY, Integer.valueOf(defaultZ), Integer.valueOf(z)); } if (defaultT != t) { firePropertyChange(ImViewer.T_SELECTED_PROPERTY, Integer.valueOf(defaultT), Integer.valueOf(t)); } newPlane = true; } model.setSelectedXYPlane(z, t, bin); if (enableSave) controller.getAction(ImViewerControl.SAVE_RND_SETTINGS).setEnabled(true); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setSelectedXYPlane(int, int, int) */ public void setSelectedRegion(int z, int t, Rectangle region) { if (z < 0) z = model.getDefaultZ(); if (t < 0) t = model.getRealSelectedT(); if (region == null || !model.isBigImage()) { setSelectedXYPlane(z, t); return; } switch (model.getState()) { case NEW: case DISCARDED: return; } int defaultZ = model.getDefaultZ(); int defaultT = model.getRealSelectedT(); boolean reset = false; if (defaultZ != z) { reset = true; firePropertyChange(ImViewer.Z_SELECTED_PROPERTY, Integer.valueOf(defaultZ), Integer.valueOf(z)); } if (defaultT != t) { reset = true; firePropertyChange(ImViewer.T_SELECTED_PROPERTY, Integer.valueOf(defaultT), Integer.valueOf(t)); } Rectangle r = model.getBrowser().getVisibleRectangle(); double f = view.getBigImageMagnificationFactor(); Rectangle transformRegion = new Rectangle( (int) (region.x*f), (int) (region.y*f), (int) (region.width*f), (int) (region.height*f)); if (r.contains(transformRegion)) return; //Now determine the view size so the ROI is displayed. Rectangle r2 = new Rectangle( transformRegion.x, transformRegion.y, r.width, r.height); if (reset) { model.fireBirdEyeViewRetrieval(true); model.resetTiles(); model.getBrowser().setSelectedRegion(r2); } else { model.getBrowser().setSelectedRegion(r2); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setSelectedXYPlane(int, int) */ public void setSelectedXYPlane(int z, int t) { setSelectedXYPlane(z, t, -1); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setImage(Object) */ public void setImage(Object image) { if (model.getState() == LOADING_IMAGE_CANCELLED) return; if (model.getState() != LOADING_IMAGE) throw new IllegalStateException("This method can only be invoked " + "in the LOADING_IMAGE state."); if (image == null) { //no need to notify. model.setImage(null); return; } if (!(image instanceof BufferedImage)) { model.setImage(null); return; } view.removeComponentListener(controller); if (newPlane) postMeasurePlane(); newPlane = false; Object originalImage; originalImage = model.getOriginalImage(); model.setImage((BufferedImage) image); view.handleUnitBar(); view.setLeftStatus(); view.setPlaneInfoStatus(); if (originalImage == null && model.isZoomFitToWindow()) { controller.setZoomFactor(ZoomAction.ZOOM_FIT_TO_WINDOW); } if (model.isPlayingChannelMovie()) model.setState(ImViewer.CHANNEL_MOVIE); if (!model.isPlayingMovie()) { //Post an event EventBus bus = ImViewerAgent.getRegistry().getEventBus(); BufferedImage icon = model.getImageIcon(); bus.post(new ImageRendered(model.getPixelsID(), icon, model.getBrowser().getRenderedImage())); //if (icon != null) view.setIconImage(icon); } if (!model.isPlayingMovie() && !model.isPlayingChannelMovie()) { if (view.isLensVisible()) view.setLensPlaneImage(); view.createHistoryItem(null); } view.setCursor(Cursor.getDefaultCursor()); view.addComponentListener(controller); fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#playChannelMovie(boolean) */ public void playChannelMovie(boolean play) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED, NEW " + "or LOADING_RENDERING_CONTROL state."); } //if (model.getState() != READY || model.getState() != CHANNEL_MOVIE) //return; model.playMovie(play); view.playChannelMovie(!play); if (!play) { displayChannelMovie(); controller.setHistoryState(READY); } fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setChannelColor(int, Color, boolean) */ public void setChannelColor(int index, Color c, boolean preview) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED, " + "NEW or LOADING_RENDERING_CONTROL state."); } if (preview) { if (colorChanges == null) colorChanges = new HashMap<Integer, Color>(); if (c == null) { c = colorChanges.get(index); //reset the color. colorChanges.clear(); } else { if (!colorChanges.containsKey(index)) colorChanges.put(index, model.getChannelColor(index)); } } else { if (colorChanges != null) colorChanges.remove(index); } if (c == null) return; try { model.setChannelColor(index, c); view.setChannelColor(index, c); if (!model.isChannelActive(index)) { setChannelActive(index, true); view.setChannelActive(index, ImViewerUI.ALL_VIEW); } if (GREY_SCALE_MODEL.equals(model.getColorModel())) setColorModel(ColorModelAction.RGB_MODEL); } catch (Exception e) { Registry reg = ImViewerAgent.getRegistry(); LogMessage msg = new LogMessage(); msg.println("Cannot set the color of channel "+index); msg.print(e); reg.getLogger().error(this, msg); reg.getUserNotifier().notifyError("Set channel color", "Cannot set the color of channel "+index, e); } firePropertyChange(CHANNEL_COLOR_CHANGED_PROPERTY, -1, index); postActiveChannelSelection(ChannelSelection.COLOR_SELECTION); //if (model.isChannelActive(index)) renderXYPlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setChannelSelection(int, boolean) */ public void setChannelSelection(int index, boolean b) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or " + "NEW state."); } //depends on model model.setLastSettingsRef(model.getTabbedIndex()); int uiIndex = -1; if (model.getColorModel().equals(GREY_SCALE_MODEL)) { if (model.getTabbedIndex() == ImViewer.GRID_INDEX) { List<Integer> l = new ArrayList<Integer>(); List selectedChannels = view.getActiveChannelsInGrid(); for (int i = 0; i < model.getMaxC(); i++) { if (i == index) { if (b) l.add(i); } else { if (selectedChannels.contains(i)) l.add(i); } } view.setChannelsSelection(l); } else if (model.getTabbedIndex() == ImViewer.PROJECTION_INDEX) { if (model.isChannelActive(index)) return; boolean c; for (int i = 0; i < model.getMaxC(); i++) { c = i == index; model.setChannelActive(i, c); if (c) firePropertyChange(CHANNEL_ACTIVE_PROPERTY, Integer.valueOf(index-1), Integer.valueOf(index)); } uiIndex = ImViewerUI.PROJECTION_ONLY; } else { if (model.isChannelActive(index)) return; boolean c; for (int i = 0; i < model.getMaxC(); i++) { c = i == index; model.setChannelActive(i, c); if (c) firePropertyChange(CHANNEL_ACTIVE_PROPERTY, Integer.valueOf(index-1), Integer.valueOf(index)); } uiIndex = ImViewerUI.VIEW_ONLY; } } else { uiIndex = ImViewerUI.ALL_VIEW; model.setChannelActive(index, b); firePropertyChange(CHANNEL_ACTIVE_PROPERTY, Integer.valueOf(index-1), Integer.valueOf(index)); } view.setChannelsSelection(uiIndex); model.setSelectedChannel(index); renderXYPlane(); postActiveChannelSelection(ChannelSelection.CHANNEL_SELECTION); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#renderXYPlane() */ public void renderXYPlane() { switch (model.getState()) { case NEW: throw new IllegalStateException( "This method can't be invoked in the NEW state."); case LOADING_IMAGE: case DISCARDED: //case LOADING_BIRD_EYE_VIEW: case LOADING_RND: return; } if (model.isBigImage()) { model.resetTiles(); loadTiles(null); return; } int compression = view.getUICompressionLevel(); boolean stop = false; int index = model.getTabbedIndex(); RndProxyDef def; if (index == PROJECTION_INDEX) { def = model.getLastProjDef(); boolean b = false; if (def != null) b = model.isSameSettings(def, false); if (b && isSameProjectionParam()) stop = true; } else { def = model.getLastMainDef(); if (def != null) stop = model.isSameSettings(def, true); } //if (stop) return; if (index == PROJECTION_INDEX) { //if (stop) return; previewProjection(); fireStateChange(); } else if (index == GRID_INDEX) { if (GREY_SCALE_MODEL.equals(model.getColorModel())) { model.getBrowser().onColorModelChange(); } else { model.fireImageRetrieval(compression); newPlane = false; fireStateChange(); } } else { //if (stop) return; model.fireImageRetrieval(compression); newPlane = false; fireStateChange(); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setChannelActive(int, boolean) */ public void setChannelActive(int index, boolean b) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED, NEW or" + "LOADING_RENDERING_CONTROL state."); } model.setChannelActive(index, b); if (b) firePropertyChange(CHANNEL_ACTIVE_PROPERTY, Integer.valueOf(index-1), Integer.valueOf(index)); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#displayChannelMovie() */ public void displayChannelMovie() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW" + "state."); } view.setChannelsSelection(ImViewerUI.ALL_VIEW); renderXYPlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getMaxC() */ public int getMaxC() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or " + "NEW state."); } return model.getMaxC(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getRealT() */ public int getRealT() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED, NEW or" + "LOADING_RENDERING_CONTROL state."); } return model.getRealT(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getMaxZ() */ public int getMaxZ() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED, NEW or" + "LOADING_RENDERING_CONTROL state."); } return model.getMaxZ(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getImageName() */ public String getImageName() { if (model.getState() == DISCARDED) throw new IllegalStateException( "This method can't be invoked in the DISCARDED state."); return model.getImageName(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getColorModel() */ public String getColorModel() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW" +" state."); } return model.getColorModel(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getUI() */ public JFrame getUI() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or" + " NEW state."); } return view; } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#iconified(boolean) */ public void iconified(boolean b) { switch (model.getState()) { case NEW: case DISCARDED: //throw new IllegalStateException( //"This method can't be invoked in the DISCARDED, NEW state."); return; } Boolean newValue = Boolean.FALSE; Boolean oldValue = Boolean.TRUE; int index = ViewerState.DEICONIFIED; if (b) { newValue = Boolean.TRUE; oldValue = Boolean.FALSE; index = ViewerState.ICONIFIED; } postViewerState(index); firePropertyChange(ICONIFIED_PROPERTY, oldValue, newValue); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getDefaultZ() */ public int getDefaultZ() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW"+ " state."); } return model.getDefaultZ(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getDefaultT() */ public int getDefaultT() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW"+ " state."); } return model.getDefaultT(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getImageComponents(String) */ public List getImageComponents(String colorModel, boolean includeROI) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW"+ " state."); } if (model.getColorModel().equals(GREY_SCALE_MODEL)) return null; List l = model.getActiveChannels(); int n = l.size(); List<BufferedImage> images = new ArrayList<BufferedImage>(n); if (n == 0) return images; else if (n == 1) { images.add(getDisplayedImage(includeROI)); return images; } Iterator i = l.iterator(); int index; String oldColorModel = model.getColorModel(); Map<Integer, BufferedImage> map = new HashMap<Integer, BufferedImage>(n); model.setColorModel(colorModel, false); BufferedImage img = null, splitImage; while (i.hasNext()) { index = (Integer) i.next(); for (int j = 0; j < model.getMaxC(); j++) model.setChannelActive(j, j == index); splitImage = model.getSplitComponentImage(); if (splitImage != null) img = Factory.magnifyImage(splitImage, model.getZoomFactor(), 0, model.isInterpolation()); if (includeROI && layers != null) { img = createImageWithROI(img); } map.put(index, img); } model.setColorModel(oldColorModel, false); i = l.iterator(); while (i.hasNext()) { //reset values. index = ((Integer) i.next()).intValue(); model.setChannelActive(index, true); } List<ChannelData> channels = model.getChannelData(); Iterator<ChannelData> k = channels.iterator(); ChannelData channel; while (k.hasNext()) { channel = k.next(); if (map.containsKey(channel.getIndex())) images.add(map.get(channel.getIndex())); } return images; } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getGridImages() */ public List getGridImages() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW"+ " state."); } view.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); //if (model.getColorModel().equals(GREY_SCALE_MODEL)) return null; List active = model.getActiveChannels(); int maxC = model.getMaxC(); List<BufferedImage> images = new ArrayList<BufferedImage>(maxC); List<ChannelData> list = getSortedChannelData(); Iterator<ChannelData> i = list.iterator(); int k; Iterator w; if (model.getColorModel().equals(GREY_SCALE_MODEL)) { active = view.getActiveChannelsInGrid(); //Iterator i = active.iterator(); while (i.hasNext()) { k = i.next().getIndex(); if (active.contains(k)) { model.setChannelActive(k, true); for (int j = 0; j < maxC; j++) { if (j != k) model.setChannelActive(j, false); } images.add(model.getSplitComponentImage()); } else { images.add(null); } } w = active.iterator(); while (w.hasNext()) { //reset values. model.setChannelActive((Integer) w.next(), true); } if (active.size() != 0) { model.setColorModel(RGB_MODEL, false); images.add(model.getSplitComponentImage()); model.setColorModel(GREY_SCALE_MODEL, false); } } else { while (i.hasNext()) { k = i.next().getIndex(); if (model.isChannelActive(k)) { for (int l = 0; l < maxC; l++) { model.setChannelActive(l, k == l); } images.add(model.getSplitComponentImage()); w = active.iterator(); while (w.hasNext()) { //reset values. model.setChannelActive((Integer) w.next(), true); } } else { images.add(null); } } } view.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return images; } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getCombinedGridImage() */ public BufferedImage getCombinedGridImage() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW"+ " state."); } //view.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (!GREY_SCALE_MODEL.equals(model.getColorModel())) return null; List active = view.getActiveChannelsInGrid(); BufferedImage image = null; Iterator i = active.iterator(); for (int k = 0; k < model.getMaxC(); k++) { model.setChannelActive(k, false); } while (i.hasNext()) { //reset values. model.setChannelActive(((Integer) i.next()).intValue(), true); } if (active.size() != 0) { model.setColorModel(RGB_MODEL, false); image = model.getSplitComponentImage(); model.setColorModel(GREY_SCALE_MODEL, false); } active = model.getActiveChannels(); i = active.iterator(); while (i.hasNext()) { //reset values. model.setChannelActive(((Integer) i.next()).intValue(), true); } return image; } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getDisplayedImage(boolean) */ public BufferedImage getDisplayedImage(boolean includeROI) { switch (model.getState()) { case NEW: throw new IllegalStateException( "This method can't be invoked in the NEW state."); case DISCARDED: return null; } if (includeROI) { if (layers == null) return model.getDisplayedImage(); return createImageWithROI(model.getDisplayedImage()); } return model.getDisplayedImage(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getDisplayedProjectedImage() */ public BufferedImage getDisplayedProjectedImage() { switch (model.getState()) { case NEW: throw new IllegalStateException( "This method can't be invoked in the NEW state."); case DISCARDED: return null; } return model.getBrowser().getDisplayedProjectedImage(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getPixelsSizeX() */ public Length getPixelsSizeX() { switch (model.getState()) { case NEW: throw new IllegalStateException( "This method can't be invoked in the NEW state."); case DISCARDED: return new LengthI(1, UnitsLength.PIXEL); } return model.getPixelsSizeX(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getPixelsSizeY() */ public Length getPixelsSizeY() { switch (model.getState()) { case NEW: throw new IllegalStateException( "This method can't be invoked in the NEW state."); case DISCARDED: return new LengthI(1, UnitsLength.PIXEL); } return model.getPixelsSizeY(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getPixelsSizeZ() */ public Length getPixelsSizeZ() { switch (model.getState()) { case NEW: throw new IllegalStateException( "This method can't be invoked in the NEW state."); case DISCARDED: return new LengthI(1, UnitsLength.PIXEL); } return model.getPixelsSizeZ(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getViewTitle() */ public String getViewTitle() { if (model.getState() == DISCARDED) return ""; return view.getTitle(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getChannelMetadata(int) */ public ChannelData getChannelMetadata(int index) { if (model.getState() == DISCARDED) throw new IllegalStateException( "This method can't be invoked in the DISCARDED state."); return model.getChannelData(index); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getActiveChannels() */ public List getActiveChannels() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW "+ "state."); } return model.getActiveChannels(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isUnitBar() */ public boolean isUnitBar() { if (model.getState() == DISCARDED) return false; return model.isUnitBar(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setUnitBar(boolean) */ public void setUnitBar(boolean b) { if (model.getState() == DISCARDED) return; model.getBrowser().setUnitBar(b); controller.setPreferences(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getHistoryState() */ public int getHistoryState() { return controller.getHistoryState(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getChannelColor(int) */ public Color getChannelColor(int index) { if (model.getState() == DISCARDED) return null; return model.getChannelColor(index); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setUnitBarSize(double) */ public void setUnitBarSize(double size) { if (model.getState() == DISCARDED) return; model.getBrowser().setUnitBarSize(size, model.getScaleBarUnit()); controller.setPreferences(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showUnitBarSelection() */ public void showUnitBarSelection() { if (model.getState() == DISCARDED) return; UnitBarSizeDialog d = new UnitBarSizeDialog(view, model.getScaleBarUnit()); d.addPropertyChangeListener(controller); UIUtilities.centerAndShow(d); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#resetDefaults() */ public void resetDefaults() { if (model.getState() == DISCARDED) throw new IllegalStateException("The method cannot be invoked in " + "the DISCARDED state."); view.setLeftStatus(); view.setPlaneInfoStatus(); view.resetDefaults(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getUnitBarValue() */ public String getUnitBarValue() { if (model.getState() == DISCARDED) return ""; return model.getBrowser().getUnitBarValue(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getUnitBarSize() */ public double getUnitBarSize() { if (model.getState() == DISCARDED) return 0; return model.getBrowser().getUnitBarSize(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getUnitBarColor() */ public Color getUnitBarColor() { if (model.getState() == DISCARDED) return null; if (model.getBrowser() == null) return null; return model.getBrowser().getUnitBarColor(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getImageIcon() */ public ImageIcon getImageIcon() { BufferedImage img = model.getImageIcon(); if (img == null) return null; return new ImageIcon(img); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showLens() */ public void showLens() { if (model.getState() == DISCARDED) return; view.setLensVisible(!view.isLensVisible(), model.getTabbedIndex()); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getZoomedLensImage() */ public BufferedImage getZoomedLensImage() { if (model.getState() == DISCARDED) return null; return view.getZoomedLensImage(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showMenu(int, Component, Point) */ public void showMenu(int menuID, Component source, Point location) { if (model.getState() == DISCARDED) return; if (source == null) throw new IllegalArgumentException("No component."); if (location == null) { Point p = source.getLocation(); location = new Point(p.x+source.getWidth(), Math.abs( p.y-source.getHeight())); } switch (menuID) { case COLOR_PICKER_MENU: if (model.getMaxC() == 1) showColorPicker(0); else view.showMenu(menuID, source, location); break; case ACTIVITY_MENU: model.activityOptions(source, location); break; default: throw new IllegalArgumentException("Menu not supported."); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getMaxX() */ public int getMaxX() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or" + " NEW state."); } return model.getMaxX(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getMaxY() */ public int getMaxY() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW" + "state."); } return model.getMaxY(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getSelectedIndex() */ public int getSelectedIndex() { return model.getTabbedIndex(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#playMovie(boolean, boolean, int) */ public void playMovie(boolean play, boolean visible, int index) { switch (model.getState()) { case NEW: case LOADING_METADATA: case DISCARDED: return; } MoviePlayerDialog d = controller.getMoviePlayer(); boolean doClick = false; if (visible) { // we have to play the movie if (!d.isVisible()) { controller.getAction( ImViewerControl.PLAY_MOVIE_T).setEnabled(false); controller.getAction( ImViewerControl.PLAY_MOVIE_Z).setEnabled(false); play = true; UIUtilities.setLocationRelativeToAndShow(view, d); } } else { if (d.isVisible()) { controller.getAction( ImViewerControl.PLAY_MOVIE_T).setEnabled(true); controller.getAction( ImViewerControl.PLAY_MOVIE_Z).setEnabled(true); play = false; d.setVisible(false); } else { switch (index) { case PlayMovieAction.ACROSS_Z: d.setZRange(model.getDefaultZ(), model.getMaxZ()); controller.getAction( ImViewerControl.PLAY_MOVIE_T).setEnabled(!play); break; case PlayMovieAction.ACROSS_T: controller.getAction( ImViewerControl.PLAY_MOVIE_Z).setEnabled(!play); break; case PlayMovieAction.ACROSS_LIFETIME: d.setBinRange(model.getSelectedBin(), model.getMaxLifetimeBin()-1); controller.getAction( ImViewerControl.PLAY_LIFETIME_MOVIE).setEnabled(!play); break; default: controller.getAction( ImViewerControl.PLAY_MOVIE_T).setEnabled(true); controller.getAction( ImViewerControl.PLAY_MOVIE_Z).setEnabled(true); } doClick = true; if (index != -1) d.setMovieIndex(index); d.setTimeRange(model.getRealSelectedT(), model.getRealT()-1); } } model.setPlayingMovie(play, index); view.enableSliders(!play); controller.getAction(ImViewerControl.CHANNEL_MOVIE).setEnabled(!play); if (doClick) { if (play) { d.addPropertyChangeListener( MoviePlayerDialog.MOVIE_STATE_CHANGED_PROPERTY, controller); d.doClick(MoviePlayerDialog.DO_CLICK_PLAY); } else { d.removePropertyChangeListener( MoviePlayerDialog.MOVIE_STATE_CHANGED_PROPERTY, controller); d.doClick(MoviePlayerDialog.DO_CLICK_PAUSE); } } else { d.removePropertyChangeListener( MoviePlayerDialog.MOVIE_STATE_CHANGED_PROPERTY, controller); } if (!play) { if (view.isLensVisible()) view.setLensPlaneImage(); switch (view.getTabbedIndex()) { case ImViewer.VIEW_INDEX: view.createHistoryItem(null); break; case ImViewer.PROJECTION_INDEX: view.createHistoryItem(view.getLastProjRef()); } if (model.getState() != LOADING_IMAGE) model.setState(READY); fireStateChange(); } } /** * * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getGridImage() */ public BufferedImage getGridImage() { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or NEW" + "state."); } return model.getBrowser().getGridImage(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getLensImageComponents(String) */ public List getLensImageComponents(String colorModel) { if (!view.hasLensImage()) return null; if (model.getTabbedIndex() != ImViewer.VIEW_INDEX) return null; switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or " + "NEW state."); } if (model.getColorModel().equals(GREY_SCALE_MODEL)) return null; List l = model.getActiveChannels(); if (l.size() < 2) return null; Iterator i = l.iterator(); int index; String oldColorModel = model.getColorModel(); List<BufferedImage> images = new ArrayList<BufferedImage>(l.size()); model.setColorModel(colorModel, false); while (i.hasNext()) { index = ((Integer) i.next()).intValue(); for (int j = 0; j < model.getMaxC(); j++) model.setChannelActive(j, j == index); images.add(view.createZoomedLensImage( model.getSplitComponentImage())); } model.setColorModel(oldColorModel, false); i = l.iterator(); while (i.hasNext()) { //reset values. index = ((Integer) i.next()).intValue(); model.setChannelActive(index, true); } return images; } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isTextVisible() */ public boolean isTextVisible() { return model.isTextVisible(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setTextVisible(boolean) */ public void setTextVisible(boolean b) { model.setTextVisible(b); model.getBrowser().viewSplitImages(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showMeasurementTool(Point) */ public void showMeasurementTool(Point point) { //TODO: Review for HCS. if (!model.isHCSImage()) { postMeasurementEvent(null); return; } Collection measurements = model.getMeasurements(); if (measurements == null || measurements.size() == 0) { postMeasurementEvent(null); return; } Map<JCheckBox, FileAnnotationData> boxes = new LinkedHashMap<JCheckBox, FileAnnotationData>(); JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); Iterator i; if (measurements != null) { i = measurements.iterator(); FileAnnotationData fa; JCheckBox box; Object object; while (i.hasNext()) { object = i.next(); if (object instanceof FileAnnotationData) { fa = (FileAnnotationData) object; box = new JCheckBox(fa.getDescription()); box.setSelected(true); p.add(box); boxes.put(box, fa); } } } if (boxes.size() == 0) return; view.setMeasurementLaunchingStatus(true); MessageBox msg = new MessageBox(view, "Measurements", "Select the measurements to display alongside the image."); msg.setNoText("Cancel"); msg.setYesText("Display"); msg.addBodyComponent(p); int option; if (point != null) option = msg.showMsgBox(point); else option = msg.centerMsgBox(); List<FileAnnotationData> files = new ArrayList<FileAnnotationData>(); if (option == MessageBox.YES_OPTION) { Entry entry; i = boxes.entrySet().iterator(); while (i.hasNext()) { entry = (Entry) i.next(); if (((JCheckBox) entry.getKey()).isSelected()) files.add((FileAnnotationData) entry.getValue()); } if (files.size() > 0) postMeasurementEvent(files); } else { view.setMeasurementLaunchingStatus(false); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#addToView(JComponent) */ public void addToView(JComponent comp) { if (model.getState() != READY) return; if (comp == null) return; if (layers == null) layers = new ArrayList<JComponent>(); layers.add(comp); view.setMeasurementLaunchingStatus(false); model.getBrowser().addComponent(comp, ImViewer.VIEW_INDEX, false); comp.setVisible(true); view.repaint(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#removeFromView(JComponent) */ public void removeFromView(JComponent comp) { if (model.getState() != READY) return; if (comp == null) return; if (layers != null) layers.remove(comp); model.getBrowser().removeComponent(comp, ImViewer.VIEW_INDEX); view.repaint(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#hasLens() */ public boolean hasLens() { if (model.getState() == DISCARDED) throw new IllegalStateException("This method cannot be invoked " + "in the DISCARDED state."); if (model.getState() != READY) return false; return view.hasLensImage(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getZoomFactor() */ public double getZoomFactor() { if (model.getState() == DISCARDED) throw new IllegalStateException("This method cannot be invoked " + "in the DISCARDED state."); if (model.getState() != READY) return -1; return model.getZoomFactor(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isPlayingMovie() */ public boolean isPlayingMovie() { return model.isPlayingMovie(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isChannelRed(int) */ public boolean isChannelRed(int index) { return model.isColorComponent(Renderer.RED_BAND, index); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isChannelGreen(int) */ public boolean isChannelGreen(int index) { return model.isColorComponent(Renderer.GREEN_BAND, index); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isChannelBlue(int) */ public boolean isChannelBlue(int index) { return model.isColorComponent(Renderer.BLUE_BAND, index); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isChannelActive(int) */ public boolean isChannelActive(int index) { return model.isChannelActive(index); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#copyRenderingSettings() */ public void copyRenderingSettings() { switch (model.getState()) { case NEW: case DISCARDED: //throw new IllegalStateException( //"This method can't be invoked in the DISCARDED, NEW state."); return; } try { model.copyRenderingSettings(); saveBeforeCopy = false; } catch (Exception e) { saveBeforeCopy = false; failureToSave = true; Logger logger = ImViewerAgent.getRegistry().getLogger(); LogMessage logMsg = new LogMessage(); logMsg.print("Rendering Exception:"); logMsg.println(e.getMessage()); logMsg.print(e); logger.error(this, logMsg); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#pasteRenderingSettings() */ public void pasteRenderingSettings() { switch (model.getState()) { case NEW: case DISCARDED: return; } if (!model.hasRndToPaste()) { return; } model.fireLoadRndSettingsToPaste(); fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#reloadRenderingThumbs() */ public void reloadRenderingThumbs() { model.reloadRenderingThumbs(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#hasSettingsToPaste() */ public boolean hasSettingsToPaste() { switch (model.getState()) { case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED state."); } return model.hasRndToPaste(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isHistoryShown() */ public boolean isHistoryShown() { if (model.getState() == DISCARDED) throw new IllegalStateException( "This method can't be invoked in the DISCARDED state."); return view.isHistoryShown(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showHistory(boolean) */ public void showHistory(boolean b) { if (model.getState() == DISCARDED) throw new IllegalStateException( "This method can't be invoked in the DISCARDED state."); view.showHistory(b); controller.setPreferences(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#resetDefaultRndSettings() */ public void resetDefaultRndSettings() { if (model.getState() == DISCARDED) throw new IllegalStateException( "This method can't be invoked in the DISCARDED state."); //addHistoryItem(); model.resetDefaultRndSettings(); view.resetDefaults(); renderXYPlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#saveRndSettings(boolean) */ public void saveRndSettings(boolean post) { try { model.saveRndSettings(true); failureToSave = false; } catch (Exception e) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo("Save settings", "Cannot save rendering settings. "); Logger logger = ImViewerAgent.getRegistry().getLogger(); LogMessage msg = new LogMessage(); msg.print("Save rendering settings"); msg.print(e); logger.error(this, msg); failureToSave = true; //post event indicating no settings to save } if (post) { EventBus bus = ImViewerAgent.getRegistry().getEventBus(); bus.post(new RndSettingsCopied(Arrays.asList(model.getImageID()), getPixelsID())); fireStateChange(); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#saveRndSettings() */ public void toFront() { if (model.getState() == DISCARDED) return; controller.toFront(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getMovieIndex() */ public int getMovieIndex() { if (model.getState() == DISCARDED || !model.isPlayingMovie() || model.isPlayingChannelMovie()) return -1; return model.getMovieIndex(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getActiveChannelsInGrid() */ public List getActiveChannelsInGrid() { if (model.getState() == DISCARDED) return null; return view.getActiveChannelsInGrid(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showPreferences() */ public void showPreferences() { ViewerPreferences pref = ImViewerFactory.getPreferences(); PreferencesDialog d = new PreferencesDialog(view, pref); d.addPropertyChangeListener(controller); UIUtilities.centerAndShow(d); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setRenderingSettings(Map, long) */ public void setRenderingSettings(Map map, long userID) { if (model.getState() == DISCARDED) return; model.setRenderingSettings(map); if (userID >= 0) { if (map != null) { Entry entry; Iterator i = map.entrySet().iterator(); ExperimenterData exp; while (i.hasNext()) { entry = (Entry) i.next(); exp = (ExperimenterData) entry.getKey(); if (exp.getId() == userID) { model.setUserSettings(exp); break; } } } } else { view.showUsersList(); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#retrieveRelatedSettings(Component, Point) */ public void retrieveRelatedSettings(Component source, Point location) { if (model.getState() == DISCARDED) return; Map m = model.getRenderingSettings(); view.setLocationAndSource(source, location); if (m == null) model.fireRenderingSettingsRetrieval(); else view.showUsersList(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setGridMagnificationFactor(double) */ public void setGridMagnificationFactor(double factor) { if (model.getTabbedIndex() != ImViewer.GRID_INDEX) return; view.setGridMagnificationFactor(factor); model.getBrowser().setGridRatio(factor); if (view.isLensVisible()) { view.setImageZoomFactor((float) model.getBrowser().getGridRatio()); view.scrollLens(); } /* if (view.isLensVisible() && model.getTabbedIndex() == ImViewer.GRID_INDEX) { view.setImageZoomFactor((float) model.getBrowser().getGridRatio()); view.scrollLens(); } */ } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setUserRndSettings(ExperimenterData) */ public void setUserRndSettings(ExperimenterData exp) { if (model.getState() == DISCARDED) throw new IllegalArgumentException("This method cannot be invoked" + " in the DISCARDED state."); try { view.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); model.setUserSettings(exp); view.resetDefaults(); renderXYPlane(); } catch (Exception e) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo("Set User rendering settings", "Could not apply " + "the settings set by "+exp.getFirstName()+ " "+exp.getLastName()); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getUserDetails() */ public ExperimenterData getUserDetails() { if (model.getState() == DISCARDED) throw new IllegalArgumentException("This method cannot be invoked" + " in the DISCARDED state."); return model.getUserDetails(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showView(int) */ public void showView(int index) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or" + "NEW state."); } if (index == RENDERER_INDEX || index == METADATA_INDEX) { view.showRenderer(false, index); controller.setPreferences(); } else { view.showView(index); setSelectedPane(index); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setOriginalRndSettings() */ public void setOriginalRndSettings() { if (model.getState() == DISCARDED) throw new IllegalArgumentException("This method cannot be invoked" + " in the DISCARDED state."); model.setOriginalRndSettings(); view.resetDefaults(); renderXYPlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#projectImage(ProjectionRef) */ public void projectImage(ProjectionRef ref) { if (model.getState() == DISCARDED) throw new IllegalArgumentException("This method cannot be invoked" + " in the DISCARDED state."); if (model.getTabbedIndex() != PROJECTION_INDEX) return; if (ref == null) throw new IllegalArgumentException("No projection object"); model.fireImageProjection(ref.getStartZ(), ref.getEndZ(), view.getProjectionStepping(), view.getProjectionType(), view.getProjectionTypeName(), ref); fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setProjectionPreview(Object) */ public void setProjectionPreview(Object image) { if (image == null) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo("Projection preview", "An error has occurred " + "while projecting the data."); return; } if (model.getTabbedIndex() != PROJECTION_INDEX) return; model.setRenderProjected(image); view.setLeftStatus(); view.setPlaneInfoStatus(); if (!model.isPlayingMovie() && !model.isPlayingChannelMovie()) { if (view.isLensVisible()) view.setLensPlaneImage(); view.createHistoryItem(model.getLastProjRef()); } fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setContainers(Collection) */ public void setContainers(Collection containers) { /* if (model.getState() != LOADING_PROJECTION_DATA) throw new IllegalArgumentException("This method can only be " + "invoked in the LOADING_PROJECTION_DATA state."); */ //Create a modal dialog. if (model.getTabbedIndex() != PROJECTION_INDEX) return; model.setContainers(containers); fireStateChange(); if (projDialog == null) showProjectionDialog(); else projDialog.setContainers(model.getContainers()); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#loadContainers() */ public void loadContainers() { if (model.getState() == DISCARDED) throw new IllegalArgumentException("This method cannot be invoked" + " in the DISCARDED state."); if (model.getTabbedIndex() != PROJECTION_INDEX) return; if (model.getContainers() == null) { model.fireContainersLoading(); fireStateChange(); } else showProjectionDialog(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setProjectedImage(ImageData, List, List, boolean) */ public void setProjectedImage(ImageData image, List<Integer> indexes, List<DataObject> containers, boolean applySettings) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); String message; if (image == null) { message = "An error occurred while creating the projected image."; un.notifyInfo("Projection", message); model.setState(READY); } else { if (applySettings) model.fireProjectedRndSettingsCreation(indexes, image); else notifyProjection("The projected image has been " + "successfully created.", image); if (containers != null) { EventBus bus = ImViewerAgent.getRegistry().getEventBus(); bus.post(new NodeToRefreshEvent(containers, true)); } } fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setProjectedRenderingSettings(Boolean, ImageData) */ public void setProjectedRenderingSettings(Boolean result, ImageData image) { String message; if (result) message = "The projected image and the rendering settings\nhave" + " been successfully created."; else message = "An error has occurred while copying the " + "rendering settings of the projected image."; notifyProjection(message, image); fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setContext(DataObject, DataObject) */ public void setContext(DataObject parent, DataObject grandParent) { if (model.getState() == DISCARDED) return; model.setContext(parent, grandParent); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setPlaneInfo(Collection) */ public void setPlaneInfo(Collection collection) { if (collection == null) return; model.setPlaneInfo(collection); view.setPlaneInfoStatus(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setImageData(ImageData) */ public void setImageData(ImageData data) { if (model.getState() != LOADING_IMAGE_DATA) throw new IllegalArgumentException("This method can only be " + "invoked in the LOADING_IMAGE_DATA."); if (data == null) throw new IllegalArgumentException("No image to set."); model.setImageData(data); view.setImageData(); if (model.getMetadataViewer() != null) model.getMetadataViewer().addPropertyChangeListener(controller); fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setSelectedPane(int) */ public void setSelectedPane(int index) { if (model.getState() == DISCARDED) return; int oldIndex = model.getTabbedIndex(); if (oldIndex == index) return; view.setSelectedPane(index); if (oldIndex == ImViewer.GRID_INDEX) { int key = ColorModelAction.RGB_MODEL; if (GREY_SCALE_MODEL.equals(colorModel)) key = ColorModelAction.GREY_SCALE_MODEL; setColorModel(key); } firePropertyChange(TAB_SELECTION_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true)); if (oldIndex == ImViewer.PROJECTION_INDEX && index == ImViewer.VIEW_INDEX) { //check if settings have changed. //model.setLastSettingsRef(oldIndex); renderXYPlane(); } else if (index == ImViewer.PROJECTION_INDEX && oldIndex == ImViewer.VIEW_INDEX) { //model.setLastSettingsRef(oldIndex); double f = model.getZoomFactor(); if (model.getBrowser().hasProjectedPreview()) { RndProxyDef def = model.getLastProjDef(); boolean b = true; if (def != null) b = model.isSameSettings(def, false); if (!b || !isSameProjectionParam()) renderXYPlane(); else { BufferedImage image = model.getProjectedImage(); if (image != null) { int x = (int) (model.getMaxX()*f); if (x != image.getWidth()) model.setZoomFactor(f, false); } } } else { model.getBrowser().setZoomFactor(model.getZoomFactor(), false); } } else { renderXYPlane(); } model.getBrowser().getUI().setVisible(true); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#loadMetadata() */ public void loadMetadata() { if (model.getState() == DISCARDED) return; model.loadMetadata(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setColorModel(int) */ public void setCompressionLevel() { switch (model.getState()) { case DISCARDED: case PROJECTION_PREVIEW: throw new IllegalArgumentException("This method cannot be " + "invoked in the DISCARDED or PROJECTION_PREVIEW state."); } int old = view.convertCompressionLevel(); int index = view.getUICompressionLevel(); if (old == index) return; view.setCompressionLevel(index); if (!model.isLargePlane()) ImViewerFactory.setCompressionLevel(index); renderXYPlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setColorModel(int) */ public void clearHistory() { switch (model.getState()) { case DISCARDED: case PROJECTION_PREVIEW: throw new IllegalArgumentException("This method cannot be " + "invoked in the DISCARDED or PROJECTION_PREVIEW state."); } model.clearHistory(); view.clearHistory(); setSelectedPane(VIEW_INDEX); //renderXYPlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isOriginalSettings() */ public boolean isOriginalSettings() { switch (model.getState()) { case DISCARDED: throw new IllegalArgumentException("This method cannot be " + "invoked in the DISCARDED state."); } return model.isOriginalSettings(true); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setSettingsToPaste(RndProxyDef) */ public void setSettingsToPaste(RndProxyDef rndProxyDef) { if (model.getState() != PASTING) throw new IllegalArgumentException("This method should be " + "invoked in the PASTING state."); try { model.resetMappingSettings(rndProxyDef); view.resetDefaults(); renderXYPlane(); } catch (Exception e) { UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier(); Logger logger = ImViewerAgent.getRegistry().getLogger(); LogMessage logMsg = new LogMessage(); logMsg.print("Rendering Exception:"); logMsg.println(e.getMessage()); logMsg.print(e); logger.error(this, logMsg); un.notifyError("Paste Rendering settings", "An error occurred " + "while pasting the rendering settings.", e); view.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getSortedChannelData() */ public List<ChannelData> getSortedChannelData() { return model.getChannelData(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#showColorPicker(int) */ public void showColorPicker(int index) { if (model.getState() == DISCARDED) return; controller.showColorPicker(index); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#loadAllContainers() */ public void loadAllContainers() { if (model.getState() == DISCARDED) return; model.loadAllContainers(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#makeMovie() */ public void makeMovie() { if (model.getState() == DISCARDED) return; model.makeMovie(); } /** Build the view.*/ private void buildView() { int index = UnitBarSizeAction.DEFAULT_UNIT_INDEX; setUnitBarSize(UnitBarSizeAction.getValue(index)); view.setDefaultScaleBarMenu(index); colorModel = model.getColorModel(); view.buildComponents(); view.onRndLoaded(); if (model.isSeparateWindow()) { view.setOnScreen(); view.toFront(); view.requestFocusInWindow(); } else { postViewerCreated(true, false);; } if (ImViewerAgent.isFastConnection()) model.firePlaneInfoRetrieval(); view.setLeftStatus(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#onRndLoaded(boolean) */ public void onRndLoaded(boolean reload) { if (model.getState() == DISCARDED) return; model.onRndLoaded(); if (!reload) { if (model.isBigImage()) { view.setCompressionLevel(ToolBar.LOW); view.resetCompressionLevel(view.convertCompressionLevel()); model.fireBirdEyeViewRetrieval(true); fireStateChange(); return; } buildView(); } else { //TODO //clean history, reset UI element model.resetHistory(); view.switchRndControl(); } renderXYPlane(); fireStateChange(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#onChannelSelection(int) */ public void onChannelSelection(int index) { int uiIndex = ImViewerUI.ALL_VIEW; firePropertyChange(CHANNEL_ACTIVE_PROPERTY, Integer.valueOf(index-1), Integer.valueOf(index)); view.setChannelsSelection(uiIndex); postActiveChannelSelection(ChannelSelection.CHANNEL_SELECTION); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#allowSplitView() */ public boolean allowSplitView() { switch (model.getState()) { case DISCARDED: case NEW: throw new IllegalArgumentException("This method cannot be " + "invoked in the DISCARDED or NEW state."); } return model.allowSplitView(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#selectAllChannels(boolean) */ public void selectAllChannels(boolean selection) { String cm = model.getColorModel(); if (ImViewer.GREY_SCALE_MODEL.equals(cm)) return; for (int i = 0; i < model.getMaxC(); i++) { model.setChannelActive(i, selection); firePropertyChange(CHANNEL_ACTIVE_PROPERTY, Integer.valueOf(i-1), Integer.valueOf(i)); model.setSelectedChannel(i); } view.setChannelsSelection(ImViewerUI.ALL_VIEW); renderXYPlane(); postActiveChannelSelection(ChannelSelection.CHANNEL_SELECTION); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setMeasurements(Collection) */ public void setMeasurements(Collection result) { if (model.getState() == DISCARDED) return; model.setMeasurements(result); Collection measurements = model.getMeasurements(); boolean enabled = true; if (measurements == null || measurements.size() == 0) { enabled = false; } else { Iterator i; i = measurements.iterator(); FileAnnotationData fa; JCheckBox box; Object object; List<Object> l = new ArrayList<Object>(); while (i.hasNext()) { object = i.next(); if (object instanceof FileAnnotationData) l.add(object); } if (l.size() == 0) enabled = false; } if (!enabled) { Action a = controller.getAction(ImViewerControl.MEASUREMENT_TOOL); a.setEnabled(false); } //Notify UI to build overlays view.buildOverlays(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#scrollToViewport(Rectangle) */ public void scrollToViewport(Rectangle bounds) { if (bounds == null) return; model.getBrowser().scrollTo(bounds, false); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isMappedImageRGB(List) */ public boolean isMappedImageRGB(List channels) { switch (model.getState()) { case DISCARDED: return false; } return model.isMappedImageRGB(channels); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#renderOverlays(int, boolean) */ public void renderOverlays(int index, boolean selected) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or " + "NEW state."); } view.renderOverlays(index, selected); if (!view.isOverlayActive()) return; Map<Long, Integer> m = null; if (index < 0) { if (selected) m = view.getSelectedOverlays(); } else m = view.getSelectedOverlays(); model.renderOverlays(m); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#renderOverlays(int, boolean) */ public void onChannelColorChanged(int index) { switch (model.getState()) { case NEW: case DISCARDED: throw new IllegalStateException( "This method can't be invoked in the DISCARDED or " + "NEW state."); } view.setChannelColor(index, model.getChannelColor(index)); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isBigImage() */ public boolean isBigImage() { switch (model.getState()) { case NEW: case DISCARDED: case LOADING_IMAGE_DATA: return false; } return model.isBigImage(); } /** * Implemented as specified by the {@link ImViewer} interface. * * @see ImViewer#isExportable() */ public boolean isExportable() { switch (model.getState()) { case NEW: case DISCARDED: case LOADING_IMAGE_DATA: return false; } return model.isExportable(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#refresh() */ public void refresh() { view.refresh(); renderXYPlane(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#close(boolean) */ public void close(boolean notifyUser) { if (model.getState() == DISCARDED) return; if (!view.isVisible()) return; if (notifyUser) postViewerCreated(false, false); switch (model.getState()) { //case DISCARDED: default: controller.setPreferences(); //tmp store compression if (!model.isLargePlane()) ImViewerFactory.setCompressionLevel( view.getUICompressionLevel()); if (!saveOnClose(notifyUser)) { return; } if (notifyUser) { postViewerState(ViewerState.CLOSE); ImViewerRecentObject object = new ImViewerRecentObject( model.getSecurityContext(), model.getImageID(), model.getImageTitle(), getImageIcon()); firePropertyChange(RECENT_VIEWER_PROPERTY, null, object); } } view.setVisible(false); view.dispose(); discard(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#detach() */ public void detach() { if (model.getState() == DISCARDED) return; if (model.isSeparateWindow()) return; //Option not available. postViewerCreated(false, true); model.setSeparateWindow(true); view.rebuild(); view.setOnScreen(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#canAnnotate() */ public boolean canAnnotate() { if (isUserOwner()) return true; return model.getImage().canAnnotate(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isUserOwner() */ public boolean isUserOwner() { return model.isUserOwner(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setRangeAllChannels(boolean) */ public void setRangeAllChannels(boolean absolute) { model.setRangeAllChannels(absolute); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setOwnerSettings() */ public void setOwnerSettings() { Map m = model.getRenderingSettings(); if (m == null) model.fireOwnerSettingsRetrieval(); else setRenderingSettings(m, model.getOwnerID()); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#includeROI() */ public boolean includeROI() { if (layers == null) return false; Iterator<JComponent> i = layers.iterator(); while (i.hasNext()) { if (i.next() instanceof DrawingCanvasView) return true; } return false; } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setBirdEyeView(Object) */ public void setBirdEyeView(BufferedImage image, boolean scaled) { switch (model.getState()) { case LOADING_BIRD_EYE_VIEW: boolean set = false; if (!view.isVisible()) { buildView(); set = true; } model.setBirdEyeView(image, scaled); if (set) controller.setZoomFactor(model.getSelectedResolutionLevel()); return; } model.setBirdEyeView(image, scaled); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getRows() */ public int getRows() { return model.getRows(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getColumns() */ public int getColumns() { return model.getColumns(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getTiles() */ public Map<Integer, Tile> getTiles() { if (model.getState() == DISCARDED) return null; return model.getTiles(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#setTile(int) */ public void setTileCount(int count) { if (model.getState() == DISCARDED) return; model.getBrowser().getUI().repaint(); if (model.isTileLoaded(count)) { view.addComponentListener(controller); model.setState(READY); fireStateChange(); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#loadTiles(Rectangle) */ public void loadTiles(Rectangle region) { if (model.getState() == DISCARDED || !model.isRendererLoaded()) return; if (region == null) region = model.getBrowser().getVisibleRectangle(); Map<Integer, Tile> tiles = getTiles(); if (tiles == null) return; //invalidate images. Dimension d = model.getTileSize(); int width = d.width; int height = d.height; int cs = region.x/width; int rs = region.y/height; int ih = region.width/width; int iv = region.height/height; int columns = getColumns(); int index; Tile t; int h = rs+iv+1; int w = cs+ih+1; cs = cs-1; rs = rs-1; if (cs < 0) cs = 0; if (rs < 0) rs = 0; List<Tile> l = new ArrayList<Tile>(); List<Tile> toKeep = new ArrayList<Tile>(); for (int i = rs; i <= h; i++) { for (int j = cs; j <= w; j++) { index = i*columns+j; t = tiles.get(index); if (t != null) { if (t.isImageLoaded()) { if (!toKeep.contains(t)) toKeep.add(t); } else { if (!l.contains(t)) l.add(t); } } } } List<Tile> toClear = new ArrayList<Tile>(); Iterator<Tile> k = tiles.values().iterator(); while (k.hasNext()) { t = k.next(); if (t.isImageLoaded() && !toClear.contains(t) && !toKeep.contains(t)) toClear.add(t); } model.clearTileImages(toClear); if (l.size() > 0) { view.removeComponentListener(controller); model.fireTileLoading(l); fireStateChange(); } } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getTiledImageSizeX() */ public int getTiledImageSizeX() { return model.getTiledImageSizeX(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getTiledImageSizeY() */ public int getTiledImageSizeY() { return model.getTiledImageSizeY(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#cancelInit() */ public void cancelInit() { switch (model.getState()) { case LOADING_RND: if (model.isBigImage()) { model.cancelBirdEyeView(); view.dispose(); fireStateChange(); } else { model.cancelRendering(); discard(); fireStateChange(); } break; case LOADING_BIRD_EYE_VIEW: model.cancelBirdEyeView(); view.dispose(); fireStateChange(); } } /** * Returns the security context. * * @return See above. */ public SecurityContext getSecurityContext() { return model.getSecurityContext(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#isCompressed() */ public boolean isCompressed() { return model.getCompressionLevel() != RenderingControl.UNCOMPRESSED; } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#onUpdatedChannels(List) */ public void onUpdatedChannels(List<ChannelData> channels) { model.setChannels(channels); view.onChannelUpdated(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getDisplayMode() */ public int getDisplayMode() { return model.getDisplayMode(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getPixelsID() */ public long getPixelsID() { return model.getPixelsID(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getSelectedResolutionLevel() */ public int getSelectedResolutionLevel() { return model.getSelectedResolutionLevel(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getResolutionLevels() */ public int getResolutionLevels() { return model.getResolutionLevels(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getResolutionLevels() */ public int getSelectedBin() { return model.getSelectedBin(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getMaxLifetimeBin() */ public int getMaxLifetimeBin() { return model.getMaxLifetimeBin(); } /** * Implemented as specified by the {@link ImViewer} interface. * @see ImViewer#getRealSelectedT()() */ public int getRealSelectedT() { return model.getRealSelectedT(); } /** * Overridden to return the name of the instance to save. * @see #toString() */ public String toString() { return "Image's Settings: "+EditorUtil.truncate(model.getImageName()); } /** * Implemented as specified by the {@link ImViewer} interface. * * @see ImViewer#isInterpolation() */ public boolean isInterpolation() { return model.isInterpolation(); } /** * Implemented as specified by the {@link ImViewer} interface. * * @see ImViewer#setInterpolation(boolean) */ public void setInterpolation(boolean interpolation) { model.setInterpolation(interpolation); } /** * Implemented as specified by the {@link ImViewer} interface. * * @see ImViewer#setImageAcquisitionData(ImageAcquisitionData) */ public void setImageAcquisitionData(ImageAcquisitionData data) { this.acquisitionData = data; view.setMagnificationStatus(); } /** * Implemented as specified by the {@link ImViewer} interface. * * @see ImViewer#getImageAcquisitionData() */ public ImageAcquisitionData getImageAcquisitionData() { return this.acquisitionData; } void onSettingsChanged() { view.resetDefaults(); } /** * Implemented as specified by the {@link ImViewer} interface. * * @see ImViewer#reloadROICount() */ @Override public void reloadROICount() { model.reloadROICount(); } }