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.Structure; 027import org.biojava.nbio.structure.align.StrucAligParameters; 028import org.biojava.nbio.structure.align.StructurePairAligner; 029import org.biojava.nbio.structure.align.pairwise.AlternativeAlignment; 030import org.biojava.nbio.structure.align.pairwise.FragmentPair; 031import org.biojava.nbio.structure.gui.util.color.*; 032import org.biojava.nbio.structure.gui.util.color.LinearColorInterpolator.InterpolationDirection; 033import org.biojava.nbio.structure.io.PDBFileReader; 034import org.biojava.nbio.structure.jama.Matrix; 035 036import javax.swing.*; 037import javax.swing.event.ChangeEvent; 038import javax.swing.event.ChangeListener; 039import java.awt.*; 040import java.awt.color.ColorSpace; 041import java.awt.event.ActionEvent; 042import java.awt.event.ActionListener; 043import java.awt.event.WindowAdapter; 044import java.awt.event.WindowEvent; 045import java.util.Map; 046import java.util.SortedMap; 047import java.util.TreeMap; 048 049 050/** A JPanel that can display the underlying distance matrix 051 * data of the protein structure alignment algorithm. It adds a 052 * JSlider to a JMatrixPanel. 053 * 054 * see also JMatrixPanel. 055 * 056 */ 057public class ScaleableMatrixPanel 058extends JPanel 059implements ChangeListener, ActionListener { 060 061 /** 062 * 063 */ 064 private static final long serialVersionUID = -8082261434322968652L; 065 066 protected JMatrixPanel mPanel; 067 protected JSlider slider; 068 protected JScrollPane scroll; 069 protected JComboBox coloring; 070 071 protected Map<String,ContinuousColorMapper> gradients; 072 073 protected static final int SLIDER_STEPS = 8; // Number of minor ticks per unit scaled 074 075 076 public static void main(String[] args){ 077 078 PDBFileReader pdbr = new PDBFileReader(); 079 pdbr.setPath("/tmp/"); 080 081 082 //String pdb1 = "1crl"; 083 //String pdb2 = "1ede"; 084 085 String pdb1 = "1buz"; 086 String pdb2 = "1ali"; 087 088 //String pdb1 = "5pti"; 089 //String pdb2 = "5pti"; 090 091 // NO NEED TO DO CHANGE ANYTHING BELOW HERE... 092 093 StructurePairAligner sc = new StructurePairAligner(); 094 StrucAligParameters params = new StrucAligParameters(); 095 params.setMaxIter(1); 096 sc.setParams(params); 097 098 // step1 : read molecules 099 try { 100 Structure s1 = pdbr.getStructureById(pdb1); 101 Structure s2 = pdbr.getStructureById(pdb2); 102 103 System.out.println("aligning " + pdb1 + " vs. " + pdb2); 104 System.out.println(s1); 105 System.out.println(); 106 System.out.println(s2); 107 // step 2 : do the calculations 108 sc.align(s1,s2); 109 110 111 ScaleableMatrixPanel smp = new ScaleableMatrixPanel(); 112 JFrame frame = new JFrame(); 113 frame.addWindowListener(new WindowAdapter(){ 114 @Override 115 public void windowClosing(WindowEvent e){ 116 JFrame f = (JFrame) e.getSource(); 117 f.setVisible(false); 118 f.dispose(); 119 } 120 121 122 123 }); 124 125 smp.setMatrix(sc.getDistMat()); 126 smp.setFragmentPairs(sc.getFragmentPairs()); 127 smp.setAlternativeAligs(sc.getAlignments()); 128 129 for (int i = 0; i < sc.getAlignments().length; i++) { 130 AlternativeAlignment aa =sc.getAlignments()[i]; 131 System.out.println(aa); 132 133 } 134 135 frame.getContentPane().add(smp); 136 137 frame.pack(); 138 frame.setVisible(true); 139 140 } catch (Exception e) { 141 e.printStackTrace(); 142 } 143 144 } 145 146 public ScaleableMatrixPanel(){ 147 148 mPanel = new JMatrixPanel(); 149 Box vBox = Box.createVerticalBox(); 150 151 Box gradientBox = Box.createHorizontalBox(); 152 vBox.add(gradientBox); 153 gradientBox.add(new JLabel("Coloring:")); 154 gradients = createGradients(); //sets gradients 155 //Set first gradient 156 this.setCellColor(gradients.values().iterator().next()); 157 158 coloring = new JComboBox(gradients.keySet().toArray(new String[] {})); 159 coloring.setRenderer(new GradientRenderer()); 160 coloring.addActionListener(this); 161 coloring.setMaximumSize(new Dimension(1000,30)); 162 gradientBox.add(coloring); 163 164 int RES_MIN = 0*SLIDER_STEPS; 165 int RES_MAX = 8*SLIDER_STEPS; 166 int RES_INIT = 1*SLIDER_STEPS; 167 168 slider = new JSlider(JSlider.HORIZONTAL, RES_MIN,RES_MAX,RES_INIT); 169 slider.setInverted(false); 170 slider.setPaintTicks(true); 171 //slider.setMinorTickSpacing(1); 172 slider.setMajorTickSpacing(SLIDER_STEPS); 173 slider.setSnapToTicks(false); 174 slider.setPaintLabels(false); 175 slider.setPaintTrack(true); 176 //slider.setLabelTable(slider.createStandardLabels(SLIDER_STEPS)); 177 slider.addChangeListener(this); 178 slider.setPreferredSize(new Dimension(100,slider.getPreferredSize().height)); 179 180 vBox.add(slider); 181 182 scroll = new JScrollPane(mPanel); 183 scroll.getHorizontalScrollBar().setUnitIncrement(60); 184 scroll.getVerticalScrollBar().setUnitIncrement(60); 185 scroll.getHorizontalScrollBar().setBlockIncrement(60); 186 scroll.getVerticalScrollBar().setBlockIncrement(60); 187 vBox.add(scroll); 188 this.setPreferredSize(new Dimension(400,400)); 189 this.add(vBox); 190 191 192 mPanel.setLayout(new BoxLayout(mPanel,BoxLayout.Y_AXIS)); 193 this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); 194 195 } 196 197 198 199 200 protected static Map<String,ContinuousColorMapper> createGradients() { 201 SortedMap<String,ContinuousColorMapper> gradients = new TreeMap<String,ContinuousColorMapper>(); 202 203 int i = 0; //prepend number, since sorted alphabetically 204 ColorSpace hsv = HSVColorSpace.getHSVColorSpace(); 205 LinearColorInterpolator interp; 206 GradientMapper gradient; 207 208 /* 209 DefaultMatrixMapper defaultMapper = new DefaultMatrixMapper(10., .9f); 210 gradients.put((++i)+". Default", defaultMapper); 211 defaultMapper = new DefaultMatrixMapper(5., .9f); 212 gradients.put((++i)+". Sensitive", defaultMapper); 213 214 215 gradients.put((++i)+". Rainbow", GradientMapper.getGradientMapper(GradientMapper.RAINBOW_INTENSITY_GRADIENT, 0, 10)); 216 gradients.put((++i)+". Rainbow", GradientMapper.getGradientMapper(GradientMapper.RAINBOW_INTENSITY_GRADIENT, 10, 0)); 217 */ 218 219 220 interp = new LinearColorInterpolator(hsv); 221 interp.setInterpolationDirection(0, InterpolationDirection.INNER); 222 gradient = new GradientMapper(Color.green, Color.black, hsv); 223 gradient.put( -50., new Color(hsv,new float[] {0f, .9f, 0f},1f)); 224 gradient.put( 10., new Color(hsv,new float[] {1f, .9f, 1f},1f)); 225 gradient.setInterpolator(interp); 226 227 gradients.put((++i)+". -50 to 10", gradient); 228 229 230 231 // Mimic DefaultMapper 232 interp = new LinearColorInterpolator(hsv); 233 interp.setInterpolationDirection(0, InterpolationDirection.INNER); 234 gradient = new GradientMapper(Color.green, Color.black, hsv); 235 gradient.put( 0., new Color(hsv,new float[] {1f, .9f, 1f},1f)); 236 gradient.put(10., new Color(hsv,new float[] {0f, .9f, 0f},1f)); 237 gradient.setInterpolator(interp); 238 239 gradients.put((++i)+". Default", gradient); 240 241 // Sensitive DefaultMapper 242 interp = new LinearColorInterpolator(hsv); 243 interp.setInterpolationDirection(0, InterpolationDirection.INNER); 244 gradient = new GradientMapper(Color.green, Color.black, hsv); 245 gradient.put( 0., new Color(hsv,new float[] {1f, .9f, 1f},1f)); 246 gradient.put( 5., new Color(hsv,new float[] {0f, .9f, 0f},1f)); 247 gradient.setInterpolator(interp); 248 249 gradients.put((++i)+". Sensitive", gradient); 250 251 // color [0,1]import java.awt.Color; 252 253 interp = new LinearColorInterpolator(hsv); 254 interp.setInterpolationDirection(0, InterpolationDirection.INNER); 255 gradient = new GradientMapper(Color.green, Color.black, hsv); 256 gradient.put( 0., new Color(hsv,new float[] {1f, .9f, 1f},1f)); 257 gradient.put( 1., new Color(hsv,new float[] {.2f, .9f, 1f},1f)); 258 gradient.put( 1+1e-6, Color.white); 259 gradient.put(5., Color.black); 260 gradient.setInterpolator(interp); 261 262 gradients.put((++i)+". Emphasize low", gradient); 263 264 265 interp = new LinearColorInterpolator(hsv); 266 interp.setInterpolationDirection(0, InterpolationDirection.INNER); 267 gradient = new GradientMapper(Color.green, Color.black, hsv); 268 gradient.put( 0., new Color(hsv,new float[] {0f, .9f, 0f},1f)); 269 gradient.put( 100., new Color(hsv,new float[] {1f, .9f, 1f},1f)); 270 gradient.setInterpolator(interp); 271 272 gradients.put((++i)+". 0 to 100", gradient); 273 274 // log color 275 interp = new LinearColorInterpolator(hsv); 276 interp.setInterpolationDirection(0, InterpolationDirection.INNER); 277 gradient = new GradientMapper(Color.red, Color.black, hsv); 278 gradient.put( 0., new Color(hsv,new float[] {1f, .9f, 1f},1f)); 279 gradient.put( 10., new Color(hsv,new float[] {0f, .9f, 0f},1f)); 280 gradient.setInterpolator(interp); 281 282 ContinuousColorMapper logGradient = new LogColorMapper(gradient,2); 283 gradients.put((++i)+". Logorithmic", logGradient); 284 285 // sqrt color 286 interp = new LinearColorInterpolator(hsv); 287 interp.setInterpolationDirection(0, InterpolationDirection.INNER); 288 gradient = new GradientMapper(Color.red, Color.black, hsv); 289 gradient.put( 0., new Color(hsv,new float[] {1f, .9f, 1f},1f)); 290 gradient.put( 4., new Color(hsv,new float[] {0f, .9f, 0f},1f)); 291 gradient.setInterpolator(interp); 292 293 ContinuousColorMapper sqrtGradient = new SqrtColorMapper(gradient); 294 gradients.put((++i)+". Square Root", sqrtGradient); 295 296 GradientMapper black = new GradientMapper(Color.BLACK, Color.BLACK); 297 gradients.put((++i)+". Black", black); 298 299 return gradients; 300 } 301 302 @Override 303 public void stateChanged(ChangeEvent e) { 304 305 JSlider source = (JSlider)e.getSource(); 306 307 if ( source.getValueIsAdjusting()) { 308 //return; 309 } 310 311 //System.out.println("Changed scale to "+source.getValue()); 312 mPanel.setScale((float)source.getValue()/SLIDER_STEPS); 313 314 scroll.repaint(); 315 scroll.updateUI(); 316 } 317 318 public Matrix getMatrix() { 319 return mPanel.getMatrix(); 320 } 321 322 public void setMatrix(Matrix matrix) { 323 mPanel.setMatrix(matrix); 324 325 326 } 327 328 public JMatrixPanel getMatrixPanel(){ 329 return mPanel; 330 } 331 332 public FragmentPair[] getFragmentPairs(){ 333 return mPanel.getFragmentPairs(); 334 } 335 public void setFragmentPairs(FragmentPair[] pairs){ 336 mPanel.setFragmentPairs(pairs); 337 } 338 339 public AlternativeAlignment[] getAlternativeAligs() { 340 return mPanel.getAlternativeAligs(); 341 } 342 343 344 345 public void setAlternativeAligs(AlternativeAlignment[] aligs) { 346 mPanel.setAlternativeAligs(aligs); 347 } 348 349 public int getSelectedAlignmentPos() { 350 return mPanel.getSelectedAlignmentPos(); 351 } 352 353 public void setSelectedAlignmentPos(int selectedAlignmentPos) { 354 mPanel.setSelectedAlignmentPos(selectedAlignmentPos); 355 } 356 357 /** 358 * @return the color mapping of the JMatrixPanel 359 */ 360 public ContinuousColorMapper getCellColor() { 361 return mPanel.getCellColor(); 362 } 363 364 /** 365 * @param cellColor the color mapping of the JMatrixPanel 366 */ 367 public void setCellColor(ContinuousColorMapper cellColor) { 368 mPanel.setCellColor(cellColor); 369 } 370 371 /** 372 * A renderer for the the gradient dropdown menu at the top of scaleableMatrixPanes. 373 * Knows how to draw a gradient and nicely label it. 374 * 375 * @author Spencer Bliven 376 * 377 */ 378 protected class GradientRenderer extends JPanel 379 implements ListCellRenderer { 380 381 private static final long serialVersionUID = -2000575579184232365L; 382 private int min,max; 383 JLabel title; 384 JPanel gradientContainer; 385 386 public GradientRenderer() { 387 this.setPreferredSize(new Dimension(100,25)); 388 this.setLayout(new BorderLayout()); 389 this.min = -1; 390 this.max = 10; 391 392 JPanel gradientBounds = new JPanel(); 393 gradientBounds.setLayout(new BorderLayout()); 394 //gradientBounds.setBorder(BorderFactory.createLineBorder(Color.GRAY)); 395 gradientBounds.add(new JLabel(Integer.toString(min)),BorderLayout.WEST); 396 397 gradientContainer = new JPanel(); 398 gradientContainer.setLayout(new BorderLayout()); 399 gradientContainer.setOpaque(false); 400 gradientContainer.add(new JLabel("<No gradient>"),BorderLayout.CENTER); 401 //gradientContainer.setMinimumSize(new Dimension(50,20)); 402 //gradientContainer.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY)); 403 //gradientBounds.setPreferredSize(new Dimension(200,25)); 404 gradientBounds.add(gradientContainer,BorderLayout.CENTER); 405 gradientBounds.setOpaque(false); 406 407 gradientBounds.add(new JLabel(Integer.toString(max)),BorderLayout.EAST); 408 409 this.add(gradientBounds, BorderLayout.EAST); 410 411 this.title = new JLabel("No gradient"); 412 //this.title.setOpaque(true); 413 this.title.setHorizontalAlignment(JLabel.CENTER); 414 this.title.setVerticalAlignment(JLabel.CENTER); 415 this.add(this.title,BorderLayout.CENTER); 416 } 417 418 /* 419 * This method finds the image and text corresponding 420 * to the selected value and returns the label, set up 421 * to display the text and image. 422 */ 423 @Override 424 public Component getListCellRendererComponent( 425 JList list, 426 Object value, 427 int index, 428 boolean isSelected, 429 boolean cellHasFocus) { 430 //Get the selected index. (The index param isn't 431 //always valid, so just use the value.) 432 String gradientLabel = (String)value; 433 434 if (isSelected) { 435 setBackground(list.getSelectionBackground()); 436 setForeground(list.getSelectionForeground()); 437 } else { 438 setBackground(list.getBackground()); 439 setForeground(list.getForeground()); 440 } 441 442 //Set the icon and text. If icon was null, say so. 443 GradientPanel gradPanel = new GradientPanel(gradients.get(gradientLabel),min,max); 444 gradPanel.setPreferredSize(new Dimension(100,20)); 445 //gradPanel.setBorder(BorderFactory.createLineBorder(Color.cyan)); 446 gradientContainer.removeAll(); 447 gradientContainer.add(gradPanel,BorderLayout.CENTER); 448 449 title.setText(gradientLabel); 450 451 this.validate(); 452 453 return this; 454 } 455 } 456 457 /** 458 * @param e 459 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) 460 */ 461 @Override 462 public void actionPerformed(ActionEvent e) { 463 JComboBox cb = (JComboBox)e.getSource(); // == coloring 464 String gradientName = (String)cb.getSelectedItem(); 465 ContinuousColorMapper gradient = gradients.get(gradientName); 466 assert(gradient != null); 467 this.setCellColor(gradient); 468 this.repaint(); 469 } 470 471 472}