001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * Created on Aug 3, 2007 021 * 022 */ 023 024package org.biojava.nbio.structure.gui; 025 026import org.biojava.nbio.structure.align.StrucAligParameters; 027import org.biojava.nbio.structure.align.pairwise.AlternativeAlignment; 028import org.biojava.nbio.structure.align.pairwise.FragmentPair; 029import org.biojava.nbio.structure.gui.util.color.ContinuousColorMapper; 030import org.biojava.nbio.structure.gui.util.color.DefaultMatrixMapper; 031import org.biojava.nbio.structure.jama.Matrix; 032 033import javax.swing.*; 034import java.awt.*; 035import java.awt.image.BufferedImage; 036 037 038/** a JPanel that can display a difference of distance matrix and paths that have been 039 * taken for the alignment 040 * 041 * <p>Note: This panel displays the transpose of its underlying matrix. 042 * Thus its width will be the same as {@link Matrix#getRowDimension()} and its 043 * height the same as {@link Matrix#getColumnDimension()}. This stems from the 044 * unfortunate ordering of {@link Matrix#get(int, int)} parameters as (row, col), 045 * which is opposite from the normal (x,y) order used when displaying graphics. 046 * 047 * @author Andreas Prlic 048 * 049 */ 050public class JMatrixPanel extends JPanel{ 051 052 /** 053 * 054 */ 055 private static final long serialVersionUID = -1720879395453257846L; 056 BufferedImage _bufImage; 057 Matrix matrix; 058 ContinuousColorMapper cellColor; //Maps matrix elements to a color 059 float scale; 060 061 FragmentPair[] fragmentPairs; 062 AlternativeAlignment[] aligs; 063 int selectedAlignmentPos; 064 065 final static BasicStroke stroke = new BasicStroke(2.0f); 066 StrucAligParameters params; 067 068 public JMatrixPanel(){ 069 scale = 1; 070 cellColor = new DefaultMatrixMapper(10, 0.9f); 071 //saturation = 0.9f; 072 //scalevalue = 10; 073 selectedAlignmentPos = -1; 074 matrix = new Matrix(0,0); 075 params = new StrucAligParameters(); 076 } 077 078 public int getSelectedAlignmentPos() { 079 return selectedAlignmentPos; 080 } 081 082 public void setSelectedAlignmentPos(int selectedAlignmentPos) { 083 this.selectedAlignmentPos = selectedAlignmentPos; 084 } 085 086 public AlternativeAlignment[] getAlternativeAligs() { 087 return aligs; 088 } 089 090 public void setAlternativeAligs(AlternativeAlignment[] aligs) { 091 this.aligs = aligs; 092 } 093 094 095 096 public FragmentPair[] getFragmentPairs() { 097 return fragmentPairs; 098 } 099 100 public void setFragmentPairs(FragmentPair[] fragmentPairs) { 101 this.fragmentPairs = fragmentPairs; 102 } 103 104 public float getScale() { 105 return scale; 106 } 107 108 public void setPreferredSize(){ 109 110 int prefW = Math.round(matrix.getRowDimension() * scale); 111 int prefH = Math.round(matrix.getColumnDimension() * scale); 112 113 this.setPreferredSize(new Dimension(prefW,prefH)); 114 115 } 116 117 public void setScale(float scale) { 118 119 if ( scale == this.scale) 120 return; 121 //System.out.println("setting scale " + scale + "current width " + getWidth() + " " + getHeight()); 122 123 this.scale = scale; 124 125 setPreferredSize(); 126 127 this.repaint(); 128 129 } 130 131 public Matrix getMatrix() { 132 return matrix; 133 } 134 135 /** sets the distance matrix to be displayed 136 * 137 * @param matrix 138 */ 139 public void setMatrix(Matrix matrix) { 140 this.matrix = matrix; 141 setPreferredSize(); 142 } 143 144 @Override 145 public void paintComponent(Graphics g){ 146 147 //super.paintComponent(g); 148 149 Graphics2D g2 = (Graphics2D)g; 150 if ( _bufImage == null){ 151 152 int w = getWidth(); 153 int h = getHeight(); 154 _bufImage = (BufferedImage) createImage(w,h); 155 //Graphics gc = _bufImage.createGraphics(); 156 //gc.setColor(Color.blue); 157 //gc.fillRect(0,0,w,h); 158 159 } 160 161 162 g2.drawImage(_bufImage,null,0,0); 163 drawDistances(g); 164 165 drawPairs(g); 166 167 if ( scale >= 4) { 168 drawBoxes(g); 169 } 170 } 171 172 /** draw alternative alignments 173 * 174 * @param g 175 */ 176 public void drawPairs(Graphics g){ 177 178 if ( aligs == null) 179 return; 180 181 int nr = aligs.length; 182 183 Graphics2D g2D = (Graphics2D)g; 184 Stroke oldStroke = g2D.getStroke(); 185 g2D.setStroke(stroke); 186 187 Color color; 188 float hue; 189 190 int width = Math.round(scale); 191 int w2 = width / 2 ; 192 193 for (int i = 0; i < aligs.length; i++) { 194 AlternativeAlignment a = aligs[i]; 195 int[] idx1 = a.getIdx1(); 196 int[] idx2 = a.getIdx2(); 197 int xold = -1; 198 int yold = -1; 199 boolean start = true; 200 201 if ( (selectedAlignmentPos != -1 ) && 202 ( selectedAlignmentPos == i)){ 203 color = Color.white; 204 } else { 205 206 hue = i * (1/ (float)nr); 207 color = Color.getHSBColor(hue,1.0f,1.0f); 208 } 209 g.setColor(color); 210 211 for (int j = 0; j < idx1.length; j++) { 212 int x1 = Math.round(idx1[j]*scale) ; 213 int y1 = Math.round(idx2[j]*scale) ; 214 if ( ! start){ 215 //g.drawLine(xold+1,yold,x1+1,y1); 216 217 //g2D.draw(new Line2D.Double(xold,yold,x1,y1)); 218 g.fillRect(xold,yold,2,2); 219 } else { 220 g.fillRect(x1,y1, w2, w2); 221 start =false; 222 } 223 xold = x1; 224 yold = y1; 225 } 226 227 if ( ! start) 228 g.fillRect(xold,yold,w2,w2); 229 230 231 } 232 233 g2D.setStroke(oldStroke); 234 } 235 236 237 /** draw high scoring fragments that are used for the initial alignment seed 238 * selection 239 * 240 * @param g 241 */ 242 public void drawBoxes(Graphics g){ 243 if ( fragmentPairs == null ) 244 return; 245 246 g.setColor(Color.yellow); 247 248 249 for (int i = 0; i < fragmentPairs.length; i++) { 250 FragmentPair fp =fragmentPairs[i]; 251 int xp = fp.getPos1(); 252 int yp = fp.getPos2(); 253 254 int width = Math.round(scale); 255 256 g.drawRect(Math.round(xp*scale),Math.round(yp*scale),width, width); 257 258 } 259 } 260 261 262 /** 263 * For each element in matrix, draw it as a colored square or pixel. 264 * 265 * The color of a matrix element with value x is specified as 266 * - H: 1-x/scalevalue 267 * - S: saturation 268 * - B: 1-x/scalevalue 269 * @param g1 270 */ 271 public void drawDistances(Graphics g1){ 272 Graphics2D g = (Graphics2D)g1; 273 274 int c = matrix.getRowDimension(); 275 int d = matrix.getColumnDimension(); 276 277 float scale = getScale(); 278 int width = Math.round(scale); 279 280 for (int i = 0; i < c; i++) { 281 int ipaint = Math.round(i*scale); 282 283 for (int j = 0; j < d; j++) { 284 double val = matrix.get(i,j); 285 286 int jpaint = Math.round(j*scale); 287 288 Color color = cellColor.getColor(val); 289 g.setColor(color); 290 291 g.fillRect(ipaint,jpaint,width,width); 292 } 293 294 } 295 296 } 297 298 /** 299 * @return the color mapping of the JMatrixPanel 300 */ 301 public ContinuousColorMapper getCellColor() { 302 return cellColor; 303 } 304 305 /** 306 * @param cellColor the color mapping of the JMatrixPanel to set 307 */ 308 public void setCellColor(ContinuousColorMapper cellColor) { 309 this.cellColor = cellColor; 310 } 311 312 313 314}