View Javadoc

    1   package baseCode.gui;
    2
    3   import java.awt.Color;
    4   import java.awt.Dimension;
    5   import java.awt.Font;
    6   import java.awt.Graphics;
    7   import java.awt.Graphics2D;
    8   import java.awt.image.BufferedImage;
    9   import java.io.File;
    10  import java.io.IOException;
    11
    12  import javax.imageio.ImageIO;
    13  import javax.swing.JPanel;
    14
    15  import baseCode.dataStructure.matrix.AbstractNamedDoubleMatrix;
    16  import baseCode.dataStructure.matrix.DenseDoubleMatrix2DNamed;
    17  import baseCode.graphics.text.Util;
    18
    19  /***
    20   * <p>
    21   * Title: JMatrixDisplay
    22   * </p>
    23   * <p>
    24   * Description: a visual component for displaying a color matrix
    25   * </p>
    26   * <p>
    27   * Copyright: Copyright (c) 2004
    28   * </p>
    29   * <p>
    30   * Institution:: Columbia University
    31   * </p>
    32   *
    33   * @author Will Braynen
    34   * @version $Id: JMatrixDisplay.java,v 1.39 2004/09/20 22:19:02 pavlidis Exp $
    35   */
    36  public class JMatrixDisplay extends JPanel {
    37
    38     // data fields
    39     ColorMatrix m_matrix; // reference to standardized or unstandardized matrix
    40     ColorMatrix m_unstandardizedMatrix;
    41     ColorMatrix m_standardizedMatrix;
    42     boolean m_isShowingStandardizedMatrix = false;
    43
    44     protected boolean m_isShowLabels = false;
    45     protected BufferedImage m_image = null;
    46
    47     protected int m_ratioWidth = 0;
    48     protected int m_rowLabelWidth; // max
    49     protected int m_columnLabelHeight; // max
    50     protected int m_labelGutter = 5;
    51     protected int m_fontGutter;
    52     protected Font m_labelFont = null;
    53     protected int m_fontSize = 10;
    54     protected final int m_maxFontSize = 10;
    55     protected final int m_defaultResolution = 120;
    56     protected int m_resolution = m_defaultResolution;
    57     protected int m_textSize = 0;
    58
    59     protected Dimension m_cellSize = new Dimension( 10, 10 ); // in pixels
    60
    61     public JMatrixDisplay( String filename ) throws IOException {
    62
    63        ColorMatrix matrix = new ColorMatrix( filename );
    64        init( matrix );
    65     }
    66
    67     public JMatrixDisplay( DenseDoubleMatrix2DNamed matrix ) {
    68        this( new ColorMatrix( matrix ) );
    69     }
    70
    71     public JMatrixDisplay( ColorMatrix matrix ) {
    72        init( matrix );
    73     }
    74
    75     public void init( ColorMatrix matrix ) {
    76
    77        m_unstandardizedMatrix = m_matrix = matrix;
    78        initSize();
    79
    80        // create a standardized copy of the matrix
    81        m_standardizedMatrix = ( ColorMatrix ) matrix.clone();
    82        m_standardizedMatrix.standardize();
    83
    84     }
    85
    86     /***
    87      * Sets the display size
    88      */
    89     protected void initSize() {
    90
    91        Dimension d = getSize( m_isShowLabels );
    92        setMinimumSize( d );
    93        setPreferredSize( d );
    94        setSize( d );
    95        this.revalidate();
    96     }
    97
    98     protected Dimension getSize( boolean withLabels ) {
    99
    100       if ( m_matrix == null ) {
    101          return null;
    102       }
    103
    104       // row label width and height (font-dependent)
    105       setFont();
    106       m_rowLabelWidth = m_labelGutter
    107             + Util.maxStringPixelWidth( m_matrix.getRowNames(), m_labelFont,
    108                   this );
    109       //m_rowLabelWidth += m_labelGutter; // this is optional (leaves some
    110       // space on the right)
    111       m_columnLabelHeight = Util.maxStringPixelWidth(
    112             m_matrix.getColumnNames(), m_labelFont, this );
    113       //m_columnLabelHeight += m_labelGutter; // this is optional (leaves some
    114       // space on top)
    115
    116       // height and width of this display component
    117       int height = m_cellSize.height * m_matrix.getRowCount();
    118       int width = m_cellSize.width * m_matrix.getColumnCount();
    119
    120       // adjust for row and column labels
    121       if ( withLabels ) {
    122          width += m_rowLabelWidth;
    123          height += ( m_columnLabelHeight + m_labelGutter );
    124       }
    125
    126       // set the sizes
    127       return new Dimension( width, height );
    128
    129    } // end getSize
    130
    131    /***
    132     * <code>JComponent</code> method used to render this component
    133     *
    134     * @param g Graphics used for painting
    135     */
    136    protected void paintComponent( Graphics g ) {
    137
    138       super.paintComponent( g );
    139       drawMatrix( g, m_isShowLabels );
    140
    141       if ( m_isShowLabels ) {
    142          drawRowNames( g );
    143          drawColumnNames( g );
    144       }
    145    } // end paintComponent
    146
    147    public void setStandardizedEnabled( boolean showStandardizedMatrix ) {
    148       m_isShowingStandardizedMatrix = showStandardizedMatrix;
    149       if ( showStandardizedMatrix ) {
    150          m_matrix = m_standardizedMatrix;
    151       } else {
    152          m_matrix = m_unstandardizedMatrix;
    153       }
    154    } // end setStandardizedEnabled
    155
    156    public boolean getStandardizedEnabled() {
    157
    158       return m_isShowingStandardizedMatrix;
    159    }
    160
    161    /***
    162     * Gets called from #paintComponent and #saveImage
    163     *
    164     * @param g Graphics
    165     * @param leaveRoomForLabels boolean
    166     */
    167    protected void drawMatrix( Graphics g, boolean leaveRoomForLabels ) {
    168
    169       g.setColor( Color.white );
    170       g.fillRect( 0, 0, this.getWidth(), this.getHeight() );
    171
    172       int rowCount = m_matrix.getRowCount();
    173       int columnCount = m_matrix.getColumnCount();
    174
    175       // loop through the matrix, one row at a time
    176       for ( int i = 0; i < rowCount; i++ ) {
    177          int y = ( i * m_cellSize.height );
    178          if ( leaveRoomForLabels ) {
    179             y += ( m_columnLabelHeight + m_labelGutter );
    180          }
    181
    182          // draw an entire row, one cell at a time
    183          for ( int j = 0; j < columnCount; j++ ) {
    184             int x = ( j * m_cellSize.width );
    185             int width = ( ( j + 1 ) * m_cellSize.width ) - x;
    186
    187             Color color = m_matrix.getColor( i, j );
    188             g.setColor( color );
    189             g.fillRect( x, y, width, m_cellSize.height );
    190          }
    191
    192       } // end looping through the matrix, one row at a time
    193    } // end drawMatrix
    194
    195    /***
    196     * Draws row names (horizontally)
    197     *
    198     * @param g Graphics
    199     */
    200    protected void drawRowNames( Graphics g ) {
    201
    202       if ( m_matrix == null ) return;
    203
    204       int rowCount = m_matrix.getRowCount();
    205
    206       // draw row names
    207       for ( int i = 0; i < rowCount; i++ ) {
    208          g.setColor( Color.black );
    209          g.setFont( m_labelFont );
    210          int y = ( i * m_cellSize.height ) + m_columnLabelHeight
    211                + m_labelGutter;
    212          int xRatio = ( m_matrix.getColumnCount() * m_cellSize.width )
    213                + m_labelGutter;
    214          int yRatio = y + m_cellSize.height - m_fontGutter;
    215          String rowName = m_matrix.getRowName( i );
    216          if ( null == rowName ) {
    217             rowName = "Undefined";
    218          }
    219          g.drawString( rowName, xRatio, yRatio );
    220       } // end drawing row names
    221    } // end rawRowName
    222
    223    /***
    224     * Draws column names vertically (turned 90 degrees counter-clockwise)
    225     *
    226     * @param g Graphics
    227     */
    228    protected void drawColumnNames( Graphics g ) {
    229
    230       if ( m_matrix == null ) return;
    231
    232       int columnCount = m_matrix.getColumnCount();
    233       for ( int j = 0; j < columnCount; j++ ) {
    234          // compute the coordinates
    235          int x = m_cellSize.width + ( j * m_cellSize.width ) - m_fontGutter;
    236          int y = m_columnLabelHeight;
    237
    238          // get column name
    239          String columnName = m_matrix.getColumnName( j );
    240          if ( null == columnName ) {
    241             columnName = "Undefined";
    242          }
    243
    244          // set font and color
    245          g.setColor( Color.black );
    246          g.setFont( m_labelFont );
    247
    248          // print the text vertically
    249          Util.drawVerticalString( g, columnName, m_labelFont, x, y );
    250
    251       } // end for column
    252    } // end drawColumnNames
    253
    254    /***
    255     * Sets the font used for drawing text
    256     */
    257    private void setFont() {
    258       int fontSize = Math
    259             .min( getFontSize(), ( int ) ( ( double ) m_maxFontSize
    260                   / ( double ) m_defaultResolution * m_resolution ) );
    261       if ( ( fontSize != m_fontSize ) || ( m_labelFont == null ) ) {
    262          m_fontSize = fontSize;
    263          m_labelFont = new Font( "Ariel", Font.PLAIN, m_fontSize );
    264          m_fontGutter = ( int ) ( m_cellSize.height * .22 );
    265       }
    266    }
    267
    268    /***
    269     * @return the height of the font
    270     */
    271    private int getFontSize() {
    272       return Math.max( m_cellSize.height, 5 );
    273    }
    274
    275    /***
    276     * Saves the image to a png file.
    277     *
    278     * @param outPngFilename String
    279     * @throws IOException
    280     */
    281    public void saveImage( String outPngFilename ) throws java.io.IOException {
    282       saveImage( outPngFilename, m_isShowLabels, m_isShowingStandardizedMatrix );
    283    }
    284
    285    public void saveImage( String outPngFilename, boolean showLabels )
    286          throws java.io.IOException {
    287       saveImage( outPngFilename, showLabels, m_isShowingStandardizedMatrix );
    288    }
    289
    290    /***
    291     * @param outPngFilename String
    292     * @param showLabels boolean
    293     * @param standardize normalize to deviation 1, mean 0.
    294     * @todo never read
    295     * @throws IOException
    296     */
    297    public void saveImage( String outPngFilename, boolean showLabels,
    298          boolean standardize ) throws java.io.IOException {
    299
    300       Graphics2D g = null;
    301
    302       // Include row and column labels?
    303       boolean wereLabelsShown = m_isShowLabels;
    304       if ( !wereLabelsShown ) {
    305          // Labels aren't visible, so make them visible
    306          setLabelsVisible( true );
    307          initSize();
    308       }
    309
    310       // Draw the image to a buffer
    311       Dimension d = getSize( showLabels ); // how big is the image with row and
    312       // column labels
    313       m_image = new BufferedImage( d.width, d.height,
    314             BufferedImage.TYPE_INT_RGB );
    315       g = m_image.createGraphics();
    316       drawMatrix( g, showLabels );
    317       if ( showLabels ) {
    318          drawRowNames( g );
    319          drawColumnNames( g );
    320       }
    321
    322       // Write the image to a png file
    323       ImageIO.write( m_image, "png", new File( outPngFilename ) );
    324
    325       // Restore state: make the image as it was before
    326       if ( !wereLabelsShown ) {
    327          // Labels weren't visible to begin with, so hide them
    328          setLabelsVisible( false );
    329          initSize();
    330       }
    331    } // end saveImage
    332
    333    /***
    334     * If this display component has already been added to the GUI, it will be resized to fit or exclude the row names
    335     *
    336     * @param isShowLabels boolean
    337     */
    338    public void setLabelsVisible( boolean isShowLabels ) {
    339       m_isShowLabels = isShowLabels;
    340       initSize();
    341    }
    342
    343    public ColorMatrix getColorMatrix() {
    344       return m_matrix;
    345    }
    346
    347    public AbstractNamedDoubleMatrix getMatrix() {
    348       return m_matrix.m_matrix;
    349    }
    350
    351    /***
    352     * @param matrix the new matrix to use; will resize this display component as necessary
    353     */
    354    public void setMatrix( ColorMatrix matrix ) {
    355       m_matrix = matrix;
    356       initSize();
    357    }
    358
    359    public void setCellSize( Dimension d ) {
    360
    361       m_cellSize = d;
    362       initSize();
    363    }
    364
    365    public void setRowHeight( int height ) {
    366
    367       m_cellSize.height = height;
    368       initSize();
    369    }
    370
    371    public int getRowHeight() {
    372       return m_cellSize.height;
    373    }
    374
    375    public Color getColor( int row, int column ) {
    376       return m_matrix.getColor( row, column );
    377    } // end getColor
    378
    379    public double getValue( int row, int column ) {
    380       return m_matrix.getValue( row, column );
    381    } // end getValue
    382
    383    public double[] getRow( int row ) {
    384       return m_matrix.getRow( row );
    385    }
    386
    387    public double[] getRowByName( String rowName ) {
    388       return m_matrix.getRowByName( rowName );
    389    }
    390
    391    public int getRowCount() {
    392       return m_matrix.getRowCount();
    393    }
    394
    395    public int getColumnCount() {
    396       return m_matrix.getColumnCount();
    397    }
    398
    399    public String getColumnName( int column ) {
    400       return m_matrix.getColumnName( column );
    401    }
    402
    403    public String getRowName( int row ) {
    404       return m_matrix.getRowName( row );
    405    }
    406
    407    public String[] getColumnNames() {
    408       return m_matrix.getColumnNames();
    409    }
    410
    411    public String[] getRowNames() {
    412       return m_matrix.getRowNames();
    413    }
    414
    415    public int getRowIndexByName( String rowName ) {
    416       return m_matrix.getRowIndexByName( rowName );
    417    }
    418
    419    public void setRowKeys( int[] rowKeys ) {
    420       m_matrix.setRowKeys( rowKeys );
    421    }
    422
    423    public void resetRowKeys() {
    424       m_matrix.resetRowKeys();
    425    }
    426
    427    /***
    428     * @param colorMap an array of colors which define the midpoints in the color map; this can be one of the constants
    429     *        defined in the ColorMap class, like ColorMap.REDGREEN_COLORMAP and ColorMap.BLACKBODY_COLORMAP
    430     */
    431    public void setColorMap( Color[] colorMap ) {
    432
    433       m_standardizedMatrix.setColorMap( colorMap );
    434       m_unstandardizedMatrix.setColorMap( colorMap );
    435    }
    436
    437    /***
    438     * @return the current color map
    439     */
    440    public Color[] getColorMap() {
    441       return m_matrix.m_colorMap;
    442    }
    443
    444    /***
    445     * @return the smallest value in the matrix
    446     */
    447    public double getMin() {
    448       return m_matrix.m_min;
    449    }
    450
    451    /***
    452     * @return the largest value in the matrix
    453     */
    454    public double getMax() {
    455       return m_matrix.m_max;
    456    }
    457
    458    public double getDisplayMin() {
    459       return m_matrix.m_displayMin;
    460    }
    461
    462    public double getDisplayMax() {
    463       return m_matrix.m_displayMax;
    464    }
    465
    466    public double getDisplayRange() {
    467       return m_matrix.m_displayMax - m_matrix.m_displayMin;
    468    }
    469
    470    public void setDisplayRange( double min, double max ) {
    471       m_matrix.setDisplayRange( min, max );
    472    }
    473
    474    /***
    475     * @return the color used for missing values
    476     */
    477    public Color getMissingColor() {
    478       return m_matrix.m_missingColor;
    479    }
    480
    481 } // end class JMatrixDisplay
    482