mev-4.0.01/source/org/tigr/microarray/mev/cluster/gui/helpers/ExperimentViewer.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2 Copyright @ 1999-2005, The Institute for Genomic Research (TIGR).
2 26 Feb 07 jari 3 All rights reserved.
2 26 Feb 07 jari 4  */
2 26 Feb 07 jari 5 /*
2 26 Feb 07 jari 6  * $RCSfile: ExperimentViewer.java,v $
2 26 Feb 07 jari 7  * $Revision: 1.12 $
2 26 Feb 07 jari 8  * $Date: 2006/07/13 16:08:37 $
2 26 Feb 07 jari 9  * $Author: eleanorahowe $
2 26 Feb 07 jari 10  * $State: Exp $
2 26 Feb 07 jari 11  */
2 26 Feb 07 jari 12 package org.tigr.microarray.mev.cluster.gui.helpers;
2 26 Feb 07 jari 13
2 26 Feb 07 jari 14 import java.awt.Color;
2 26 Feb 07 jari 15 import java.awt.Dimension;
2 26 Feb 07 jari 16 import java.awt.Font;
2 26 Feb 07 jari 17 import java.awt.FontMetrics;
2 26 Feb 07 jari 18 import java.awt.Frame;
2 26 Feb 07 jari 19 import java.awt.GradientPaint;
2 26 Feb 07 jari 20 import java.awt.Graphics;
2 26 Feb 07 jari 21 import java.awt.Graphics2D;
2 26 Feb 07 jari 22 import java.awt.Insets;
2 26 Feb 07 jari 23 import java.awt.Rectangle;
2 26 Feb 07 jari 24 import java.awt.RenderingHints;
2 26 Feb 07 jari 25 import java.awt.event.ActionListener;
2 26 Feb 07 jari 26 import java.awt.event.MouseAdapter;
2 26 Feb 07 jari 27 import java.awt.event.MouseEvent;
2 26 Feb 07 jari 28 import java.awt.event.MouseMotionListener;
2 26 Feb 07 jari 29 import java.awt.image.BufferedImage;
2 26 Feb 07 jari 30 import java.beans.Expression;
2 26 Feb 07 jari 31 import java.io.IOException;
2 26 Feb 07 jari 32 import java.io.ObjectInputStream;
2 26 Feb 07 jari 33 import java.io.ObjectOutputStream;
2 26 Feb 07 jari 34
2 26 Feb 07 jari 35 import javax.swing.JComponent;
2 26 Feb 07 jari 36 import javax.swing.JMenuItem;
2 26 Feb 07 jari 37 import javax.swing.JOptionPane;
2 26 Feb 07 jari 38 import javax.swing.JPanel;
2 26 Feb 07 jari 39 import javax.swing.JPopupMenu;
2 26 Feb 07 jari 40 import javax.swing.SwingUtilities;
2 26 Feb 07 jari 41
2 26 Feb 07 jari 42 import org.tigr.microarray.mev.cluster.clusterUtil.Cluster;
2 26 Feb 07 jari 43 import org.tigr.microarray.mev.cluster.clusterUtil.ClusterRepository;
2 26 Feb 07 jari 44 import org.tigr.microarray.mev.cluster.gui.Experiment;
2 26 Feb 07 jari 45 import org.tigr.microarray.mev.cluster.gui.IData;
2 26 Feb 07 jari 46 import org.tigr.microarray.mev.cluster.gui.IDisplayMenu;
2 26 Feb 07 jari 47 import org.tigr.microarray.mev.cluster.gui.IFramework;
2 26 Feb 07 jari 48 import org.tigr.microarray.mev.cluster.gui.IViewer;
2 26 Feb 07 jari 49 import org.tigr.microarray.mev.cluster.gui.impl.GUIFactory;
2 26 Feb 07 jari 50
2 26 Feb 07 jari 51 /**
2 26 Feb 07 jari 52  * This class is used to render an experiment values.
2 26 Feb 07 jari 53  *
2 26 Feb 07 jari 54  * @version 1.0
2 26 Feb 07 jari 55  * @author Aleksey D.Rezantsev
2 26 Feb 07 jari 56  */
2 26 Feb 07 jari 57 public class ExperimentViewer extends JPanel implements IViewer {
2 26 Feb 07 jari 58     
2 26 Feb 07 jari 59     private static final float INITIAL_MAX_VALUE = 3f;
2 26 Feb 07 jari 60     private static final float INITIAL_MIN_VALUE = -3f;
2 26 Feb 07 jari 61     private static final String NO_GENES_STR = "No Genes in Cluster!";
2 26 Feb 07 jari 62     private static final Font ERROR_FONT = new Font("monospaced", Font.BOLD, 20);
2 26 Feb 07 jari 63     protected static final String STORE_CLUSTER_CMD = "store-cluster-cmd";
2 26 Feb 07 jari 64     protected static final String SET_DEF_COLOR_CMD = "set-def-color-cmd";
2 26 Feb 07 jari 65     protected static final String SAVE_CLUSTER_CMD = "save-cluster-cmd";
2 26 Feb 07 jari 66     protected static final String SAVE_ALL_CLUSTERS_CMD = "save-all-clusters-cmd";
2 26 Feb 07 jari 67     protected static final String LAUNCH_NEW_SESSION_CMD = "launch-new-session-cmd";
2 26 Feb 07 jari 68     
2 26 Feb 07 jari 69     private ExperimentHeader header;
2 26 Feb 07 jari 70     private Experiment experiment;
2 26 Feb 07 jari 71     private IFramework framework;
2 26 Feb 07 jari 72     private IData data;
2 26 Feb 07 jari 73     private int clusterIndex = 0;
2 26 Feb 07 jari 74     private int[][] clusters;
2 26 Feb 07 jari 75     private int[] samplesOrder;
2 26 Feb 07 jari 76     private Dimension elementSize = new Dimension(20, 5);
2 26 Feb 07 jari 77     private int labelIndex = -1;
2 26 Feb 07 jari 78     private boolean isAntiAliasing = true;
2 26 Feb 07 jari 79     private boolean isDrawBorders = true;
2 26 Feb 07 jari 80     private boolean isDrawAnnotations = true;
2 26 Feb 07 jari 81     public static Color missingColor = new Color(128, 128, 128);
2 26 Feb 07 jari 82     public static Color maskColor = new Color(255, 255, 255, 128);
2 26 Feb 07 jari 83     private float maxValue = INITIAL_MAX_VALUE;
2 26 Feb 07 jari 84     private float minValue = INITIAL_MIN_VALUE;
2 26 Feb 07 jari 85     private float midValue = 0.0f;
2 26 Feb 07 jari 86     private int firstSelectedRow = -1;
2 26 Feb 07 jari 87     private int lastSelectedRow  = -1;
2 26 Feb 07 jari 88     private int firstSelectedColumn = -1;
2 26 Feb 07 jari 89     private int lastSelectedColumn  = -1;
2 26 Feb 07 jari 90     public BufferedImage posColorImage = createGradientImage(Color.black, Color.red);
2 26 Feb 07 jari 91     public BufferedImage negColorImage = createGradientImage(Color.green, Color.black);
2 26 Feb 07 jari 92     private int annotationWidth;
2 26 Feb 07 jari 93     private Insets insets = new Insets(0, 10, 0, 0);
2 26 Feb 07 jari 94     private int contentWidth = 0;
2 26 Feb 07 jari 95     private boolean useDoubleGradient = true;
2 26 Feb 07 jari 96     private boolean showClusters = true;
2 26 Feb 07 jari 97     private boolean haveColorBar = false;
2 26 Feb 07 jari 98     protected int exptID = 0;
2 26 Feb 07 jari 99     
2 26 Feb 07 jari 100     
2 26 Feb 07 jari 101     public Expression getExpression(){
2 26 Feb 07 jari 102       return new Expression(this, this.getClass(), "new", 
2 26 Feb 07 jari 103         new Object[]{this.experiment, this.clusters, this.samplesOrder, new Boolean(this.isDrawAnnotations)});
2 26 Feb 07 jari 104     }
2 26 Feb 07 jari 105     /**
2 26 Feb 07 jari 106      * Constructs an <code>ExperimentViewer</code> with specified
2 26 Feb 07 jari 107      * experiment and clusters.
2 26 Feb 07 jari 108      *
2 26 Feb 07 jari 109      * @param experiment the experiment data.
2 26 Feb 07 jari 110      * @param clusters the two dimensional array with spots indices.
2 26 Feb 07 jari 111      */
2 26 Feb 07 jari 112     public ExperimentViewer(Experiment experiment, int[][] clusters) {
2 26 Feb 07 jari 113         this(experiment, clusters, true);
2 26 Feb 07 jari 114     }
2 26 Feb 07 jari 115     
2 26 Feb 07 jari 116     /**
2 26 Feb 07 jari 117      * Constructs an <code>ExperimentViewer</code> with specified
2 26 Feb 07 jari 118      * experiment, clusters and draw annotations attribute.
2 26 Feb 07 jari 119      *
2 26 Feb 07 jari 120      * @param experiment the experiment data.
2 26 Feb 07 jari 121      * @param clusters the two dimensional array with spots indices.
2 26 Feb 07 jari 122      * @param drawAnnotations true if this viewer must draw annotations.
2 26 Feb 07 jari 123      */
2 26 Feb 07 jari 124     public ExperimentViewer(Experiment experiment, int[][] clusters, boolean drawAnnotations) {
2 26 Feb 07 jari 125         this(experiment, clusters, null, drawAnnotations);
2 26 Feb 07 jari 126     }
2 26 Feb 07 jari 127     /**
2 26 Feb 07 jari 128      * State-saving constructor
2 26 Feb 07 jari 129      * @param experiment
2 26 Feb 07 jari 130      * @param clusters
2 26 Feb 07 jari 131      * @param samplesOrder
2 26 Feb 07 jari 132      * @param drawAnnotations
2 26 Feb 07 jari 133      */
2 26 Feb 07 jari 134     public ExperimentViewer(Experiment experiment, int[][] clusters, int[] samplesOrder, Boolean drawAnnotations) {
2 26 Feb 07 jari 135       this(experiment, clusters, samplesOrder, drawAnnotations.booleanValue());
2 26 Feb 07 jari 136     }
2 26 Feb 07 jari 137     /**
2 26 Feb 07 jari 138      * Constructs an <code>ExperimentViewer</code> with specified
2 26 Feb 07 jari 139      * experiment, clusters, samples order and draw annotations attribute.
2 26 Feb 07 jari 140      *
2 26 Feb 07 jari 141      * @param experiment the experiment data.
2 26 Feb 07 jari 142      * @param clusters the two dimensional array with spots indices.
2 26 Feb 07 jari 143      * @param samplesOrder the one dimensional array with samples indices.
2 26 Feb 07 jari 144      * @param drawAnnotations true if this viewer must draw annotations.
2 26 Feb 07 jari 145      */
2 26 Feb 07 jari 146     public ExperimentViewer(Experiment experiment, int[][] clusters, int[] samplesOrder, boolean drawAnnotations) {
2 26 Feb 07 jari 147         if (experiment == null) {
2 26 Feb 07 jari 148             throw new IllegalArgumentException("experiment == null");
2 26 Feb 07 jari 149         }
2 26 Feb 07 jari 150         this.experiment = experiment;
2 26 Feb 07 jari 151         this.exptID = experiment.getId();
2 26 Feb 07 jari 152         this.clusters = clusters == null ? defGenesOrder(experiment.getNumberOfGenes()) : clusters;
2 26 Feb 07 jari 153         this.samplesOrder = samplesOrder == null ? defSamplesOrder(experiment.getNumberOfSamples()) : samplesOrder;
2 26 Feb 07 jari 154         this.isDrawAnnotations = drawAnnotations;
2 26 Feb 07 jari 155         this.header = new ExperimentHeader(this.experiment, this.clusters, this.samplesOrder);
2 26 Feb 07 jari 156         this.header.setNegAndPosColorImages(this.negColorImage, this.posColorImage);
2 26 Feb 07 jari 157         setBackground(Color.white);
2 26 Feb 07 jari 158         Listener listener = new Listener();
2 26 Feb 07 jari 159         addMouseListener(listener);
2 26 Feb 07 jari 160         addMouseMotionListener(listener);
2 26 Feb 07 jari 161     }
2 26 Feb 07 jari 162     
2 26 Feb 07 jari 163     
2 26 Feb 07 jari 164     /**
2 26 Feb 07 jari 165      * Constructs an <code>ExperimentViewer</code> with specified
2 26 Feb 07 jari 166      * experiment, clusters, samples order and draw annotations attribute.
2 26 Feb 07 jari 167      *
2 26 Feb 07 jari 168      * @param experiment the experiment data.
2 26 Feb 07 jari 169      * @param clusters the two dimensional array with spots indices.
2 26 Feb 07 jari 170      * @param samplesOrder the one dimensional array with samples indices.
2 26 Feb 07 jari 171      * @param drawAnnotations true if this viewer must draw annotations.
2 26 Feb 07 jari 172      */
2 26 Feb 07 jari 173     public ExperimentViewer(Experiment experiment, int[][] clusters, int[] samplesOrder, boolean drawAnnotations, int offset) {
2 26 Feb 07 jari 174         if (experiment == null) {
2 26 Feb 07 jari 175             throw new IllegalArgumentException("experiment == null");
2 26 Feb 07 jari 176         }
2 26 Feb 07 jari 177         this.experiment = experiment;
2 26 Feb 07 jari 178         this.exptID = experiment.getId();
2 26 Feb 07 jari 179         this.clusters = clusters == null ? defGenesOrder(experiment.getNumberOfGenes()) : clusters;
2 26 Feb 07 jari 180         this.samplesOrder = samplesOrder == null ? defSamplesOrder(experiment.getNumberOfSamples()) : samplesOrder;
2 26 Feb 07 jari 181         this.isDrawAnnotations = drawAnnotations;
2 26 Feb 07 jari 182         this.header = new ExperimentHeader(this.experiment, this.clusters, this.samplesOrder);
2 26 Feb 07 jari 183         this.header.setNegAndPosColorImages(this.negColorImage, this.posColorImage);
2 26 Feb 07 jari 184         this.insets.left = offset;
2 26 Feb 07 jari 185         this.header.setLeftInset(offset);
2 26 Feb 07 jari 186         setBackground(Color.white);
2 26 Feb 07 jari 187         Listener listener = new Listener();
2 26 Feb 07 jari 188         addMouseListener(listener);
2 26 Feb 07 jari 189         addMouseMotionListener(listener);
2 26 Feb 07 jari 190     }
2 26 Feb 07 jari 191     
2 26 Feb 07 jari 192     public ExperimentViewer(){  }
2 26 Feb 07 jari 193     public void setInsets(Insets i) {
2 26 Feb 07 jari 194       this.insets = i;
2 26 Feb 07 jari 195     }    
2 26 Feb 07 jari 196     /**
2 26 Feb 07 jari 197      * This constructor is used to re-create an ExperimentViewer from information
2 26 Feb 07 jari 198      * stored in a saved analysis file by XMLEncoder.  
2 26 Feb 07 jari 199      * @param experiment TODO
2 26 Feb 07 jari 200      * @param clusters
2 26 Feb 07 jari 201      * @param samplesOrder
2 26 Feb 07 jari 202      * @param drawAnnotations
2 26 Feb 07 jari 203      * @param header
2 26 Feb 07 jari 204      * @param insets
2 26 Feb 07 jari 205      * @param experiment
2 26 Feb 07 jari 206      */
2 26 Feb 07 jari 207     public ExperimentViewer(Experiment experiment, int[][] clusters, int[] samplesOrder, boolean drawAnnotations, ExperimentHeader header, Insets insets) {
2 26 Feb 07 jari 208       this.insets = insets;
2 26 Feb 07 jari 209       this.experiment = experiment;
2 26 Feb 07 jari 210       this.header = header;
2 26 Feb 07 jari 211       this.clusters = clusters;
2 26 Feb 07 jari 212       this.samplesOrder = samplesOrder;
2 26 Feb 07 jari 213       this.isDrawAnnotations = drawAnnotations;
2 26 Feb 07 jari 214       this.header = header;
2 26 Feb 07 jari 215
2 26 Feb 07 jari 216       setBackground(Color.white);
2 26 Feb 07 jari 217       
2 26 Feb 07 jari 218       Listener listener = new Listener();
2 26 Feb 07 jari 219       addMouseListener(listener);
2 26 Feb 07 jari 220       addMouseMotionListener(listener);
2 26 Feb 07 jari 221     }
2 26 Feb 07 jari 222     /*
2 26 Feb 07 jari 223     copy-paste this constructor into descendent classes
2 26 Feb 07 jari 224     /**
2 26 Feb 07 jari 225      * @inheritDoc
2 26 Feb 07 jari 226      * 
2 26 Feb 07 jari 227     public ExperimentViewer(Experiment e, int[][] clusters, int[] samplesOrder, boolean drawAnnotations, ExperimentHeader header, Insets insets) {
2 26 Feb 07 jari 228       super(e, clusters, samplesOrder, drawAnnotations, header, insets);
2 26 Feb 07 jari 229     } 
2 26 Feb 07 jari 230     */
2 26 Feb 07 jari 231     
2 26 Feb 07 jari 232     /**
2 26 Feb 07 jari 233      * @inheritdoc
2 26 Feb 07 jari 234      */
2 26 Feb 07 jari 235 //    public Expression getExpression(){
2 26 Feb 07 jari 236 //      return new Expression(this, this.getClass(), "new",
2 26 Feb 07 jari 237 //        new Object[]{this.clusters, this.samplesOrder, new Boolean(this.isDrawAnnotations), this.header, this.insets, new Integer(this.exptID)});  
2 26 Feb 07 jari 238 //    }
2 26 Feb 07 jari 239     
2 26 Feb 07 jari 240     public void setExperiment(Experiment e) {
2 26 Feb 07 jari 241       this.experiment = e;
2 26 Feb 07 jari 242       this.exptID = experiment.getId();
2 26 Feb 07 jari 243       if(this.header !=null){
2 26 Feb 07 jari 244         this.header.setExperiment(e);
2 26 Feb 07 jari 245       } else{
2 26 Feb 07 jari 246         this.header = new ExperimentHeader(this.experiment, this.clusters, this.samplesOrder);
2 26 Feb 07 jari 247             this.header.setNegAndPosColorImages(this.negColorImage, this.posColorImage);
2 26 Feb 07 jari 248       }
2 26 Feb 07 jari 249        this.header.setIData(data);
2 26 Feb 07 jari 250     }
2 26 Feb 07 jari 251     /*
2 26 Feb 07 jari 252     public ExperimentHeader getHeader() {
2 26 Feb 07 jari 253       return header;
2 26 Feb 07 jari 254     }
2 26 Feb 07 jari 255     public int[] getSamplesOrder(){
2 26 Feb 07 jari 256       return samplesOrder;
2 26 Feb 07 jari 257     }
2 26 Feb 07 jari 258     public boolean getIsDrawAnnotations(){return isDrawAnnotations;}
2 26 Feb 07 jari 259
2 26 Feb 07 jari 260     public Insets getInsets() {return insets;}
2 26 Feb 07 jari 261
2 26 Feb 07 jari 262     public void setInsets(Insets i) {
2 26 Feb 07 jari 263       this.insets = i;
2 26 Feb 07 jari 264     }    
2 26 Feb 07 jari 265     */
2 26 Feb 07 jari 266     private static int[] defSamplesOrder(int size) {
2 26 Feb 07 jari 267         int[] order = new int[size];
2 26 Feb 07 jari 268         for (int i=0; i<order.length; i++) {
2 26 Feb 07 jari 269             order[i] = i;
2 26 Feb 07 jari 270         }
2 26 Feb 07 jari 271         return order;
2 26 Feb 07 jari 272     }
2 26 Feb 07 jari 273     
2 26 Feb 07 jari 274     private static int[][] defGenesOrder(int size) {
2 26 Feb 07 jari 275         int[][] order = new int[1][size];
2 26 Feb 07 jari 276         for (int i=0; i<order[0].length; i++) {
2 26 Feb 07 jari 277             order[0][i] = i;
2 26 Feb 07 jari 278         }
2 26 Feb 07 jari 279         return order;
2 26 Feb 07 jari 280     }
2 26 Feb 07 jari 281     
2 26 Feb 07 jari 282     /**
2 26 Feb 07 jari 283      * Sets the left margin for the viewer
2 26 Feb 07 jari 284      */
2 26 Feb 07 jari 285     public void setLeftInset(int leftMargin){
2 26 Feb 07 jari 286         insets.left = leftMargin;
2 26 Feb 07 jari 287         this.header.setLeftInset(leftMargin);
2 26 Feb 07 jari 288     }
2 26 Feb 07 jari 289     
2 26 Feb 07 jari 290     /**
2 26 Feb 07 jari 291      * Returns component to render the experiment header.
2 26 Feb 07 jari 292      */
2 26 Feb 07 jari 293     public JComponent getHeaderComponent() {
2 26 Feb 07 jari 294         return header;
2 26 Feb 07 jari 295     }
2 26 Feb 07 jari 296     
2 26 Feb 07 jari 297     /**
2 26 Feb 07 jari 298      * Returns component to render the experiment values.
2 26 Feb 07 jari 299      */
2 26 Feb 07 jari 300     public JComponent getContentComponent() {
2 26 Feb 07 jari 301         return this;
2 26 Feb 07 jari 302     }
2 26 Feb 07 jari 303     
2 26 Feb 07 jari 304     /**
2 26 Feb 07 jari 305      * Returns null.
2 26 Feb 07 jari 306      */
2 26 Feb 07 jari 307     public BufferedImage getImage() {
2 26 Feb 07 jari 308         return null;
2 26 Feb 07 jari 309     }
2 26 Feb 07 jari 310     
2 26 Feb 07 jari 311     /**
2 26 Feb 07 jari 312      * Returns a gradient image for positive values.
2 26 Feb 07 jari 313      */
2 26 Feb 07 jari 314     public BufferedImage getPosColorImage() {
2 26 Feb 07 jari 315         return posColorImage;
2 26 Feb 07 jari 316     }
2 26 Feb 07 jari 317     
2 26 Feb 07 jari 318     /**
2 26 Feb 07 jari 319      * Returns a gradient image for negative values.
2 26 Feb 07 jari 320      */
2 26 Feb 07 jari 321     public BufferedImage getNegColorImage() {
2 26 Feb 07 jari 322         return negColorImage;
2 26 Feb 07 jari 323     }
2 26 Feb 07 jari 324     
2 26 Feb 07 jari 325     /**
2 26 Feb 07 jari 326      * Returns a color assigned for a NaN value.
2 26 Feb 07 jari 327      */
2 26 Feb 07 jari 328     public Color getMissingColor() {
2 26 Feb 07 jari 329         return missingColor;
2 26 Feb 07 jari 330     }
2 26 Feb 07 jari 331     
2 26 Feb 07 jari 332     /**
2 26 Feb 07 jari 333      * Selects rows from start to end.
2 26 Feb 07 jari 334      */
2 26 Feb 07 jari 335     public void selectRows(int start, int end) {
2 26 Feb 07 jari 336         firstSelectedRow = start;
2 26 Feb 07 jari 337         lastSelectedRow  = end;
2 26 Feb 07 jari 338         repaint();
2 26 Feb 07 jari 339     }
2 26 Feb 07 jari 340     
2 26 Feb 07 jari 341     /**
2 26 Feb 07 jari 342      * Selects columns from start to end.
2 26 Feb 07 jari 343      */
2 26 Feb 07 jari 344     public void selectColumns(int start, int end) {
2 26 Feb 07 jari 345         firstSelectedColumn = start;
2 26 Feb 07 jari 346         lastSelectedColumn  = end;
2 26 Feb 07 jari 347         repaint();
2 26 Feb 07 jari 348     }
2 26 Feb 07 jari 349     
2 26 Feb 07 jari 350     /**
2 26 Feb 07 jari 351      * Initializes appropriate attributes of this viewer and its header.
2 26 Feb 07 jari 352      * @see IViewer#onSelected
2 26 Feb 07 jari 353      */
2 26 Feb 07 jari 354     public void onSelected(IFramework framework) {
2 26 Feb 07 jari 355         this.framework = framework;
2 26 Feb 07 jari 356         this.data = framework.getData();
2 26 Feb 07 jari 357         IDisplayMenu menu = framework.getDisplayMenu();
2 26 Feb 07 jari 358         useDoubleGradient = menu.getUseDoubleGradient();
2 26 Feb 07 jari 359         Integer userObject = (Integer)framework.getUserObject();
2 26 Feb 07 jari 360         setClusterIndex(userObject == null ? 0 : userObject.intValue());
2 26 Feb 07 jari 361         this.header.setClusterIndex(this.clusterIndex);
2 26 Feb 07 jari 362         labelIndex = menu.getLabelIndex();
2 26 Feb 07 jari 363         this.maxValue = menu.getMaxRatioScale();
2 26 Feb 07 jari 364         this.minValue = menu.getMinRatioScale();
2 26 Feb 07 jari 365         this.midValue = menu.getMidRatioValue();
2 26 Feb 07 jari 366         setElementSize(menu.getElementSize());
2 26 Feb 07 jari 367         setAntialiasing(menu.isAntiAliasing());
2 26 Feb 07 jari 368         setDrawBorders(menu.isDrawingBorder());
2 26 Feb 07 jari 369         if(showClusters)
2 26 Feb 07 jari 370             haveColorBar = areProbesColored();
2 26 Feb 07 jari 371         else
2 26 Feb 07 jari 372             haveColorBar = false;
2 26 Feb 07 jari 373         updateSize();        
2 26 Feb 07 jari 374         header.updateSizes(getSize().width, elementSize.width);
2 26 Feb 07 jari 375         header.setData(data);
2 26 Feb 07 jari 376         onMenuChanged(menu);
2 26 Feb 07 jari 377         //header.setValues(maxValue, minValue);
2 26 Feb 07 jari 378         header.setValues(minValue, midValue, maxValue);
2 26 Feb 07 jari 379         header.setAntiAliasing(menu.isAntiAliasing());
2 26 Feb 07 jari 380         header.updateSizes(getSize().width, elementSize.width);
2 26 Feb 07 jari 381         header.setUseDoubleGradient(useDoubleGradient);
2 26 Feb 07 jari 382     }
2 26 Feb 07 jari 383     
2 26 Feb 07 jari 384     /**
2 26 Feb 07 jari 385      * Updates appropriate attributes of this viewer and its header.
2 26 Feb 07 jari 386      * @see IViewer#onMenuChanged
2 26 Feb 07 jari 387      */
2 26 Feb 07 jari 388     public void onMenuChanged(IDisplayMenu menu) {
2 26 Feb 07 jari 389         setDrawBorders(menu.isDrawingBorder());
2 26 Feb 07 jari 390         this.maxValue = menu.getMaxRatioScale();
2 26 Feb 07 jari 391         this.minValue = menu.getMinRatioScale();
2 26 Feb 07 jari 392         this.midValue = menu.getMidRatioValue();
2 26 Feb 07 jari 393         this.posColorImage = menu.getPositiveGradientImage();
2 26 Feb 07 jari 394         this.negColorImage = menu.getNegativeGradientImage();
2 26 Feb 07 jari 395         this.useDoubleGradient = menu.getUseDoubleGradient();
2 26 Feb 07 jari 396         this.header.setNegAndPosColorImages(this.negColorImage, this.posColorImage);
2 26 Feb 07 jari 397         this.header.setUseDoubleGradient(useDoubleGradient);
2 26 Feb 07 jari 398         //header.setValues(maxValue, minValue);
2 26 Feb 07 jari 399         header.setValues(minValue, midValue, maxValue);
2 26 Feb 07 jari 400         if (this.elementSize.equals(menu.getElementSize()) &&
2 26 Feb 07 jari 401         labelIndex == menu.getLabelIndex() &&
2 26 Feb 07 jari 402         this.isAntiAliasing == menu.isAntiAliasing()) {
2 26 Feb 07 jari 403             return;
2 26 Feb 07 jari 404         }
2 26 Feb 07 jari 405         setElementSize(menu.getElementSize());
2 26 Feb 07 jari 406         setAntialiasing(menu.isAntiAliasing());
2 26 Feb 07 jari 407         labelIndex = menu.getLabelIndex();
2 26 Feb 07 jari 408         if(showClusters)
2 26 Feb 07 jari 409             haveColorBar = areProbesColored();
2 26 Feb 07 jari 410         else
2 26 Feb 07 jari 411             haveColorBar = false;
2 26 Feb 07 jari 412         updateSize();
2 26 Feb 07 jari 413         header.setAntiAliasing(menu.isAntiAliasing());
2 26 Feb 07 jari 414         header.updateSizes(getSize().width, elementSize.width);
2 26 Feb 07 jari 415     }
2 26 Feb 07 jari 416     
2 26 Feb 07 jari 417     /**
2 26 Feb 07 jari 418      * Sets data for this viewer and its header.
2 26 Feb 07 jari 419      * @see IViewer#onDataChanged
2 26 Feb 07 jari 420      */
2 26 Feb 07 jari 421     public void onDataChanged(IData data) {
2 26 Feb 07 jari 422         this.data = data;
2 26 Feb 07 jari 423         this.header.setData(data);
2 26 Feb 07 jari 424         if(showClusters)
2 26 Feb 07 jari 425             haveColorBar = areProbesColored();
2 26 Feb 07 jari 426         else
2 26 Feb 07 jari 427             haveColorBar = false;
2 26 Feb 07 jari 428         updateSize();
2 26 Feb 07 jari 429         repaint();
2 26 Feb 07 jari 430     }
2 26 Feb 07 jari 431     
2 26 Feb 07 jari 432     public void onDeselected() {}
2 26 Feb 07 jari 433     public void onClosed() {}
2 26 Feb 07 jari 434     
2 26 Feb 07 jari 435     /**
2 26 Feb 07 jari 436      * Sets cluster index to be displayed.
2 26 Feb 07 jari 437      */
2 26 Feb 07 jari 438     public void setClusterIndex(int clusterIndex) {
2 26 Feb 07 jari 439         this.clusterIndex = clusterIndex;
2 26 Feb 07 jari 440     }
2 26 Feb 07 jari 441     
2 26 Feb 07 jari 442     /**
2 26 Feb 07 jari 443      * Returns index of current cluster.
2 26 Feb 07 jari 444      */
2 26 Feb 07 jari 445     public int getClusterIndex() {
2 26 Feb 07 jari 446         return clusterIndex;
2 26 Feb 07 jari 447     }
2 26 Feb 07 jari 448     
2 26 Feb 07 jari 449     /**
2 26 Feb 07 jari 450      * Returns indices of current cluster.
2 26 Feb 07 jari 451      */
2 26 Feb 07 jari 452     public int[] getCluster() {
2 26 Feb 07 jari 453         return clusters[this.clusterIndex];
2 26 Feb 07 jari 454     }
2 26 Feb 07 jari 455     
2 26 Feb 07 jari 456     /**
2 26 Feb 07 jari 457      * Returns all the clusters.
2 26 Feb 07 jari 458      */
2 26 Feb 07 jari 459     public int[][] getClusters() {
2 26 Feb 07 jari 460         return clusters;
2 26 Feb 07 jari 461     }
2 26 Feb 07 jari 462     
2 26 Feb 07 jari 463     /**
2 26 Feb 07 jari 464      *  Returns the row (index) within the main iData which corresponds to
2 26 Feb 07 jari 465      *  the passed index to the clusters array
2 26 Feb 07 jari 466      */
2 26 Feb 07 jari 467     private int getMultipleArrayDataRow(int clusterArrayRow) {
2 26 Feb 07 jari 468         return experiment.getGeneIndexMappedToData(this.clusters[this.clusterIndex][clusterArrayRow]);
2 26 Feb 07 jari 469     }
2 26 Feb 07 jari 470     
2 26 Feb 07 jari 471     /**
2 26 Feb 07 jari 472      *  Returns the row index in the experiment's <code>FloatMatrix<\code>
2 26 Feb 07 jari 473      *  corresponding to the passed index to the clusters array
2 26 Feb 07 jari 474      */
2 26 Feb 07 jari 475     private int getExperimentRow(int row){
2 26 Feb 07 jari 476         return this.clusters[this.clusterIndex][row];
2 26 Feb 07 jari 477     }
2 26 Feb 07 jari 478     
2 26 Feb 07 jari 479     private int getColumn(int column) {
2 26 Feb 07 jari 480         return samplesOrder[column];
2 26 Feb 07 jari 481     }
2 26 Feb 07 jari 482     
2 26 Feb 07 jari 483     /**
2 26 Feb 07 jari 484      * Returns wrapped experiment.
2 26 Feb 07 jari 485      */
2 26 Feb 07 jari 486     public Experiment getExperiment() {
2 26 Feb 07 jari 487         return experiment;
2 26 Feb 07 jari 488     }
2 26 Feb 07 jari 489     
2 26 Feb 07 jari 490     /**
2 26 Feb 07 jari 491      * Returns the data.
2 26 Feb 07 jari 492      */
2 26 Feb 07 jari 493     public IData getData() {
2 26 Feb 07 jari 494         return data;
2 26 Feb 07 jari 495     }
2 26 Feb 07 jari 496     
2 26 Feb 07 jari 497     /**
2 26 Feb 07 jari 498      * returns true if a probe in the current viewer has color
2 26 Feb 07 jari 499      */
2 26 Feb 07 jari 500     protected  boolean areProbesColored() {
2 26 Feb 07 jari 501         int [] indices = this.getCluster();
2 26 Feb 07 jari 502         for(int i = 0; i < indices.length; i++){
2 26 Feb 07 jari 503             if( this.data.getProbeColor(this.getMultipleArrayDataRow(i)) != null){
2 26 Feb 07 jari 504                 return true;
2 26 Feb 07 jari 505             }
2 26 Feb 07 jari 506         }
2 26 Feb 07 jari 507         return false;
2 26 Feb 07 jari 508     }
2 26 Feb 07 jari 509     
2 26 Feb 07 jari 510     /**
2 26 Feb 07 jari 511      * Sets public color for the current cluster.
2 26 Feb 07 jari 512      */
2 26 Feb 07 jari 513     public void setClusterColor(Color color) {
2 26 Feb 07 jari 514         if(color ==null){  //indicates removal of cluster
2 26 Feb 07 jari 515             framework.removeCluster(getIDataRowIndices(getCluster()), experiment, ClusterRepository.GENE_CLUSTER);
2 26 Feb 07 jari 516         }
2 26 Feb 07 jari 517     }
2 26 Feb 07 jari 518     
2 26 Feb 07 jari 519     /**
2 26 Feb 07 jari 520      *  Sets cluster color
2 26 Feb 07 jari 521      */
2 26 Feb 07 jari 522     public void storeCluster(){
2 26 Feb 07 jari 523         framework.storeCluster(getIDataRowIndices(getCluster()), experiment, ClusterRepository.GENE_CLUSTER);
2 26 Feb 07 jari 524         onDataChanged(this.data);
2 26 Feb 07 jari 525         updateSize();
2 26 Feb 07 jari 526     }
2 26 Feb 07 jari 527     
2 26 Feb 07 jari 528     /**
2 26 Feb 07 jari 529      * Sets public color for the current cluster related to genes or experiment indices.
2 26 Feb 07 jari 530      */
2 26 Feb 07 jari 531     public Color setHCLClusterColor(int [] clusterIndices, Color color, boolean areGeneIndices) {
2 26 Feb 07 jari 532         Color clusterColor = null;
2 26 Feb 07 jari 533         if(areGeneIndices)
2 26 Feb 07 jari 534             clusterColor = framework.storeSubCluster(clusterIndices, experiment, ClusterRepository.GENE_CLUSTER);
2 26 Feb 07 jari 535         else
2 26 Feb 07 jari 536             clusterColor = framework.storeSubCluster(clusterIndices, experiment, ClusterRepository.EXPERIMENT_CLUSTER);
2 26 Feb 07 jari 537         
2 26 Feb 07 jari 538         this.selectColumns(-1,-1);
2 26 Feb 07 jari 539         this.selectRows(-1,-1);
2 26 Feb 07 jari 540         header.updateSizes(getSize().width, elementSize.width);
2 26 Feb 07 jari 541         this.header.repaint();
2 26 Feb 07 jari 542         updateSize();
2 26 Feb 07 jari 543         this.repaint();
2 26 Feb 07 jari 544         
2 26 Feb 07 jari 545         return clusterColor;
2 26 Feb 07 jari 546     }
2 26 Feb 07 jari 547     
2 26 Feb 07 jari 548     /**
2 26 Feb 07 jari 549      * Converts cluster indicies from the experiment to IData rows which could be different
2 26 Feb 07 jari 550      */
2 26 Feb 07 jari 551     private int [] getIDataRowIndices(int [] expIndices){
2 26 Feb 07 jari 552         int [] dataIndices = new int[expIndices.length];
2 26 Feb 07 jari 553         for(int i = 0; i < expIndices.length; i++){
2 26 Feb 07 jari 554             dataIndices[i] = this.getMultipleArrayDataRow(i);
2 26 Feb 07 jari 555         }
2 26 Feb 07 jari 556         return dataIndices;
2 26 Feb 07 jari 557     }
2 26 Feb 07 jari 558     
2 26 Feb 07 jari 559     /**
2 26 Feb 07 jari 560      * Saves all the clusters.
2 26 Feb 07 jari 561      */
2 26 Feb 07 jari 562     public void saveClusters(Frame frame) throws Exception {
2 26 Feb 07 jari 563         frame = frame == null ? JOptionPane.getFrameForComponent(this) : frame;
2 26 Feb 07 jari 564         ExperimentUtil.saveExperiment(frame, getExperiment(), getData(), getClusters());
2 26 Feb 07 jari 565     }
2 26 Feb 07 jari 566     
2 26 Feb 07 jari 567     /**
2 26 Feb 07 jari 568      * Saves current cluster.
2 26 Feb 07 jari 569      */
2 26 Feb 07 jari 570     public void saveCluster(Frame frame) throws Exception {
2 26 Feb 07 jari 571         frame = frame == null ? JOptionPane.getFrameForComponent(this) : frame;
2 26 Feb 07 jari 572         ExperimentUtil.saveExperiment(frame, getExperiment(), getData(), getCluster());
2 26 Feb 07 jari 573     }
2 26 Feb 07 jari 574     
2 26 Feb 07 jari 575     /**
2 26 Feb 07 jari 576      * Launches a new <code>MultipleExperimentViewer</code> containing the current cluster
2 26 Feb 07 jari 577      */
2 26 Feb 07 jari 578     public void launchNewSession(){
2 26 Feb 07 jari 579         framework.launchNewMAV(getIDataRowIndices(getCluster()), this.experiment, "Multiple Experiment Viewer - Cluster Viewer", Cluster.GENE_CLUSTER);
2 26 Feb 07 jari 580     }
2 26 Feb 07 jari 581     
2 26 Feb 07 jari 582     /**
2 26 Feb 07 jari 583      * Sets a shape size.
2 26 Feb 07 jari 584      */
2 26 Feb 07 jari 585     private void setElementSize(Dimension elementSize) {
2 26 Feb 07 jari 586         this.elementSize = new Dimension(elementSize);
2 26 Feb 07 jari 587     }
2 26 Feb 07 jari 588     
2 26 Feb 07 jari 589     /**
2 26 Feb 07 jari 590      * Sets anti-aliasing attribute.
2 26 Feb 07 jari 591      */
2 26 Feb 07 jari 592     private void setAntialiasing(boolean value) {
2 26 Feb 07 jari 593         this.isAntiAliasing = value;
2 26 Feb 07 jari 594     }
2 26 Feb 07 jari 595     
2 26 Feb 07 jari 596     /**
2 26 Feb 07 jari 597      * Sets draw borders attribute.
2 26 Feb 07 jari 598      */
2 26 Feb 07 jari 599     private void setDrawBorders(boolean value) {
2 26 Feb 07 jari 600         this.isDrawBorders = value;
2 26 Feb 07 jari 601     }
2 26 Feb 07 jari 602     
2 26 Feb 07 jari 603     /**
2 26 Feb 07 jari 604      * Creates a gradient image with specified initial colors.
2 26 Feb 07 jari 605      */
2 26 Feb 07 jari 606     public BufferedImage createGradientImage(Color color1, Color color2) {
2 26 Feb 07 jari 607         BufferedImage image = (BufferedImage)java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(256,1);
2 26 Feb 07 jari 608         Graphics2D graphics = image.createGraphics();
2 26 Feb 07 jari 609         GradientPaint gp = new GradientPaint(0, 0, color1, 255, 0, color2);
2 26 Feb 07 jari 610         graphics.setPaint(gp);
2 26 Feb 07 jari 611         graphics.drawRect(0, 0, 255, 1);
2 26 Feb 07 jari 612         return image;
2 26 Feb 07 jari 613     }
2 26 Feb 07 jari 614     
2 26 Feb 07 jari 615     /**
2 26 Feb 07 jari 616      * Updates size of this viewer.
2 26 Feb 07 jari 617      */
2 26 Feb 07 jari 618     private void updateSize() {
2 26 Feb 07 jari 619         if (this.clusters == null || getCluster().length == 0) {
2 26 Feb 07 jari 620             setFont(ERROR_FONT);
2 26 Feb 07 jari 621             Graphics2D g = (Graphics2D)getGraphics();
2 26 Feb 07 jari 622             FontMetrics metrics = g.getFontMetrics();
2 26 Feb 07 jari 623             int width = metrics.stringWidth(NO_GENES_STR)+10;
2 26 Feb 07 jari 624             int height = metrics.getHeight()+30;
2 26 Feb 07 jari 625             setSize(width, height);
2 26 Feb 07 jari 626             setPreferredSize(new Dimension(width, height));
2 26 Feb 07 jari 627             return;
2 26 Feb 07 jari 628         }
2 26 Feb 07 jari 629         setFont(new Font("monospaced", Font.PLAIN, elementSize.height));
2 26 Feb 07 jari 630         Graphics2D g = (Graphics2D)getGraphics();
2 26 Feb 07 jari 631         int width = elementSize.width*experiment.getNumberOfSamples() + 1 + insets.left;
2 26 Feb 07 jari 632         if (isDrawAnnotations) {
2 26 Feb 07 jari 633             this.annotationWidth = getMaxWidth(g);
2 26 Feb 07 jari 634             width += 20+this.annotationWidth;
2 26 Feb 07 jari 635         }
2 26 Feb 07 jari 636         
2 26 Feb 07 jari 637         if(haveColorBar)
2 26 Feb 07 jari 638             width += this.elementSize.width + 10;
2 26 Feb 07 jari 639         
2 26 Feb 07 jari 640         this.contentWidth = width;
2 26 Feb 07 jari 641         
2 26 Feb 07 jari 642         int height = elementSize.height*getCluster().length+1;
2 26 Feb 07 jari 643         setSize(width, height);
2 26 Feb 07 jari 644         setPreferredSize(new Dimension(width, height));
2 26 Feb 07 jari 645     }
2 26 Feb 07 jari 646     
2 26 Feb 07 jari 647     /**
2 26 Feb 07 jari 648      * Returns max width of annotation strings.
2 26 Feb 07 jari 649      */
2 26 Feb 07 jari 650     private int getMaxWidth(Graphics2D g) {
2 26 Feb 07 jari 651         if (g == null || data == null || getCluster() == null) {
2 26 Feb 07 jari 652             return 0;
2 26 Feb 07 jari 653         }
2 26 Feb 07 jari 654         if (isAntiAliasing) {
2 26 Feb 07 jari 655             g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
2 26 Feb 07 jari 656             g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
2 26 Feb 07 jari 657         }
2 26 Feb 07 jari 658         FontMetrics fm = g.getFontMetrics();
2 26 Feb 07 jari 659         int max = 0;
2 26 Feb 07 jari 660         String str;
2 26 Feb 07 jari 661         for (int i=0; i<getCluster().length; i++) {
2 26 Feb 07 jari 662             str = data.getElementAttribute(getMultipleArrayDataRow(i), labelIndex);
2 26 Feb 07 jari 663             // str = genename ? data.getGeneName(getMultipleArrayDataRow(i)) : data.getUniqueId(getMultipleArrayDataRow(i));
2 26 Feb 07 jari 664             max = Math.max(max, fm.stringWidth(str));
2 26 Feb 07 jari 665         }
2 26 Feb 07 jari 666         return max;
2 26 Feb 07 jari 667     }
2 26 Feb 07 jari 668     
2 26 Feb 07 jari 669     /**
2 26 Feb 07 jari 670      * Returns content width
2 26 Feb 07 jari 671      */
2 26 Feb 07 jari 672     public int getContentWidth(){
2 26 Feb 07 jari 673         return contentWidth;
2 26 Feb 07 jari 674     }
2 26 Feb 07 jari 675
2 26 Feb 07 jari 676     
2 26 Feb 07 jari 677     /**
2 26 Feb 07 jari 678      * Calculates color for passed value.
2 26 Feb 07 jari 679      */
2 26 Feb 07 jari 680     /*
2 26 Feb 07 jari 681       
2 26 Feb 07 jari 682      private Color getColor(float value) {
2 26 Feb 07 jari 683         if (Float.isNaN(value)) {
2 26 Feb 07 jari 684             return missingColor;
2 26 Feb 07 jari 685         }
2 26 Feb 07 jari 686         
2 26 Feb 07 jari 687         float maximum;
2 26 Feb 07 jari 688         int colorIndex, rgb;
2 26 Feb 07 jari 689         
2 26 Feb 07 jari 690         if(useDoubleGradient) {
2 26 Feb 07 jari 691           maximum = value < 0 ? this.minValue : this.maxValue;
2 26 Feb 07 jari 692       colorIndex = (int) (255 * value / maximum);
2 26 Feb 07 jari 693       colorIndex = colorIndex > 255 ? 255 : colorIndex;
2 26 Feb 07 jari 694       rgb = value < 0 ? negColorImage.getRGB(255 - colorIndex, 0)
2 26 Feb 07 jari 695           : posColorImage.getRGB(colorIndex, 0);
2 26 Feb 07 jari 696         } else {
2 26 Feb 07 jari 697           float span = this.maxValue - this.minValue;
2 26 Feb 07 jari 698           if(value <= minValue)
2 26 Feb 07 jari 699             colorIndex = 0;
2 26 Feb 07 jari 700           else if(value >= maxValue)
2 26 Feb 07 jari 701             colorIndex = 255;
2 26 Feb 07 jari 702           else
2 26 Feb 07 jari 703             colorIndex = (int)(((value - this.minValue)/span) * 255);
2 26 Feb 07 jari 704            
2 26 Feb 07 jari 705           rgb = posColorImage.getRGB(colorIndex,0);
2 26 Feb 07 jari 706         }
2 26 Feb 07 jari 707         return new Color(rgb);
2 26 Feb 07 jari 708     }
2 26 Feb 07 jari 709     */
2 26 Feb 07 jari 710     
2 26 Feb 07 jari 711     private Color getColor(float value) {
2 26 Feb 07 jari 712         if (Float.isNaN(value)) {
2 26 Feb 07 jari 713             return missingColor;
2 26 Feb 07 jari 714         }
2 26 Feb 07 jari 715         
2 26 Feb 07 jari 716         float maximum;
2 26 Feb 07 jari 717         int colorIndex, rgb;
2 26 Feb 07 jari 718         
2 26 Feb 07 jari 719         if(useDoubleGradient) {
2 26 Feb 07 jari 720           maximum = value < midValue ? this.minValue : this.maxValue;
2 26 Feb 07 jari 721       colorIndex = (int) (255 * (value-midValue) / (maximum - midValue));
2 26 Feb 07 jari 722       colorIndex = colorIndex > 255 ? 255 : colorIndex;
2 26 Feb 07 jari 723       rgb = value < midValue ? negColorImage.getRGB(255 - colorIndex, 0)
2 26 Feb 07 jari 724           : posColorImage.getRGB(colorIndex, 0);
2 26 Feb 07 jari 725         } else {
2 26 Feb 07 jari 726           float span = this.maxValue - this.minValue;
2 26 Feb 07 jari 727           if(value <= minValue)
2 26 Feb 07 jari 728             colorIndex = 0;
2 26 Feb 07 jari 729           else if(value >= maxValue)
2 26 Feb 07 jari 730             colorIndex = 255;
2 26 Feb 07 jari 731           else
2 26 Feb 07 jari 732             colorIndex = (int)(((value - this.minValue)/span) * 255);
2 26 Feb 07 jari 733            
2 26 Feb 07 jari 734           rgb = posColorImage.getRGB(colorIndex,0);
2 26 Feb 07 jari 735         }
2 26 Feb 07 jari 736         return new Color(rgb);
2 26 Feb 07 jari 737     }
2 26 Feb 07 jari 738     
2 26 Feb 07 jari 739     /**
2 26 Feb 07 jari 740      * Paint component into specified graphics.
2 26 Feb 07 jari 741      */
2 26 Feb 07 jari 742     public void paint(Graphics g) {
2 26 Feb 07 jari 743         super.paint(g);
2 26 Feb 07 jari 744         
2 26 Feb 07 jari 745         if (this.data == null) {
2 26 Feb 07 jari 746             return;
2 26 Feb 07 jari 747         }
2 26 Feb 07 jari 748         if(this.elementSize.getHeight() < 1)
2 26 Feb 07 jari 749             return;
2 26 Feb 07 jari 750         final int samples = experiment.getNumberOfSamples();
2 26 Feb 07 jari 751         
2 26 Feb 07 jari 752         
2 26 Feb 07 jari 753         if (this.clusters == null || getCluster().length == 0) {
2 26 Feb 07 jari 754             g.setColor(new Color(0, 0, 128));
2 26 Feb 07 jari 755             g.setFont(ERROR_FONT);
2 26 Feb 07 jari 756             g.drawString(NO_GENES_STR, 10, 30);
2 26 Feb 07 jari 757             return;
2 26 Feb 07 jari 758         }
2 26 Feb 07 jari 759         
2 26 Feb 07 jari 760         Rectangle bounds = g.getClipBounds();
2 26 Feb 07 jari 761         final int top = getTopIndex(bounds.y);
2 26 Feb 07 jari 762         final int bottom = getBottomIndex(bounds.y+bounds.height, getCluster().length);
2 26 Feb 07 jari 763         final int left = getLeftIndex(bounds.x);
2 26 Feb 07 jari 764         final int right = getRightIndex(bounds.x+bounds.width, samples);
2 26 Feb 07 jari 765         
2 26 Feb 07 jari 766         int x, y;
2 26 Feb 07 jari 767         // draw rectangles
2 26 Feb 07 jari 768         for (int column=left; column<right; column++) {
2 26 Feb 07 jari 769             for (int row=top; row<bottom; row++) {
2 26 Feb 07 jari 770                 fillRectAt(g, row, column);
2 26 Feb 07 jari 771             }
2 26 Feb 07 jari 772         }
2 26 Feb 07 jari 773         Color initColor = g.getColor();
2 26 Feb 07 jari 774         
2 26 Feb 07 jari 775         int expWidth = samples * this.elementSize.width + 5;
2 26 Feb 07 jari 776         
2 26 Feb 07 jari 777         if(haveColorBar){
2 26 Feb 07 jari 778             for (int row=top; row<bottom; row++) {
2 26 Feb 07 jari 779                 fillClusterRectAt(g, row, expWidth);
2 26 Feb 07 jari 780             }
2 26 Feb 07 jari 781         }
2 26 Feb 07 jari 782         
2 26 Feb 07 jari 783         // draw annotations
2 26 Feb 07 jari 784         if (this.isDrawAnnotations) {
2 26 Feb 07 jari 785             if (this.isAntiAliasing) {
2 26 Feb 07 jari 786                 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
2 26 Feb 07 jari 787                 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
2 26 Feb 07 jari 788             }
2 26 Feb 07 jari 789             if (right >= samples) {
2 26 Feb 07 jari 790                 String label = "";
2 26 Feb 07 jari 791                 g.setColor(Color.black);
2 26 Feb 07 jari 792                 int uniqX = elementSize.width*samples+10;
2 26 Feb 07 jari 793                 
2 26 Feb 07 jari 794                 if(haveColorBar)
2 26 Feb 07 jari 795                     uniqX += this.elementSize.width;
2 26 Feb 07 jari 796                 
2 26 Feb 07 jari 797                 int annY;
2 26 Feb 07 jari 798                 for (int row=top; row<bottom; row++) {
2 26 Feb 07 jari 799                     if (labelIndex >= 0) {
2 26 Feb 07 jari 800                         label = data.getElementAttribute(getMultipleArrayDataRow(row), labelIndex);
2 26 Feb 07 jari 801                     }
2 26 Feb 07 jari 802                     annY = (row+1)*elementSize.height;
2 26 Feb 07 jari 803                     g.drawString(label, uniqX + insets.left, annY);
2 26 Feb 07 jari 804                 }
2 26 Feb 07 jari 805             }
2 26 Feb 07 jari 806         }
2 26 Feb 07 jari 807     }
2 26 Feb 07 jari 808     
2 26 Feb 07 jari 809     /**
2 26 Feb 07 jari 810      * Fills rect with specified row and colunn.
2 26 Feb 07 jari 811      */
2 26 Feb 07 jari 812     private void fillRectAt(Graphics g, int row, int column) {
2 26 Feb 07 jari 813         int x = column*elementSize.width + insets.left;
2 26 Feb 07 jari 814         int y = row*elementSize.height;
2 26 Feb 07 jari 815         boolean mask = this.firstSelectedRow >= 0 && this.lastSelectedRow >= 0 && (row < this.firstSelectedRow || row > this.lastSelectedRow);
2 26 Feb 07 jari 816         mask = (mask || this.firstSelectedColumn >= 0 && this.lastSelectedColumn >= 0 && (column < this.firstSelectedColumn || column > this.lastSelectedColumn));
2 26 Feb 07 jari 817         
2 26 Feb 07 jari 818         g.setColor(getColor(this.experiment.get(getExperimentRow(row), getColumn(column))));
2 26 Feb 07 jari 819         g.fillRect(x, y, elementSize.width, elementSize.height);
2 26 Feb 07 jari 820         if (mask) {
2 26 Feb 07 jari 821             g.setColor(maskColor);
2 26 Feb 07 jari 822             g.fillRect(x, y, elementSize.width, elementSize.height);
2 26 Feb 07 jari 823         }
2 26 Feb 07 jari 824         if (this.isDrawBorders) {
2 26 Feb 07 jari 825             g.setColor(Color.black);
2 26 Feb 07 jari 826             g.drawRect(x, y, elementSize.width-1, elementSize.height-1);
2 26 Feb 07 jari 827         }
2 26 Feb 07 jari 828     }
2 26 Feb 07 jari 829     
2 26 Feb 07 jari 830     /**
2 26 Feb 07 jari 831      * fills cluster colors
2 26 Feb 07 jari 832      */
2 26 Feb 07 jari 833     private void fillClusterRectAt(Graphics g, int row, int xLoc) {
2 26 Feb 07 jari 834         Color geneColor = data.getProbeColor(getMultipleArrayDataRow(row));
2 26 Feb 07 jari 835         if(geneColor == null)
2 26 Feb 07 jari 836             geneColor = Color.white;
2 26 Feb 07 jari 837         
2 26 Feb 07 jari 838         g.setColor(geneColor);
2 26 Feb 07 jari 839         g.fillRect(xLoc + insets.left, row*elementSize.height, elementSize.width-1, elementSize.height);
2 26 Feb 07 jari 840     }
2 26 Feb 07 jari 841     
2 26 Feb 07 jari 842     /**
2 26 Feb 07 jari 843      * Draws rect with specified row, column and color.
2 26 Feb 07 jari 844      */
2 26 Feb 07 jari 845     private void drawRectAt(Graphics g, int row, int column, Color color) {
2 26 Feb 07 jari 846         g.setColor(color);
2 26 Feb 07 jari 847         g.drawRect(column*elementSize.width + insets.left, row*elementSize.height, elementSize.width-1, elementSize.height-1);
2 26 Feb 07 jari 848     }
2 26 Feb 07 jari 849     
2 26 Feb 07 jari 850     private int getTopIndex(int top) {
2 26 Feb 07 jari 851         if (top < 0) {
2 26 Feb 07 jari 852             return 0;
2 26 Feb 07 jari 853         }
2 26 Feb 07 jari 854         return top/elementSize.height;
2 26 Feb 07 jari 855     }
2 26 Feb 07 jari 856     
2 26 Feb 07 jari 857     private int getLeftIndex(int left) {
2 26 Feb 07 jari 858         if (left < insets.left) {
2 26 Feb 07 jari 859             return 0;
2 26 Feb 07 jari 860         }
2 26 Feb 07 jari 861         return (left - insets.left)/elementSize.width;
2 26 Feb 07 jari 862     }
2 26 Feb 07 jari 863     
2 26 Feb 07 jari 864     private int getRightIndex(int right, int limit) {
2 26 Feb 07 jari 865         if (right < 0) {
2 26 Feb 07 jari 866             return 0;
2 26 Feb 07 jari 867         }
2 26 Feb 07 jari 868         int result = right/elementSize.width+1;
2 26 Feb 07 jari 869         return result > limit ? limit : result;
2 26 Feb 07 jari 870     }
2 26 Feb 07 jari 871     
2 26 Feb 07 jari 872     private int getBottomIndex(int bottom, int limit) {
2 26 Feb 07 jari 873         if (bottom < 0) {
2 26 Feb 07 jari 874             return 0;
2 26 Feb 07 jari 875         }
2 26 Feb 07 jari 876         int result = bottom/elementSize.height+1;
2 26 Feb 07 jari 877         return result > limit ? limit : result;
2 26 Feb 07 jari 878     }
2 26 Feb 07 jari 879     
2 26 Feb 07 jari 880     /**
2 26 Feb 07 jari 881      * Finds column for specified x coordinate.
2 26 Feb 07 jari 882      * @return -1 if column was not found.
2 26 Feb 07 jari 883      */
2 26 Feb 07 jari 884     private int findColumn(int targetx) {
2 26 Feb 07 jari 885         int xSize = experiment.getNumberOfSamples()*elementSize.width;
2 26 Feb 07 jari 886         if (targetx >= (xSize + insets.left) || targetx < insets.left) {
2 26 Feb 07 jari 887             return -1;
2 26 Feb 07 jari 888         }
2 26 Feb 07 jari 889         return (targetx - insets.left)/elementSize.width;
2 26 Feb 07 jari 890     }
2 26 Feb 07 jari 891     
2 26 Feb 07 jari 892     /**
2 26 Feb 07 jari 893      * Finds row for specified y coordinate.
2 26 Feb 07 jari 894      * @return -1 if row was not found.
2 26 Feb 07 jari 895      */
2 26 Feb 07 jari 896     private int findRow(int targety) {
2 26 Feb 07 jari 897         int ySize = getCluster().length*elementSize.height;
2 26 Feb 07 jari 898         if (targety >= ySize || targety < 0)
2 26 Feb 07 jari 899             return -1;
2 26 Feb 07 jari 900         return targety/elementSize.height;
2 26 Feb 07 jari 901     }
2 26 Feb 07 jari 902     
2 26 Feb 07 jari 903     private boolean isLegalPosition(int row, int column) {
2 26 Feb 07 jari 904         if (isLegalRow(row) && isLegalColumn(column))
2 26 Feb 07 jari 905             return true;
2 26 Feb 07 jari 906         return false;
2 26 Feb 07 jari 907     }
2 26 Feb 07 jari 908     
2 26 Feb 07 jari 909     private boolean isLegalColumn(int column) {
2 26 Feb 07 jari 910         if (column < 0 || column > experiment.getNumberOfSamples() -1)
2 26 Feb 07 jari 911             return false;
2 26 Feb 07 jari 912         return true;
2 26 Feb 07 jari 913     }
2 26 Feb 07 jari 914     
2 26 Feb 07 jari 915     private boolean isLegalRow(int row) {
2 26 Feb 07 jari 916         if (row < 0 || row > getCluster().length -1)
2 26 Feb 07 jari 917             return false;
2 26 Feb 07 jari 918         return true;
2 26 Feb 07 jari 919     }
2 26 Feb 07 jari 920     
2 26 Feb 07 jari 921     /**
2 26 Feb 07 jari 922      * Adds viewer specific menu items.
2 26 Feb 07 jari 923      */
2 26 Feb 07 jari 924     protected void addMenuItems(JPopupMenu menu, ActionListener listener) {
2 26 Feb 07 jari 925         JMenuItem menuItem;
2 26 Feb 07 jari 926         menuItem = new JMenuItem("Store cluster", GUIFactory.getIcon("new16.gif"));
2 26 Feb 07 jari 927         menuItem.setActionCommand(STORE_CLUSTER_CMD);
2 26 Feb 07 jari 928         menuItem.addActionListener(listener);
2 26 Feb 07 jari 929         menu.add(menuItem);
2 26 Feb 07 jari 930         
2 26 Feb 07 jari 931         menu.addSeparator();
2 26 Feb 07 jari 932         
2 26 Feb 07 jari 933         menuItem = new JMenuItem("Launch new session", GUIFactory.getIcon("launch_new_mav.gif"));
2 26 Feb 07 jari 934         menuItem.setActionCommand(LAUNCH_NEW_SESSION_CMD);
2 26 Feb 07 jari 935         menuItem.addActionListener(listener);
2 26 Feb 07 jari 936         menu.add(menuItem);
2 26 Feb 07 jari 937         
2 26 Feb 07 jari 938         menu.addSeparator();
2 26 Feb 07 jari 939         
2 26 Feb 07 jari 940         menuItem = new JMenuItem("Delete public cluster", GUIFactory.getIcon("delete16.gif"));
2 26 Feb 07 jari 941         menuItem.setActionCommand(SET_DEF_COLOR_CMD);
2 26 Feb 07 jari 942         menuItem.addActionListener(listener);
2 26 Feb 07 jari 943         menu.add(menuItem);
2 26 Feb 07 jari 944         
2 26 Feb 07 jari 945         menu.addSeparator();
2 26 Feb 07 jari 946         
2 26 Feb 07 jari 947         menuItem = new JMenuItem("Save cluster...", GUIFactory.getIcon("save16.gif"));
2 26 Feb 07 jari 948         menuItem.setActionCommand(SAVE_CLUSTER_CMD);
2 26 Feb 07 jari 949         menuItem.addActionListener(listener);
2 26 Feb 07 jari 950         menu.add(menuItem);
2 26 Feb 07 jari 951         
2 26 Feb 07 jari 952         menuItem = new JMenuItem("Save all clusters...", GUIFactory.getIcon("save16.gif"));
2 26 Feb 07 jari 953         menuItem.setActionCommand(SAVE_ALL_CLUSTERS_CMD);
2 26 Feb 07 jari 954         menuItem.addActionListener(listener);
2 26 Feb 07 jari 955         menu.add(menuItem);
2 26 Feb 07 jari 956     }
2 26 Feb 07 jari 957     
2 26 Feb 07 jari 958     /** Returns a component to be inserted into the scroll pane row header
2 26 Feb 07 jari 959      */
2 26 Feb 07 jari 960     public JComponent getRowHeaderComponent() {
2 26 Feb 07 jari 961         return null;
2 26 Feb 07 jari 962     }
2 26 Feb 07 jari 963     
2 26 Feb 07 jari 964     /** Returns the corner component corresponding to the indicated corner,
2 26 Feb 07 jari 965      * posibly null
2 26 Feb 07 jari 966      */
2 26 Feb 07 jari 967     public JComponent getCornerComponent(int cornerIndex) {
2 26 Feb 07 jari 968         return null;
2 26 Feb 07 jari 969     }
2 26 Feb 07 jari 970     
2 26 Feb 07 jari 971     
2 26 Feb 07 jari 972     
2 26 Feb 07 jari 973     /** Returns int value indicating viewer type
2 26 Feb 07 jari 974      * Cluster.GENE_CLUSTER, Cluster.EXPERIMENT_CLUSTER, or -1 for both or unspecified
2 26 Feb 07 jari 975      */
2 26 Feb 07 jari 976     public int getViewerType() {
2 26 Feb 07 jari 977         return Cluster.GENE_CLUSTER;
2 26 Feb 07 jari 978     }
2 26 Feb 07 jari 979     
2 26 Feb 07 jari 980     /**
2 26 Feb 07 jari 981      * The class to listen to mouse events.
2 26 Feb 07 jari 982      */
2 26 Feb 07 jari 983     private class Listener extends MouseAdapter implements MouseMotionListener {
2 26 Feb 07 jari 984         
2 26 Feb 07 jari 985         private String oldStatusText;
2 26 Feb 07 jari 986         private int oldRow = -1;
2 26 Feb 07 jari 987         private int oldColumn = -1;
2 26 Feb 07 jari 988         
2 26 Feb 07 jari 989         public void mouseClicked(MouseEvent event) {
2 26 Feb 07 jari 990             if (SwingUtilities.isRightMouseButton(event)) {
2 26 Feb 07 jari 991                 return;
2 26 Feb 07 jari 992             }
2 26 Feb 07 jari 993             int column = findColumn(event.getX());
2 26 Feb 07 jari 994             int row = findRow(event.getY());
2 26 Feb 07 jari 995             if (!isLegalPosition(row, column)) {
2 26 Feb 07 jari 996                 return;
2 26 Feb 07 jari 997             }
2 26 Feb 07 jari 998             if (event.isControlDown()) { // single array viewer
2 26 Feb 07 jari 999                 framework.displaySingleArrayViewer(experiment.getSampleIndex(getColumn(column)));
2 26 Feb 07 jari 1000                 return;
2 26 Feb 07 jari 1001             }
2 26 Feb 07 jari 1002             if (!event.isShiftDown()) { // element info
2 26 Feb 07 jari 1003                 framework.displaySlideElementInfo(experiment.getSampleIndex(getColumn(column)), getMultipleArrayDataRow(row));
2 26 Feb 07 jari 1004                 return;
2 26 Feb 07 jari 1005             }
2 26 Feb 07 jari 1006         }
2 26 Feb 07 jari 1007         
2 26 Feb 07 jari 1008         public void mouseMoved(MouseEvent event) {
2 26 Feb 07 jari 1009             if (experiment.getNumberOfSamples() == 0 || event.isShiftDown())
2 26 Feb 07 jari 1010                 return;
2 26 Feb 07 jari 1011             int column = findColumn(event.getX());
2 26 Feb 07 jari 1012             int row = findRow(event.getY());
2 26 Feb 07 jari 1013             if (isCurrentPosition(row, column)) {
2 26 Feb 07 jari 1014                 return;
2 26 Feb 07 jari 1015             }
2 26 Feb 07 jari 1016             Graphics g = null;
2 26 Feb 07 jari 1017             if (isLegalPosition(row, column)) {
2 26 Feb 07 jari 1018                 g = getGraphics();
2 26 Feb 07 jari 1019                 drawRectAt(g, row, column, Color.white);
2 26 Feb 07 jari 1020                 framework.setStatusText("Gene: "+data.getUniqueId(getMultipleArrayDataRow(row))+" Sample: "+data.getSampleName(experiment.getSampleIndex(getColumn(column)))+" Value: "+experiment.get(getExperimentRow(row), getColumn(column)));
2 26 Feb 07 jari 1021             } else {
2 26 Feb 07 jari 1022                 framework.setStatusText(oldStatusText);
2 26 Feb 07 jari 1023             }
2 26 Feb 07 jari 1024             if (isLegalPosition(oldRow, oldColumn)) {
2 26 Feb 07 jari 1025                 g = g != null ? g : getGraphics();
2 26 Feb 07 jari 1026                 fillRectAt(g, oldRow, oldColumn);
2 26 Feb 07 jari 1027             }
2 26 Feb 07 jari 1028             setOldPosition(row, column);
2 26 Feb 07 jari 1029             if (g != null) {
2 26 Feb 07 jari 1030                 g.dispose();
2 26 Feb 07 jari 1031             }
2 26 Feb 07 jari 1032         }
2 26 Feb 07 jari 1033         
2 26 Feb 07 jari 1034         public void mouseEntered(MouseEvent event) {
2 26 Feb 07 jari 1035           try {
2 26 Feb 07 jari 1036             oldStatusText = framework.getStatusText();
2 26 Feb 07 jari 1037           } catch (NullPointerException npe) {
2 26 Feb 07 jari 1038             npe.printStackTrace();
2 26 Feb 07 jari 1039           }
2 26 Feb 07 jari 1040         }
2 26 Feb 07 jari 1041         
2 26 Feb 07 jari 1042         public void mouseExited(MouseEvent event) {
2 26 Feb 07 jari 1043             if (isLegalPosition(oldRow, oldColumn)) {
2 26 Feb 07 jari 1044                 Graphics g = getGraphics();
2 26 Feb 07 jari 1045                 fillRectAt(g, oldRow, oldColumn);
2 26 Feb 07 jari 1046                 g.dispose();
2 26 Feb 07 jari 1047             }
2 26 Feb 07 jari 1048             setOldPosition(-1, -1);
2 26 Feb 07 jari 1049             framework.setStatusText(oldStatusText);
2 26 Feb 07 jari 1050         }
2 26 Feb 07 jari 1051         
2 26 Feb 07 jari 1052         public void mouseDragged(MouseEvent event) {}
2 26 Feb 07 jari 1053         
2 26 Feb 07 jari 1054         private void setOldPosition(int row, int column) {
2 26 Feb 07 jari 1055             oldColumn = column;
2 26 Feb 07 jari 1056             oldRow = row;
2 26 Feb 07 jari 1057         }
2 26 Feb 07 jari 1058         
2 26 Feb 07 jari 1059         private boolean isCurrentPosition(int row, int column) {
2 26 Feb 07 jari 1060             return(row == oldRow && column == oldColumn);
2 26 Feb 07 jari 1061         }
2 26 Feb 07 jari 1062     }
2 26 Feb 07 jari 1063     
2 26 Feb 07 jari 1064   /* (non-Javadoc)
2 26 Feb 07 jari 1065    * @see org.tigr.microarray.mev.cluster.gui.IViewer#getExperimentID()
2 26 Feb 07 jari 1066    */
2 26 Feb 07 jari 1067   public int getExperimentID() {
2 26 Feb 07 jari 1068     return exptID;
2 26 Feb 07 jari 1069   }
2 26 Feb 07 jari 1070   /* (non-Javadoc)
2 26 Feb 07 jari 1071    * @see org.tigr.microarray.mev.cluster.gui.IViewer#setExperimentID(int)
2 26 Feb 07 jari 1072    */
2 26 Feb 07 jari 1073   public void setExperimentID(int id) {
2 26 Feb 07 jari 1074     this.exptID = id;
2 26 Feb 07 jari 1075     
2 26 Feb 07 jari 1076   }
2 26 Feb 07 jari 1077
2 26 Feb 07 jari 1078 }