1 /*************************************************************** 2 * 3 * This program is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU General Public License 5 * as published by the Free Software Foundation; either version 2 6 * of the License, or (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * 17 * @author: Copyright (C) Tim Carver 18 * 19 ***************************************************************/ 20 21 package org.emboss.jemboss.editor; 22 23 import javax.swing.*; 24 25 import java.awt.*; 26 import java.awt.event.*; 27 import java.util.*; 28 import java.io.File; 29 import javax.swing.border.*; 30 import java.net.URL; 31 32 import org.emboss.jemboss.JembossParams; 33 import org.emboss.jemboss.gui.form.TextFieldInt; 34 import org.emboss.jemboss.gui.ScrollPanel; 35 import org.emboss.jemboss.gui.Browser; 36 37 /** 38 * 39 * Displays a grapical representation of a collection of 40 * sequences. 41 * 42 */ 43 public class AlignJFrame extends JFrame 44 { 45 46 protected JScrollPane jspSequence; // Sequence scrollpane 47 protected static GraphicSequenceCollection gsc; 48 private static Matrix mat; 49 private PrettyPlotJFrame ppj = null; 50 protected static JTextField statusField = new JTextField(); 51 private File sequenceFile = null; 52 private Cursor cbusy = new Cursor(Cursor.WAIT_CURSOR); 53 private Cursor cdone = new Cursor(Cursor.DEFAULT_CURSOR); 54 protected JCheckBoxMenuItem residueColor; 55 protected Hashtable currentColour; 56 protected boolean useExitMenu = false; // whether to use 'Exit' or 'Close' 57 protected JMenuBar menuBar; 58 PatternJFrame findPattern; 59 JCheckBoxMenuItem drawColorBox; 60 61 /** 62 * 63 * @param vseqs vector containing Sequence objects 64 * 65 */ AlignJFrame(Vector vseqs)66 public AlignJFrame(Vector vseqs) 67 { 68 this(); 69 if(vseqs != null && vseqs.size() > 0) 70 openMethod(vseqs); 71 } 72 73 74 /** 75 * 76 * @param seqFile sequence file 77 * 78 */ AlignJFrame(File seqFile)79 public AlignJFrame(File seqFile) 80 { 81 this(); 82 83 SequenceReader sr = new SequenceReader(seqFile); 84 sequenceFile = sr.getSequenceFile(); 85 86 if(sr.getSequenceVector()==null) 87 { 88 statusField.setText("Jemboss not able to read sequences in "+ 89 sequenceFile.getName()); 90 return; 91 } 92 93 openMethod(sr.getSequenceVector()); 94 setTitle("Jemboss Alignment Viewer :: "+ 95 sequenceFile.getName()); 96 } 97 98 99 /** 100 * 101 * @param seqString formatted sequence string 102 * @param name name of sequence set 103 * 104 */ AlignJFrame(String seqString, String name)105 public AlignJFrame(String seqString, String name) 106 { 107 this(); 108 109 SequenceReader sr = new SequenceReader(seqString); 110 sequenceFile = null; 111 openMethod(sr.getSequenceVector()); 112 setTitle("Jemboss Alignment Viewer :: "+name); 113 } 114 115 AlignJFrame()116 public AlignJFrame() 117 { 118 this(false); 119 } 120 121 122 /** 123 * 124 * @param useExitMenu true if an exit menu is to be displayed 125 * otherwise a close menu is used 126 * 127 */ AlignJFrame(boolean useExitMenu)128 public AlignJFrame(boolean useExitMenu) 129 { 130 this(useExitMenu, new Matrix("resources/resources.jar", 131 Matrix.DEFAULT_MATRIX)); 132 } 133 AlignJFrame(boolean useExitMenu, Matrix mat_)134 public AlignJFrame(boolean useExitMenu, Matrix mat_){ 135 super("Jemboss Alignment Editor"); 136 137 this.useExitMenu = useExitMenu; 138 139 final Dimension dScreen = getToolkit().getScreenSize(); 140 141 mat = mat_; 142 jspSequence = new JScrollPane(); 143 jspSequence.getViewport().setBackground(Color.white); 144 145 final JButton leftbutt = new JButton("Lock"); 146 jspSequence.setCorner(JScrollPane.LOWER_LEFT_CORNER, 147 leftbutt); 148 leftbutt.addActionListener(new ActionListener() 149 { 150 public void actionPerformed(ActionEvent e) 151 { 152 if(leftbutt.getText().equals("Lock")) 153 { 154 gsc.setSequenceLock(true); 155 leftbutt.setText("Unlock"); 156 } 157 else 158 { 159 gsc.setSequenceLock(false); 160 leftbutt.setText("Lock"); 161 } 162 } 163 }); 164 165 final JPanel mainPane = (JPanel)getContentPane(); 166 167 // set up a menu bar 168 menuBar = new JMenuBar(); 169 170 // File menu 171 JMenu fileMenu = new JMenu("File"); 172 fileMenu.setMnemonic(KeyEvent.VK_F); 173 174 // open sequence file 175 final JMenuItem calculateCons = new JMenuItem("Consensus"); 176 final JMenuItem calculatePlotCon = new JMenuItem("Consensus plot"); 177 178 JMenuItem openSequence = new JMenuItem("Open..."); 179 openSequence.addActionListener(new ActionListener() 180 { 181 public void actionPerformed(ActionEvent e) 182 { 183 SequenceReader sr = new SequenceReader(); 184 185 if(sr.isReading()) 186 { 187 sequenceFile = sr.getSequenceFile(); 188 openMethod(sr.getSequenceVector()); 189 calculateCons.setText("Calculate consensus"); 190 calculatePlotCon.setText("Calculate consensus plot"); 191 setTitle("Jemboss Alignment Viewer :: "+ 192 sequenceFile.getName()); 193 } 194 } 195 }); 196 fileMenu.add(openSequence); 197 198 // save 199 JMenuItem saveAsMenu = new JMenuItem("Save As..."); 200 saveAsMenu.addActionListener(new ActionListener() 201 { 202 public void actionPerformed(ActionEvent e) 203 { 204 new SequenceSaver(gsc.getSequenceCollection(),sequenceFile); 205 } 206 }); 207 fileMenu.add(saveAsMenu); 208 209 JMenuItem saveConsMenu = new JMenuItem("Save Consensus"); 210 saveConsMenu.addActionListener(new ActionListener() 211 { 212 public void actionPerformed(ActionEvent e) 213 { 214 Vector v = new Vector(); 215 v.add(gsc.getConsensusSequence()); 216 new SequenceSaver(v); 217 } 218 }); 219 fileMenu.add(saveConsMenu); 220 221 222 // print 223 JMenu printMenu = new JMenu("Print"); 224 fileMenu.add(printMenu); 225 226 JMenuItem print = new JMenuItem("Print Postscript..."); 227 print.setToolTipText("Print using available printers in your computer\n" + 228 "or export alignment image to a postscript file (if you have " + 229 " installed postscript printers)"); 230 print.addActionListener(new ActionListener() 231 { 232 public void actionPerformed(ActionEvent e) 233 { 234 new PrintAlignment(gsc); 235 } 236 }); 237 printMenu.add(print); 238 239 // 240 JMenuItem printImage = new JMenuItem("Print Image Files (png/jpeg)..."); 241 printImage.addActionListener(new ActionListener() 242 { 243 public void actionPerformed(ActionEvent e) 244 { 245 PrintAlignmentImage pai = new PrintAlignmentImage(gsc); 246 pai.print(); 247 } 248 }); 249 printMenu.add(printImage); 250 251 JMenuItem printOneImage = new JMenuItem("Print to Single Image File..."); 252 printOneImage.addActionListener(new ActionListener() 253 { 254 public void actionPerformed(ActionEvent e) 255 { 256 PrintAlignmentImage pai = new PrintAlignmentImage(gsc); 257 String fsave = pai.showOptions(); 258 if(fsave == null) 259 return; 260 261 pai.print(fsave,0.,0.,0.,0.); 262 } 263 }); 264 printMenu.add(printOneImage); 265 266 // print preview 267 JMenu printPreviewMenu = new JMenu("Print Preview"); 268 fileMenu.add(printPreviewMenu); 269 270 JMenuItem printPreview = new JMenuItem("Multiple Pages..."); 271 printPreview.addActionListener(new ActionListener() 272 { 273 public void actionPerformed(ActionEvent e) 274 { 275 PrintAlignmentImage pai = new PrintAlignmentImage(gsc); 276 pai.printPreview(); 277 } 278 }); 279 printPreviewMenu.add(printPreview); 280 281 JMenuItem printSinglePreview = new JMenuItem("Single Page..."); 282 printSinglePreview.addActionListener(new ActionListener() 283 { 284 public void actionPerformed(ActionEvent e) 285 { 286 PrintAlignmentImage pai = new PrintAlignmentImage(gsc); 287 /*String type = */pai.showPrintPreviewOptions(); 288 pai.printSinglePagePreview(); 289 } 290 }); 291 printPreviewMenu.add(printSinglePreview); 292 293 // close 294 fileMenu.add(new JSeparator()); 295 if(!useExitMenu) 296 { 297 JMenuItem close = new JMenuItem("Close"); 298 close.setAccelerator(KeyStroke.getKeyStroke( 299 KeyEvent.VK_E, ActionEvent.CTRL_MASK)); 300 301 close.addActionListener(new ActionListener() 302 { 303 public void actionPerformed(ActionEvent e) 304 { 305 dispose(); 306 findPattern.dispose(); 307 } 308 }); 309 fileMenu.add(close); 310 } 311 else // exit 312 { 313 JMenuItem fileMenuExit = new JMenuItem("Exit"); 314 fileMenuExit.addActionListener(new ActionListener() 315 { 316 public void actionPerformed(ActionEvent e) 317 { 318 System.exit(0); 319 } 320 }); 321 fileMenu.add(fileMenuExit); 322 } 323 menuBar.add(fileMenu); 324 325 // Edit menu 326 JMenu editMenu = new JMenu("Edit"); 327 menuBar.add(editMenu); 328 329 JMenuItem insertAnn = new JMenuItem("Insert Annotation Sequence"); 330 editMenu.add(insertAnn); 331 insertAnn.addActionListener(new ActionListener() 332 { 333 public void actionPerformed(ActionEvent e) 334 { 335 ScrollPanel pane = new ScrollPanel(new BorderLayout()); 336 Box bacross = Box.createVerticalBox(); 337 JRadioButton openFile = new JRadioButton("Read from File"); 338 JRadioButton cut = new JRadioButton("Cut and Paste"); 339 ButtonGroup group = new ButtonGroup(); 340 group.add(openFile); 341 group.add(cut); 342 cut.setSelected(true); 343 bacross.add(openFile); 344 bacross.add(cut); 345 pane.add(bacross,BorderLayout.CENTER); 346 int selectedValue = JOptionPane.showConfirmDialog(null, 347 pane, "Cut and Paste/Read from File", 348 JOptionPane.OK_CANCEL_OPTION, 349 JOptionPane.QUESTION_MESSAGE); 350 if(selectedValue == JOptionPane.OK_OPTION) 351 { 352 SequenceReader sr = null; 353 if(openFile.isSelected()) 354 sr = new SequenceReader(); 355 else 356 { 357 Paste pastePane = new Paste(); 358 selectedValue = JOptionPane.showConfirmDialog(null, 359 pastePane, "Cut and Paste", 360 JOptionPane.OK_CANCEL_OPTION, 361 JOptionPane.QUESTION_MESSAGE); 362 if(selectedValue == JOptionPane.OK_OPTION) 363 sr = new SequenceReader(pastePane.getSequence()); 364 } 365 if(sr != null && sr.isReading()) 366 { 367 sequenceFile = sr.getSequenceFile(); 368 gsc.addAnnotationSequence(sr.getSequence(0)); 369 Dimension dpane = gsc.getPanelSize(); 370 gsc.setPreferredSize(dpane); 371 gsc.setNamePanelWidth(gsc.getNameWidth()); 372 jspSequence.setViewportView(gsc); 373 } 374 } 375 } 376 }); 377 378 JMenuItem trimMenu = new JMenuItem("Trim Sequences"); 379 editMenu.add(trimMenu); 380 trimMenu.addActionListener(new ActionListener() 381 { 382 public void actionPerformed(ActionEvent e) 383 { 384 ScrollPanel pane = new ScrollPanel(new BorderLayout()); 385 Box bacross = Box.createHorizontalBox(); 386 TextFieldInt start = new TextFieldInt(); 387 start.setValue(1); 388 TextFieldInt end = new TextFieldInt(); 389 end.setValue(gsc.getMaxSeqLength()); 390 bacross.add(start); 391 bacross.add(new JLabel(" start ")); 392 bacross.add(end); 393 bacross.add(new JLabel(" end")); 394 pane.add(bacross,BorderLayout.CENTER); 395 int selectedValue = JOptionPane.showConfirmDialog(null, 396 pane, "Select Sequence Range to Use", 397 JOptionPane.OK_CANCEL_OPTION, 398 JOptionPane.QUESTION_MESSAGE); 399 if(selectedValue == JOptionPane.OK_OPTION) 400 { 401 Vector vseq = gsc.getSequenceCollection(); 402 Enumeration enumer = vseq.elements(); 403 while(enumer.hasMoreElements()) 404 { 405 Sequence s = (Sequence)enumer.nextElement(); 406 s.trim(start.getValue(),end.getValue()); 407 } 408 gsc.setMaxSeqLength(); 409 gsc.repaint(); 410 } 411 } 412 }); 413 414 JMenuItem unlock = new JMenuItem("Unlock All Sequences"); 415 editMenu.add(unlock); 416 unlock.addActionListener(new ActionListener() 417 { 418 public void actionPerformed(ActionEvent e) 419 { 420 gsc.setSequenceLock(false); 421 } 422 }); 423 424 // View menu 425 JMenu viewMenu = new JMenu("View"); 426 viewMenu.setMnemonic(KeyEvent.VK_V); 427 428 // find pattern 429 JMenuItem findMenu = new JMenuItem("Find pattern"); 430 viewMenu.add(findMenu); 431 findPattern = new PatternJFrame(); 432 final PatternJFrame patFrame = findPattern; 433 findMenu.addActionListener(new ActionListener() 434 { 435 public void actionPerformed(ActionEvent e) 436 { 437 Point pos = getLocationOnScreen(); 438 pos.y = pos.y - patFrame.getHeight(); 439 if(pos.y+patFrame.getHeight() > dScreen.getHeight()) 440 pos.x = (int)(dScreen.getWidth()-patFrame.getHeight()); 441 442 patFrame.setLocation(pos); 443 patFrame.setGraphic(gsc); 444 patFrame.setVisible(true); 445 patFrame.setExtendedState(patFrame.getExtendedState() & ~ICONIFIED); 446 patFrame.requestFocusInWindow(); 447 patFrame.toFront(); 448 } 449 }); 450 viewMenu.add(new JSeparator()); 451 452 // matrix display 453 JMenuItem showMatrix = new JMenuItem("Matrix Display"); 454 viewMenu.add(showMatrix); 455 final MatrixJFrame matFrame = new MatrixJFrame(mat,statusField, 456 this); 457 showMatrix.addActionListener(new ActionListener() 458 { 459 public void actionPerformed(ActionEvent e) 460 { 461 matFrame.setMatrix(mat); 462 matFrame.setVisible(true); 463 matFrame.toFront(); 464 } 465 }); 466 467 // colour display 468 JMenuItem showColour = new JMenuItem("Colour Display"); 469 viewMenu.add(showColour); 470 final ColourJFrame colFrame = new ColourJFrame(this); 471 showColour.addActionListener(new ActionListener() 472 { 473 public void actionPerformed(ActionEvent e) 474 { 475 Point pos = getLocationOnScreen(); 476 pos.x = pos.x + getWidth(); 477 if(pos.x+colFrame.getWidth() > dScreen.getWidth()) 478 pos.x = (int)(dScreen.getWidth()-colFrame.getWidth()); 479 480 colFrame.setLocation(pos); 481 colFrame.setCurrentColour(currentColour); 482 colFrame.setVisible(true); 483 colFrame.toFront(); 484 } 485 }); 486 viewMenu.add(new JSeparator()); 487 488 colourMenus(viewMenu); 489 490 //pretty plot 491 final JMenuItem pretty = new JMenuItem("Colour Identical/Matches"); 492 viewMenu.add(pretty); 493 viewMenu.add(new JSeparator()); 494 495 //draw black box 496 final JCheckBoxMenuItem drawBoxes = new JCheckBoxMenuItem("Draw boxes",false); 497 drawBoxes.addActionListener(new ActionListener() 498 { 499 public void actionPerformed(ActionEvent e) 500 { 501 gsc.setDrawBoxes(drawBoxes.isSelected()); 502 } 503 }); 504 viewMenu.add(drawBoxes); 505 506 //draw colored boxes 507 viewMenu.add(drawColorBox); 508 509 pretty.addActionListener(new ActionListener() 510 { 511 public void actionPerformed(ActionEvent e) 512 { 513 if(ppj == null) 514 ppj = new PrettyPlotJFrame(gsc); 515 else 516 ppj.setGraphicSequenceCollection(gsc); 517 gsc.setMatrix(mat); 518 ppj.setVisible(true); 519 } 520 }); 521 menuBar.add(viewMenu); 522 523 // calculate menu 524 JMenu calculateMenu = new JMenu("Calculate"); 525 menuBar.add(calculateMenu); 526 527 // consensus sequence 528 final ConsensusOptions options = new ConsensusOptions(jspSequence); 529 calculateCons.addActionListener(new ActionListener() 530 { 531 public void actionPerformed(ActionEvent e) 532 { 533 setCursor(cbusy); 534 try{ 535 gsc.deleteSequence(Consensus.DEFAULT_SEQUENCE_NAME); 536 537 float wgt = getTotalWeight(gsc.getSequenceCollection()); 538 float plu = 0.f; 539 try 540 { 541 plu = options.getPlurality(); 542 } 543 catch(NumberFormatException nfe) 544 { 545 plu = wgt/2.f; 546 } 547 548 float cas = 0.f; 549 try 550 { 551 cas = options.getCase(); 552 } 553 catch(NumberFormatException nfe) 554 { 555 cas = wgt/2.f; 556 } 557 558 Consensus conseq = new Consensus(mat, 559 gsc.getSequenceCollection(), 560 plu,cas, 561 options.getIdentity()); 562 563 int fontSize = gsc.getFontSize(); 564 gsc.addSequence(conseq.getConsensusSequence(),true,0,fontSize); 565 566 // if(pretty.isSelected()) 567 // gsc.setPrettyPlot(pretty.isSelected(),ppj); 568 569 Dimension dpane = gsc.getPanelSize(); 570 gsc.setPreferredSize(dpane); 571 gsc.setNamePanelWidth(gsc.getNameWidth()); 572 jspSequence.setViewportView(gsc); 573 calculateCons.setText("Recalculate consensus"); 574 } finally { 575 setCursor(cdone); 576 } 577 } 578 }); 579 calculateMenu.add(calculateCons); 580 581 582 JMenuItem consOptions = new JMenuItem("Set consensus options..."); 583 consOptions.addActionListener(new ActionListener() 584 { 585 public void actionPerformed(ActionEvent e) 586 { 587 try 588 { 589 // Vector vseq = gsc.getSequenceCollection(); 590 // Enumeration enumer = vseq.elements(); 591 float wgt = getTotalWeight(gsc.getSequenceCollection()); 592 options.setCase(wgt/2.f); 593 options.setPlurality(wgt/2.f); 594 options.setGraphicSequenceCollection(gsc); 595 } 596 catch(NullPointerException npe){} 597 options.setMatrix(mat); 598 options.setVisible(true); 599 } 600 }); 601 calculateMenu.add(consOptions); 602 calculateMenu.add(new JSeparator()); 603 604 // %age identity between pairs 605 JMenuItem calculateId = new JMenuItem("Identity table"); 606 calculateId.addActionListener(new ActionListener() 607 { 608 public void actionPerformed(ActionEvent e) 609 { 610 IDTableJFrame idtab = new IDTableJFrame(gsc.getSequenceCollection()); 611 idtab.setVisible(true); 612 } 613 }); 614 calculateMenu.add(calculateId); 615 calculateMenu.add(new JSeparator()); 616 617 // consensus plot 618 calculatePlotCon.addActionListener(new ActionListener() 619 { 620 public void actionPerformed(ActionEvent e) 621 { 622 setCursor(cbusy); 623 gsc.showConsensusPlot(mat,2); 624 setCursor(cdone); 625 calculatePlotCon.setText("Recalculate Consensus plot"); 626 } 627 }); 628 calculateMenu.add(calculatePlotCon); 629 calculateMenu.add(new JSeparator()); 630 631 // sort by id 632 JMenuItem test = new JMenuItem("Sort by ID"); 633 calculateMenu.add(test); 634 test.addActionListener(new ActionListener() 635 { 636 public void actionPerformed(ActionEvent e) 637 { 638 gsc.idSort(); 639 jspSequence.setViewportView(gsc); 640 } 641 }); 642 643 // font menu 644 String sizes[] = {"10", "12", "14", "16", "18"}; 645 final JComboBox fntSize = new JComboBox(sizes); 646 fntSize.setToolTipText("font size"); 647 fntSize.setSelectedItem("12"); 648 menuBar.add(fntSize); 649 fntSize.setEditable(true); 650 Dimension dfont = new Dimension(50,20); 651 fntSize.setPreferredSize(dfont); 652 fntSize.setMaximumSize(dfont); 653 fntSize.addActionListener(new ActionListener() 654 { 655 public void actionPerformed(ActionEvent e) 656 { 657 String fsize = (String)fntSize.getSelectedItem(); 658 if(gsc !=null) 659 gsc.setFontSizeForCollection(Integer.parseInt(fsize)); 660 } 661 }); 662 663 setJMenuBar(menuBar); 664 665 // help manu 666 JMenu helpMenu = new JMenu("Help"); 667 menuBar.add(helpMenu); 668 669 JMenuItem aboutMenu = new JMenuItem("About"); 670 helpMenu.add(aboutMenu); 671 aboutMenu.addActionListener(new ActionListener() 672 { 673 public void actionPerformed(ActionEvent e) 674 { 675 ClassLoader cl = this.getClass().getClassLoader(); 676 try 677 { 678 URL inURL = cl.getResource("resources/readmeAlign.html"); 679 new Browser(inURL,"resources/readmeAlign.html"); 680 } 681 catch (Exception ex) 682 { 683 JOptionPane.showMessageDialog(null, 684 "Jemboss Alignment Viewer Guide not found!", 685 "Error", JOptionPane.ERROR_MESSAGE); 686 } 687 } 688 }); 689 690 // set size of sequence panel 691 Dimension d = new Dimension(700,300); 692 jspSequence.setPreferredSize(d); 693 694 JPanel seqNamePanel = new JPanel(new BorderLayout()); 695 seqNamePanel.add(jspSequence,BorderLayout.CENTER); 696 697 mainPane.add(jspSequence,BorderLayout.CENTER); 698 699 Border loweredbevel = BorderFactory.createLoweredBevelBorder(); 700 Border raisedbevel = BorderFactory.createRaisedBevelBorder(); 701 Border compound = BorderFactory.createCompoundBorder(raisedbevel,loweredbevel); 702 statusField.setBorder(compound); 703 statusField.setEditable(false); 704 statusField.setText("Current matrix: "+mat.getCurrentMatrixName()); 705 mainPane.add(statusField,BorderLayout.SOUTH); 706 707 addWindowListener(new winExit()); 708 pack(); 709 setLocation( (int)(dScreen.getWidth()-getWidth())/3, 710 (int)(dScreen.getHeight()-getHeight())/3 ); 711 } 712 713 getTotalWeight(Vector vseq)714 public static float getTotalWeight(Vector vseq) 715 { 716 float wgt = 0.f; 717 vseq = gsc.getSequenceCollection(); 718 Enumeration enumer = vseq.elements(); 719 while(enumer.hasMoreElements()) 720 { 721 Sequence s = (Sequence)enumer.nextElement(); 722 if(!s.getName().equals(Consensus.DEFAULT_SEQUENCE_NAME)) 723 wgt+=s.getWeight(); 724 } 725 return wgt; 726 } 727 728 729 /** 730 * 731 * Set the scoring matrix 732 * @param mat scoring matrix to use 733 * 734 */ setMatrix(Matrix mat)735 public void setMatrix(Matrix mat) 736 { 737 AlignJFrame.mat = mat; 738 } 739 740 /** 741 * 742 * Force a re-display of the sequences with a new colour 743 * scheme. 744 * @param hash hash of the colour scheme 745 * 746 */ repaintSequences(Hashtable hash)747 public void repaintSequences(Hashtable hash) 748 { 749 gsc.setColorScheme(hash); 750 gsc.repaint(); 751 } 752 753 /** 754 * 755 * Given a Vector of Sequence display them in the editor 756 * @param seqVector vector containing Sequence objects 757 * 758 */ openMethod(Vector seqVector)759 protected void openMethod(Vector seqVector) 760 { 761 gsc = new GraphicSequenceCollection(seqVector, 762 jspSequence,true,false,true,true, 763 statusField); 764 // set colour scheme 765 gsc.setColorScheme(SequenceProperties.residueColor); 766 currentColour = (Hashtable)SequenceProperties.residueColor.clone(); 767 residueColor.setSelected(true); 768 jspSequence.setViewportView(gsc); 769 770 colourScheme("Residue colour"); 771 } 772 773 774 /** 775 * 776 * Update the status bar with the selected colour scheme 777 * being used. 778 * @param colScheme name of colour scheme 779 * 780 */ colourScheme(String colScheme)781 protected void colourScheme(String colScheme) 782 { 783 String status = statusField.getText(); 784 int ncol = status.indexOf("Colour Scheme: "); 785 if(ncol > -1) 786 statusField.setText(status.substring(0,ncol)+ 787 "Colour Scheme: "+colScheme); 788 else 789 statusField.setText(status+" "+ 790 "Colour Scheme: "+colScheme); 791 drawColorBox.setSelected(true); 792 } 793 794 /** 795 * 796 * Constructs the colour menus 797 * 798 */ colourMenus(JMenu viewMenu)799 private void colourMenus(JMenu viewMenu) 800 { 801 final ButtonGroup group = new ButtonGroup(); 802 // an invisble radio button to workaround earlier versions of java 803 // which is selected only when user deselect "Colour boxes" option 804 final JRadioButton invisibleb = new JRadioButton(); 805 group.add(invisibleb); 806 drawColorBox = new JCheckBoxMenuItem("Colour boxes",true); 807 drawColorBox.addItemListener(new ItemListener() 808 { 809 ButtonModel lastSelection; 810 public void itemStateChanged(ItemEvent e) { 811 boolean selected = e.getStateChange() == ItemEvent.SELECTED; 812 gsc.setDrawColor(selected); 813 if(!selected){ 814 lastSelection = group.getSelection(); 815 //java6 has a group.clearSelection(); method that in the future 816 //can replace the invisible button workaround 817 invisibleb.setSelected(true); 818 } else if (invisibleb.isSelected()){ 819 lastSelection.setSelected(true); 820 } 821 } 822 }); 823 824 // property colour menus 825 JMenu propertyMenu = new JMenu("Colour by Property"); 826 viewMenu.add(propertyMenu); 827 828 JCheckBoxMenuItem acidColor = 829 new JCheckBoxMenuItem("Red=acidic, Blue=basic"); 830 propertyMenu.add(acidColor); 831 group.add(acidColor); 832 acidColor.addActionListener(new ActionListener() 833 { 834 public void actionPerformed(ActionEvent e) 835 { 836 gsc.setColorScheme(SequenceProperties.acidColor); 837 jspSequence.setViewportView(gsc); 838 currentColour = SequenceProperties.acidColor; 839 colourScheme("Red=acidic, Blue=basic"); 840 } 841 }); 842 843 JCheckBoxMenuItem polarColor = 844 new JCheckBoxMenuItem("Red=polar"); 845 propertyMenu.add(polarColor); 846 group.add(polarColor); 847 polarColor.addActionListener(new ActionListener() 848 { 849 public void actionPerformed(ActionEvent e) 850 { 851 gsc.setColorScheme(SequenceProperties.polarColor); 852 jspSequence.setViewportView(gsc); 853 currentColour = SequenceProperties.polarColor; 854 colourScheme("Red=polar"); 855 } 856 }); 857 858 JCheckBoxMenuItem hydrophobicColor = 859 new JCheckBoxMenuItem("Red=Hydrophobic"); 860 propertyMenu.add(hydrophobicColor); 861 group.add(hydrophobicColor); 862 hydrophobicColor.addActionListener(new ActionListener() 863 { 864 public void actionPerformed(ActionEvent e) 865 { 866 gsc.setColorScheme(SequenceProperties.hydrophobicColor); 867 jspSequence.setViewportView(gsc); 868 currentColour = SequenceProperties.hydrophobicColor; 869 colourScheme("Red=Hydrophobic"); 870 } 871 }); 872 873 JCheckBoxMenuItem aromaticColor = 874 new JCheckBoxMenuItem("Red=Aromatic, Blue=Aliphatic"); 875 propertyMenu.add(aromaticColor); 876 group.add(aromaticColor); 877 aromaticColor.addActionListener(new ActionListener() 878 { 879 public void actionPerformed(ActionEvent e) 880 { 881 gsc.setColorScheme(SequenceProperties.aromaticColor); 882 jspSequence.setViewportView(gsc); 883 currentColour = SequenceProperties.aromaticColor; 884 colourScheme("Red=Aromatic, Blue=Aliphatic"); 885 } 886 }); 887 888 JCheckBoxMenuItem surfaceColor = 889 new JCheckBoxMenuItem("Red=Surface, Blue=Buried"); 890 propertyMenu.add(surfaceColor); 891 group.add(surfaceColor); 892 surfaceColor.addActionListener(new ActionListener() 893 { 894 public void actionPerformed(ActionEvent e) 895 { 896 gsc.setColorScheme(SequenceProperties.surfaceColor); 897 jspSequence.setViewportView(gsc); 898 currentColour = SequenceProperties.surfaceColor; 899 colourScheme("Red=Surface, Blue=Buried"); 900 } 901 }); 902 903 JCheckBoxMenuItem chargeColor = 904 new JCheckBoxMenuItem("Red=Positive, Blue=Negative"); 905 propertyMenu.add(chargeColor); 906 group.add(chargeColor); 907 chargeColor.addActionListener(new ActionListener() 908 { 909 public void actionPerformed(ActionEvent e) 910 { 911 gsc.setColorScheme(SequenceProperties.chargeColor); 912 jspSequence.setViewportView(gsc); 913 currentColour = SequenceProperties.chargeColor; 914 colourScheme("Red=Positive, Blue=Negative"); 915 } 916 }); 917 918 JCheckBoxMenuItem sizeColor = 919 new JCheckBoxMenuItem("Red=Tiny, Green=Small, Blue=Large"); 920 propertyMenu.add(sizeColor); 921 group.add(sizeColor); 922 sizeColor.addActionListener(new ActionListener() 923 { 924 public void actionPerformed(ActionEvent e) 925 { 926 gsc.setColorScheme(SequenceProperties.sizeColor); 927 jspSequence.setViewportView(gsc); 928 currentColour = SequenceProperties.sizeColor; 929 colourScheme("Red=Tiny, Green=Small, Blue=Large"); 930 } 931 }); 932 933 // other colour schemes 934 JCheckBoxMenuItem taylor = new JCheckBoxMenuItem("Taylor Colour"); 935 viewMenu.add(taylor); 936 group.add(taylor); 937 taylor.addActionListener(new ActionListener() 938 { 939 public void actionPerformed(ActionEvent e) 940 { 941 gsc.setColorScheme(SequenceProperties.taylorColor); 942 jspSequence.setViewportView(gsc); 943 currentColour = SequenceProperties.taylorColor; 944 colourScheme("Taylor"); 945 } 946 }); 947 948 residueColor = new JCheckBoxMenuItem("Residue Colour"); 949 viewMenu.add(residueColor); 950 group.add(residueColor); 951 residueColor.addActionListener(new ActionListener() 952 { 953 public void actionPerformed(ActionEvent e) 954 { 955 gsc.setColorScheme(SequenceProperties.residueColor); 956 jspSequence.setViewportView(gsc); 957 currentColour = SequenceProperties.residueColor; 958 colourScheme("Residue"); 959 } 960 }); 961 962 JCheckBoxMenuItem rasmolColor = new JCheckBoxMenuItem("Rasmol Colour"); 963 viewMenu.add(rasmolColor); 964 group.add(rasmolColor); 965 rasmolColor.addActionListener(new ActionListener() 966 { 967 public void actionPerformed(ActionEvent e) 968 { 969 gsc.setColorScheme(SequenceProperties.rasmolColor); 970 jspSequence.setViewportView(gsc); 971 currentColour = SequenceProperties.rasmolColor; 972 colourScheme("Rasmol"); 973 } 974 }); 975 976 JCheckBoxMenuItem nuc = new JCheckBoxMenuItem("Nucleotide Colour"); 977 viewMenu.add(nuc); 978 group.add(nuc); 979 nuc.addActionListener(new ActionListener() 980 { 981 public void actionPerformed(ActionEvent e) 982 { 983 gsc.setColorScheme(SequenceProperties.baseColor); 984 jspSequence.setViewportView(gsc); 985 currentColour = SequenceProperties.baseColor; 986 colourScheme("Nucleotide"); 987 } 988 }); 989 viewMenu.add(new JSeparator()); 990 } 991 992 993 /** 994 * 995 * 996 * red, blue, cyan, darkGray, gray , green, lightGray, 997 * magenta , orange, pink, white, yellow, black 998 * 999 */ resolveColor(String[] args,int index)1000 private static Color resolveColor(String[] args,int index) 1001 { 1002 if(args[index].equalsIgnoreCase("red")) 1003 return Color.red; 1004 else if(args[index].equalsIgnoreCase("blue")) 1005 return Color.blue; 1006 else if(args[index].equalsIgnoreCase("black")) 1007 return Color.black; 1008 else if(args[index].equalsIgnoreCase("cyan")) 1009 return Color.cyan; 1010 else if(args[index].equalsIgnoreCase("darkGray")) 1011 return Color.darkGray; 1012 else if(args[index].equalsIgnoreCase("gray")) 1013 return Color.gray; 1014 else if(args[index].equalsIgnoreCase("green")) 1015 return Color.green; 1016 else if(args[index].equalsIgnoreCase("lightGray")) 1017 return Color.lightGray; 1018 else if(args[index].equalsIgnoreCase("magenta")) 1019 return Color.magenta; 1020 else if(args[index].equalsIgnoreCase("orange")) 1021 return Color.orange; 1022 else if(args[index].equalsIgnoreCase("pink")) 1023 return Color.pink; 1024 else if(args[index].equalsIgnoreCase("white")) 1025 return Color.white; 1026 else if(args[index].equalsIgnoreCase("yellow")) 1027 return Color.yellow; 1028 else if(args[index].equalsIgnoreCase("black")) 1029 return Color.black; 1030 1031 return null; 1032 } 1033 1034 /** 1035 * 1036 * Extends WindowAdapter to close window 1037 * 1038 */ 1039 class winExit extends WindowAdapter 1040 { windowClosing(WindowEvent we)1041 public void windowClosing(WindowEvent we) 1042 { 1043 dispose(); 1044 findPattern.dispose(); 1045 } 1046 } 1047 1048 main(String args[])1049 public static void main(String args[]) 1050 { 1051 AlignJFrame ajFrame = null; 1052 1053 if( args.length > 0 ) 1054 { 1055 for(int i=0;i<args.length;i++) 1056 { 1057 if(args[i].indexOf("-help") > -1) 1058 { 1059 System.out.println( 1060 "\n Jemboss Alignment Editor\n\n"+ 1061 "DESCRIPTION\n"+ 1062 "The Jemboss Alignment Editor can be used interactively to\n"+ 1063 "edit a sequence alignment (read in fasta or MSF format). It can\n"+ 1064 "also be used from the command line to produce image files\n"+ 1065 "of the alignment.\n\nUSAGE\n"+ 1066 "java org/emboss/jemboss/editor/AlignJFrame file [options]\n\n"+ 1067 "file This is the multiple sequence alignment in\n"+ 1068 " fasta or MSF format.\n\n"+ 1069 "OPTIONS\n"+ 1070 "-calc Calculate consensus and display under the alignment.\n"+ 1071 " The following 3 flags can be used to define values\n"+ 1072 " used in the calculations.\n"+ 1073 " -plu (plurality) minimum positive match score\n"+ 1074 " value for there to be a consensus.\n"+ 1075 " -numid minimum number of identities for there to\n"+ 1076 " be a consensus.\n"+ 1077 " -case minimum positive match score for setting\n"+ 1078 " the consensus to upper-case.\n"+ 1079 "-color Used to define a colour scheme, below is the list of\n"+ 1080 " available colour schemes:\n"+ 1081 " taylor\n"+ 1082 " residue\n"+ 1083 " rasmol\n"+ 1084 " acid\n"+ 1085 " polar\n"+ 1086 " hydrophobic\n"+ 1087 " aromatic\n"+ 1088 " surface\n"+ 1089 " charge\n"+ 1090 " size\n"+ 1091 " base\n\n"+ 1092 " java org.emboss.jemboss.editor.AlignJFrame file -color size\n\n"+ 1093 "-font Set the font size.\n"+ 1094 "-id Display a percentage ID pair table.\n"+ 1095 "-noshow Turns of the alignment display.\n"+ 1096 "-nres Number of residues to each line is a print out.\n"+ 1097 "-pretty EMBOSS prettyplot colour scheme. The -matrix flag option\n"+ 1098 " can be used to define a scoring matrix for identifying\n"+ 1099 " positive matches.\n"+ 1100 " -noBox switch off box drawing around identical and\n"+ 1101 " positive matches.\n"+ 1102 " -minID define the minimum number of identities. The\n"+ 1103 " default for this is the number of sequences\n"+ 1104 " in the file.\n"+ 1105 " -match define a threshold value for the number of\n"+ 1106 " positive matches, the default is half the\n"+ 1107 " total wgt.\n"+ 1108 " -colID define a lettering colour for the identities.\n"+ 1109 " -colIDBack define a background colour for identities.\n"+ 1110 " -colMatch define a lettering colour for positive matches.\n"+ 1111 " -colMatchBack define a background colour for positive\n"+ 1112 " matches.\n"+ 1113 " Available colour options:\n"+ 1114 " red, blue, cyan, darkGray, gray , green, lightGray,\n"+ 1115 " magenta , orange, pink, white, yellow, black\n"+ 1116 "-print Print the alignment image. The following 2 flags can be\n"+ 1117 " used along with the print flag\n"+ 1118 " -prefix prefix for image output file.\n"+ 1119 " -onePage fit the alignment to one page. This option must be\n"+ 1120 " be used with the -nres flag to define the residues\n"+ 1121 " per line.\n"+ 1122 " -type png or jpeg (default is jpeg).\n"+ 1123 " -antialias turn anti-aliasing on.\n"+ 1124 " -landscape Print as landscape (the default is portrait).\n"+ 1125 " -margin Define the left, right, top and bottom margin\n"+ 1126 " (in cm).\n"+ 1127 " java org.emboss.jemboss.editor.AlignJFrame file -matrix EBLOSUM62 \\\n"+ 1128 " -noshow -print -margin 0.5 0.5 0.5 0.5\n\n"+ 1129 "-matrix To define a scoring matrix. Used with the -pretty and -calc\n"+ 1130 " option.\n"+ 1131 "-list List the available scoring matrix files.\n\n"+ 1132 "EXAMPLE\n"+ 1133 "java org.emboss.jemboss.editor.AlignJFrame file -matrix EBLOSUM80 \\\n"+ 1134 " -pretty -noshow -id -print -type png\n\n"+ 1135 "java org.emboss.jemboss.editor.AlignJFrame file -matrix EPAM250 \\\n"+ 1136 " -pretty -colIDBack black -colID white -print \\\n"+ 1137 " -margin 0.5 0.5 0.5 0.0 -noshow\n"); 1138 System.exit(0); 1139 } 1140 } 1141 1142 File seqFile = new File(args[0]); 1143 if(seqFile.canRead()) 1144 { 1145 JembossParams jp = new JembossParams(); 1146 String ed = jp.getEmbossData(); 1147 Matrix m = new Matrix(ed, Matrix.DEFAULT_MATRIX); 1148 ajFrame = new AlignJFrame(true, m); 1149 SequenceReader sr = new SequenceReader(seqFile); 1150 sr.getSequenceFile(); 1151 ajFrame.openMethod(sr.getSequenceVector()); 1152 ajFrame.setTitle("Jemboss Alignment Viewer :: "+ 1153 seqFile.getName()); 1154 gsc.setMatrix(mat); 1155 } 1156 1157 String prefix = "output"; 1158 String type = "jpeg"; 1159 boolean show = true; 1160 boolean print = false; 1161 int nresiduesPerLine = 0; 1162 1163 float wgt = getTotalWeight(gsc.getSequenceCollection()); 1164 double lmargin = -0.5; // left margin 1165 double rmargin = -0.5; // right margin 1166 double tmargin = -0.5; // top margin 1167 double bmargin = -0.5; // bottom margin 1168 float plu = wgt/2.f; 1169 float cas = wgt/2.f; 1170 int ident = 0; 1171 int minID = gsc.getNumberSequences(); 1172 float match = wgt/2.f; 1173 Color colID = Color.red; 1174 Color colMatch = Color.blue; 1175 Color colIDBack = Color.white; 1176 Color colMatchBack = Color.white; 1177 boolean prettyBox = true; 1178 boolean landscape = false; 1179 boolean onePage = false; 1180 boolean antialias = false; 1181 1182 for(int i=0;i<args.length;i++) 1183 { 1184 if(args[i].indexOf("-matrix") > -1) 1185 { 1186 mat = new Matrix("resources/resources.jar", 1187 args[i+1]); 1188 gsc.setMatrix(mat); 1189 statusField.setText("Current matrix: "+args[i+1]); 1190 } 1191 else if(args[i].indexOf("-plu") > -1) 1192 plu = Float.parseFloat(args[i+1]); 1193 else if(args[i].indexOf("-match") > -1) 1194 match = Float.parseFloat(args[i+1]); 1195 else if(args[i].indexOf("-case") > -1) 1196 cas = Float.parseFloat(args[i+1]); 1197 else if(args[i].indexOf("-numid") > -1) 1198 ident = Integer.parseInt(args[i+1]); 1199 else if(args[i].indexOf("-colIDBack") > -1) 1200 { 1201 Color col = resolveColor(args,i+1); 1202 if(col != null) 1203 colIDBack = col; 1204 } 1205 else if(args[i].indexOf("-colMatchBack") > -1) 1206 { 1207 Color col = resolveColor(args,i+1); 1208 if(col != null) 1209 colMatchBack = col; 1210 } 1211 else if(args[i].indexOf("-colMatch") > -1) 1212 { 1213 Color col = resolveColor(args,i+1); 1214 if(col != null) 1215 colMatch = col; 1216 } 1217 else if(args[i].indexOf("-colID") > -1) 1218 { 1219 Color col = resolveColor(args,i+1); 1220 if(col != null) 1221 colID = col; 1222 } 1223 else if(args[i].indexOf("-minID") > -1) 1224 minID = Integer.parseInt(args[i+1]); 1225 else if(args[i].indexOf("-noBox") > -1) 1226 prettyBox = false; 1227 else if(args[i].indexOf("-font") > -1) 1228 gsc.setFontSizeForCollection(Integer.parseInt(args[i+1])); 1229 else if(args[i].indexOf("-landscape") > -1) 1230 landscape = true; 1231 else if(args[i].indexOf("-margin") > -1) 1232 { 1233 lmargin = Double.parseDouble(args[i+1]); 1234 rmargin = Double.parseDouble(args[i+2]); 1235 tmargin = Double.parseDouble(args[i+3]); 1236 bmargin = Double.parseDouble(args[i+4]); 1237 } 1238 else if(args[i].indexOf("-onePage") > -1) 1239 onePage = true; 1240 else if(args[i].indexOf("-antialias") > -1) 1241 antialias = true; 1242 } 1243 1244 for(int i=0;i<args.length;i++) 1245 { 1246 if(args[i].indexOf("-color") > -1) 1247 { 1248 i++; 1249 if(args[i].startsWith("taylor")) 1250 gsc.setColorScheme(SequenceProperties.taylorColor); 1251 else if(args[i].startsWith("residue")) 1252 gsc.setColorScheme(SequenceProperties.residueColor); 1253 else if(args[i].startsWith("rasmol")) 1254 gsc.setColorScheme(SequenceProperties.rasmolColor); 1255 else if(args[i].startsWith("acid")) 1256 gsc.setColorScheme(SequenceProperties.acidColor); 1257 else if(args[i].startsWith("polar")) 1258 gsc.setColorScheme(SequenceProperties.polarColor); 1259 else if(args[i].startsWith("hydro")) 1260 gsc.setColorScheme(SequenceProperties.hydrophobicColor); 1261 else if(args[i].startsWith("aromatic")) 1262 gsc.setColorScheme(SequenceProperties.aromaticColor); 1263 else if(args[i].startsWith("surface")) 1264 gsc.setColorScheme(SequenceProperties.surfaceColor); 1265 else if(args[i].startsWith("charge")) 1266 gsc.setColorScheme(SequenceProperties.chargeColor); 1267 else if(args[i].startsWith("size")) 1268 gsc.setColorScheme(SequenceProperties.sizeColor); 1269 else if(args[i].startsWith("base")) 1270 gsc.setColorScheme(SequenceProperties.baseColor); 1271 } 1272 else if(args[i].indexOf("-calc") > -1) 1273 { 1274 Consensus conseq = new Consensus(mat, 1275 gsc.getSequenceCollection(), 1276 plu,cas,ident); 1277 1278 int fontSize = gsc.getFontSize(); 1279 gsc.addSequence(conseq.getConsensusSequence(),true,5,fontSize); 1280 1281 Dimension dpane = gsc.getPanelSize(); 1282 gsc.setPreferredSize(dpane); 1283 gsc.setNamePanelWidth(gsc.getNameWidth()); 1284 } 1285 else if(args[i].indexOf("-list") > -1) 1286 System.out.println("AVAILABLE DATABASES:\n"+ 1287 mat.getKeyNamesString()); 1288 else if(args[i].indexOf("-id") > -1) 1289 { 1290 IDTableJFrame idtab = new IDTableJFrame(gsc.getSequenceCollection()); 1291 idtab.printTable(); 1292 } 1293 else if(args[i].indexOf("-noshow") > -1) 1294 show = false; 1295 else if(args[i].indexOf("-print") > -1) 1296 print = true; 1297 else if(args[i].indexOf("-nres") > -1) 1298 nresiduesPerLine = Integer.parseInt(args[i+1]); 1299 else if(args[i].indexOf("-pretty") > -1) 1300 { 1301 PrettyPlotJFrame pretty = new PrettyPlotJFrame(minID, 1302 match,colID,colMatch, 1303 colIDBack,colMatchBack,prettyBox); 1304 gsc.setPrettyPlot(true,pretty); 1305 gsc.setDrawBoxes(false); 1306 gsc.setDrawColor(false); 1307 } 1308 else if(args[i].indexOf("-preview") > -1) 1309 { 1310 PrintAlignmentImage pai = new PrintAlignmentImage(gsc); 1311 pai.printPreview(); 1312 show = true; 1313 } 1314 else if(args[i].indexOf("-type") > -1) 1315 { 1316 if( args[i+1].equalsIgnoreCase("png") || 1317 args[i+1].equalsIgnoreCase("jpeg") ) 1318 type = args[i+1]; 1319 else 1320 System.out.println("UNKOWN PRINT FORMAT: "+args[i+1]+ 1321 " reverting to default format "+type); 1322 } 1323 else if(args[i].indexOf("-prefix") > -1) 1324 prefix = args[i+1]; 1325 } 1326 1327 if(print) 1328 { 1329 if(onePage) 1330 { 1331 PrintAlignmentImage pai = new PrintAlignmentImage(gsc); 1332 if(antialias) 1333 pai.setAntiAlias(true); 1334 pai.print(nresiduesPerLine,type,prefix, 1335 lmargin,rmargin,tmargin,bmargin); 1336 } 1337 else 1338 { 1339 PrintAlignmentImage pai = new PrintAlignmentImage(gsc); 1340 if(antialias) 1341 pai.setAntiAlias(true); 1342 pai.print(nresiduesPerLine,type,prefix,landscape, 1343 lmargin,rmargin,tmargin,bmargin); 1344 } 1345 } 1346 if(!show) 1347 System.exit(0); 1348 } 1349 else 1350 { 1351 ajFrame = new AlignJFrame(true); 1352 } 1353 ajFrame.setVisible(true); 1354 } 1355 1356 1357 } 1358 1359