1 /* 2 * Jalview - A Sequence Alignment Editor and Viewer (2.11.1.4) 3 * Copyright (C) 2021 The Jalview Authors 4 * 5 * This file is part of Jalview. 6 * 7 * Jalview is free software: you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation, either version 3 10 * of the License, or (at your option) any later version. 11 * 12 * Jalview is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 15 * PURPOSE. See the GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>. 19 * The Jalview Authors are detailed in the 'AUTHORS' file. 20 */ 21 package jalview.appletgui; 22 23 import jalview.analysis.AAFrequency; 24 import jalview.api.FeatureColourI; 25 import jalview.datamodel.SequenceGroup; 26 import jalview.renderer.ResidueShader; 27 import jalview.schemes.Blosum62ColourScheme; 28 import jalview.schemes.ColourSchemeI; 29 import jalview.schemes.FeatureColour; 30 import jalview.schemes.PIDColourScheme; 31 import jalview.schemes.ResidueProperties; 32 import jalview.schemes.UserColourScheme; 33 import jalview.util.MessageManager; 34 35 import java.awt.Button; 36 import java.awt.Color; 37 import java.awt.Component; 38 import java.awt.Container; 39 import java.awt.Dialog; 40 import java.awt.Font; 41 import java.awt.Frame; 42 import java.awt.GridLayout; 43 import java.awt.Label; 44 import java.awt.Panel; 45 import java.awt.Rectangle; 46 import java.awt.Scrollbar; 47 import java.awt.TextField; 48 import java.awt.event.ActionEvent; 49 import java.awt.event.ActionListener; 50 import java.awt.event.AdjustmentEvent; 51 import java.awt.event.AdjustmentListener; 52 import java.awt.event.FocusEvent; 53 import java.awt.event.FocusListener; 54 import java.awt.event.MouseEvent; 55 import java.util.Vector; 56 57 public class UserDefinedColours extends Panel 58 implements ActionListener, AdjustmentListener, FocusListener 59 { 60 61 AlignmentPanel ap; 62 63 SequenceGroup seqGroup; 64 65 Button selectedButton; 66 67 Vector<Color> oldColours = new Vector<>(); 68 69 ColourSchemeI oldColourScheme; 70 71 Frame frame; 72 73 MCview.AppletPDBCanvas pdbcanvas; 74 75 AppletJmol jmol; 76 77 Dialog dialog; 78 79 Object caller; 80 81 String originalLabel; 82 83 FeatureColourI originalColour; 84 85 int R = 0, G = 0, B = 0; 86 loadDefaultColours()87 public ColourSchemeI loadDefaultColours() 88 { 89 // NOT IMPLEMENTED YET IN APPLET VERSION 90 return null; 91 } 92 UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)93 public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg) 94 { 95 this.ap = ap; 96 seqGroup = sg; 97 98 if (seqGroup != null) 99 { 100 oldColourScheme = seqGroup.getColourScheme(); 101 } 102 else 103 { 104 oldColourScheme = ap.av.getGlobalColourScheme(); 105 } 106 107 init(); 108 } 109 UserDefinedColours(MCview.AppletPDBCanvas pdb)110 public UserDefinedColours(MCview.AppletPDBCanvas pdb) 111 { 112 this.pdbcanvas = pdb; 113 init(); 114 } 115 UserDefinedColours(AppletJmol jmol)116 public UserDefinedColours(AppletJmol jmol) 117 { 118 this.jmol = jmol; 119 init(); 120 } 121 UserDefinedColours(FeatureRenderer fr, Frame alignframe)122 public UserDefinedColours(FeatureRenderer fr, Frame alignframe) 123 { 124 caller = fr; 125 originalColour = new FeatureColour(fr.colourPanel.getBackground()); 126 originalLabel = "Feature Colour"; 127 setForDialog("Select Feature Colour", alignframe); 128 setTargetColour(fr.colourPanel.getBackground()); 129 dialog.setVisible(true); 130 } 131 UserDefinedColours(Component caller, Color col1, Frame alignframe)132 public UserDefinedColours(Component caller, Color col1, Frame alignframe) 133 { 134 this(caller, col1, alignframe, "Select Colour"); 135 } 136 137 /** 138 * Makes a dialog to choose the colour 139 * 140 * @param caller 141 * - handles events 142 * @param col 143 * - original colour 144 * @param alignframe 145 * - the parent Frame for the dialog 146 * @param title 147 * - window title 148 */ UserDefinedColours(Component caller, Color col, Frame alignframe, String title)149 public UserDefinedColours(Component caller, Color col, Frame alignframe, 150 String title) 151 { 152 this.caller = caller; 153 originalColour = new FeatureColour(col); 154 originalLabel = title; 155 setForDialog(title, alignframe); 156 setTargetColour(col); 157 dialog.setVisible(true); 158 } 159 160 /** 161 * feature colour chooser 162 * 163 * @param caller 164 * @param label 165 * @param colour 166 */ UserDefinedColours(Object caller, String label, Color colour)167 public UserDefinedColours(Object caller, String label, Color colour) 168 { 169 this(caller, label, new FeatureColour(colour), colour); 170 } 171 172 /** 173 * feature colour chooser when changing style to single color 174 * 175 * @param me 176 * @param type 177 * @param graduatedColor 178 */ UserDefinedColours(FeatureSettings me, String type, FeatureColourI graduatedColor)179 public UserDefinedColours(FeatureSettings me, String type, 180 FeatureColourI graduatedColor) 181 { 182 this(me, type, graduatedColor, graduatedColor.getMaxColour()); 183 } 184 UserDefinedColours(Object caller, String label, FeatureColourI ocolour, Color colour)185 private UserDefinedColours(Object caller, String label, 186 FeatureColourI ocolour, Color colour) 187 { 188 this.caller = caller; 189 originalColour = ocolour; 190 originalLabel = label; 191 init(); 192 remove(buttonPanel); 193 194 setTargetColour(colour); 195 196 okcancelPanel.setBounds(new Rectangle(0, 113, 400, 35)); 197 frame.setTitle(MessageManager.getString("label.user_defined_colours") 198 + " - " + label); 199 frame.setSize(420, 200); 200 } 201 setForDialog(String title, Container alignframe)202 void setForDialog(String title, Container alignframe) 203 { 204 init(); 205 frame.setVisible(false); 206 remove(buttonPanel); 207 if (alignframe instanceof Frame) 208 { 209 dialog = new Dialog((Frame) alignframe, title, true); 210 } 211 else 212 { 213 // if (alignframe instanceof JVDialog){ 214 // // not 1.1 compatible! 215 // dialog = new Dialog(((JVDialog)alignframe), title, true); 216 // } else { 217 throw new Error(MessageManager.getString( 218 "label.error_unsupported_owwner_user_colour_scheme")); 219 } 220 221 dialog.add(this); 222 this.setSize(400, 123); 223 okcancelPanel.setBounds(new Rectangle(0, 123, 400, 35)); 224 int height = 160 + alignframe.getInsets().top + getInsets().bottom; 225 int width = 400; 226 227 dialog.setBounds( 228 alignframe.getBounds().x 229 + (alignframe.getSize().width - width) / 2, 230 alignframe.getBounds().y 231 + (alignframe.getSize().height - height) / 2, 232 width, height); 233 234 } 235 236 @Override actionPerformed(ActionEvent evt)237 public void actionPerformed(ActionEvent evt) 238 { 239 final Object source = evt.getSource(); 240 if (source == okButton) 241 { 242 okButton_actionPerformed(); 243 } 244 else if (source == applyButton) 245 { 246 applyButton_actionPerformed(); 247 } 248 else if (source == cancelButton) 249 { 250 cancelButton_actionPerformed(); 251 } 252 else if (source == rText) 253 { 254 rText_actionPerformed(); 255 } 256 else if (source == gText) 257 { 258 gText_actionPerformed(); 259 } 260 else if (source == bText) 261 { 262 bText_actionPerformed(); 263 } 264 } 265 266 @Override adjustmentValueChanged(AdjustmentEvent evt)267 public void adjustmentValueChanged(AdjustmentEvent evt) 268 { 269 if (evt.getSource() == rScroller) 270 { 271 rScroller_adjustmentValueChanged(); 272 } 273 else if (evt.getSource() == gScroller) 274 { 275 gScroller_adjustmentValueChanged(); 276 } 277 else if (evt.getSource() == bScroller) 278 { 279 bScroller_adjustmentValueChanged(); 280 } 281 } 282 init()283 void init() 284 { 285 try 286 { 287 jbInit(); 288 } catch (Exception e) 289 { 290 e.printStackTrace(); 291 } 292 frame = new Frame(); 293 frame.add(this); 294 jalview.bin.JalviewLite.addFrame(frame, 295 MessageManager.getString("label.user_defined_colours"), 420, 296 345); 297 298 if (seqGroup != null) 299 { 300 frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")"); 301 } 302 303 for (int i = 0; i < 20; i++) 304 { 305 makeButton(ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i]) 306 + "", ResidueProperties.aa[i]); 307 } 308 309 makeButton("B", "B"); 310 makeButton("Z", "Z"); 311 makeButton("X", "X"); 312 makeButton("Gap", "'.','-',' '"); 313 314 validate(); 315 } 316 rText_actionPerformed()317 protected void rText_actionPerformed() 318 { 319 try 320 { 321 int i = Integer.parseInt(rText.getText()); 322 rScroller.setValue(i); 323 rScroller_adjustmentValueChanged(); 324 } catch (NumberFormatException ex) 325 { 326 } 327 } 328 gText_actionPerformed()329 protected void gText_actionPerformed() 330 { 331 try 332 { 333 int i = Integer.parseInt(gText.getText()); 334 gScroller.setValue(i); 335 gScroller_adjustmentValueChanged(); 336 } catch (NumberFormatException ex) 337 { 338 } 339 340 } 341 bText_actionPerformed()342 protected void bText_actionPerformed() 343 { 344 try 345 { 346 int i = Integer.parseInt(bText.getText()); 347 bScroller.setValue(i); 348 bScroller_adjustmentValueChanged(); 349 } catch (NumberFormatException ex) 350 { 351 } 352 353 } 354 rScroller_adjustmentValueChanged()355 protected void rScroller_adjustmentValueChanged() 356 { 357 R = rScroller.getValue(); 358 rText.setText(R + ""); 359 colourChanged(); 360 } 361 gScroller_adjustmentValueChanged()362 protected void gScroller_adjustmentValueChanged() 363 { 364 G = gScroller.getValue(); 365 gText.setText(G + ""); 366 colourChanged(); 367 } 368 bScroller_adjustmentValueChanged()369 protected void bScroller_adjustmentValueChanged() 370 { 371 B = bScroller.getValue(); 372 bText.setText(B + ""); 373 colourChanged(); 374 } 375 colourChanged()376 public void colourChanged() 377 { 378 Color col = new Color(R, G, B); 379 target.setBackground(col); 380 target.repaint(); 381 382 if (selectedButton != null) 383 { 384 selectedButton.setBackground(col); 385 selectedButton.repaint(); 386 } 387 } 388 setTargetColour(Color col)389 void setTargetColour(Color col) 390 { 391 R = col.getRed(); 392 G = col.getGreen(); 393 B = col.getBlue(); 394 395 rScroller.setValue(R); 396 gScroller.setValue(G); 397 bScroller.setValue(B); 398 rText.setText(R + ""); 399 gText.setText(G + ""); 400 bText.setText(B + ""); 401 colourChanged(); 402 } 403 colourButtonPressed(MouseEvent e)404 public void colourButtonPressed(MouseEvent e) 405 { 406 selectedButton = (Button) e.getSource(); 407 setTargetColour(selectedButton.getBackground()); 408 } 409 makeButton(String label, String aa)410 void makeButton(String label, String aa) 411 { 412 final Button button = new Button(); 413 Color col = Color.white; 414 if (oldColourScheme != null && oldColourScheme.isSimple()) 415 { 416 col = oldColourScheme.findColour(aa.charAt(0), 0, null, null, 0f); 417 } 418 button.setBackground(col); 419 oldColours.addElement(col); 420 button.setLabel(label); 421 button.setForeground(col.darker().darker().darker()); 422 button.setFont(new java.awt.Font("Verdana", 1, 10)); 423 button.addMouseListener(new java.awt.event.MouseAdapter() 424 { 425 @Override 426 public void mousePressed(MouseEvent e) 427 { 428 colourButtonPressed(e); 429 } 430 }); 431 432 buttonPanel.add(button, null); 433 } 434 okButton_actionPerformed()435 protected void okButton_actionPerformed() 436 { 437 applyButton_actionPerformed(); 438 if (dialog != null) 439 { 440 dialog.setVisible(false); 441 } 442 443 frame.setVisible(false); 444 } 445 getColor()446 public Color getColor() 447 { 448 return new Color(R, G, B); 449 } 450 applyButton_actionPerformed()451 protected void applyButton_actionPerformed() 452 { 453 if (caller != null) 454 { 455 if (caller instanceof FeatureSettings) 456 { 457 ((FeatureSettings) caller).setUserColour(originalLabel, 458 new FeatureColour(getColor())); 459 } 460 else if (caller instanceof AnnotationColourChooser) 461 { 462 if (originalLabel.equals("Min Colour")) 463 { 464 ((AnnotationColourChooser) caller) 465 .minColour_actionPerformed(getColor()); 466 } 467 else 468 { 469 ((AnnotationColourChooser) caller) 470 .maxColour_actionPerformed(getColor()); 471 } 472 } 473 else if (caller instanceof FeatureRenderer) 474 { 475 ((FeatureRenderer) caller).colourPanel 476 .updateColor(new FeatureColour(getColor())); 477 } 478 else if (caller instanceof FeatureColourChooser) 479 { 480 if (originalLabel.indexOf("inimum") > -1) 481 { 482 ((FeatureColourChooser) caller) 483 .minColour_actionPerformed(getColor()); 484 } 485 else 486 { 487 ((FeatureColourChooser) caller) 488 .maxColour_actionPerformed(getColor()); 489 } 490 } 491 492 return; 493 } 494 495 Color[] newColours = new Color[24]; 496 for (int i = 0; i < 24; i++) 497 { 498 Button button = (Button) buttonPanel.getComponent(i); 499 newColours[i] = button.getBackground(); 500 } 501 502 UserColourScheme ucs = new UserColourScheme(newColours); 503 // if (ap != null) 504 // { 505 // ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); 506 // } 507 508 if (ap != null) 509 { 510 if (seqGroup != null) 511 { 512 seqGroup.cs = new ResidueShader(ucs); 513 seqGroup.getGroupColourScheme().setThreshold(0, 514 ap.av.isIgnoreGapsConsensus()); 515 } 516 else 517 { 518 ap.av.setGlobalColourScheme(ucs); 519 ap.av.getResidueShading().setThreshold(0, 520 ap.av.isIgnoreGapsConsensus()); 521 } 522 ap.seqPanel.seqCanvas.img = null; 523 ap.paintAlignment(true, true); 524 } 525 else if (jmol != null) 526 { 527 jmol.setJalviewColourScheme(ucs); 528 } 529 else if (pdbcanvas != null) 530 { 531 pdbcanvas.setColours(ucs); 532 } 533 } 534 cancelButton_actionPerformed()535 protected void cancelButton_actionPerformed() 536 { 537 if (caller != null) 538 { 539 if (caller instanceof FeatureSettings) 540 { 541 ((FeatureSettings) caller).setUserColour(originalLabel, 542 originalColour); 543 } 544 else if (caller instanceof AnnotationColourChooser) 545 { 546 if (originalLabel.equals("Min Colour")) 547 { 548 ((AnnotationColourChooser) caller) 549 .minColour_actionPerformed(originalColour.getColour()); 550 } 551 else 552 { 553 ((AnnotationColourChooser) caller) 554 .maxColour_actionPerformed(originalColour.getColour()); 555 } 556 } 557 else if (caller instanceof FeatureRenderer) 558 { 559 ((FeatureRenderer) caller).colourPanel.updateColor(originalColour); 560 561 } 562 563 else if (caller instanceof FeatureColourChooser) 564 { 565 if (originalLabel.indexOf("inimum") > -1) 566 { 567 ((FeatureColourChooser) caller) 568 .minColour_actionPerformed(originalColour.getColour()); 569 } 570 else 571 { 572 ((FeatureColourChooser) caller) 573 .maxColour_actionPerformed(originalColour.getColour()); 574 } 575 } 576 if (dialog != null) 577 { 578 dialog.setVisible(false); 579 } 580 581 frame.setVisible(false); 582 return; 583 } 584 585 if (ap != null) 586 { 587 if (seqGroup != null) 588 { 589 seqGroup.cs = new ResidueShader(oldColourScheme); 590 if (oldColourScheme instanceof PIDColourScheme 591 || oldColourScheme instanceof Blosum62ColourScheme) 592 { 593 seqGroup.cs.setConsensus(AAFrequency.calculate( 594 seqGroup.getSequences(ap.av.getHiddenRepSequences()), 0, 595 ap.av.getAlignment().getWidth())); 596 } 597 } 598 else 599 { 600 ap.av.setGlobalColourScheme(oldColourScheme); 601 } 602 ap.paintAlignment(true, true); 603 } 604 605 frame.setVisible(false); 606 } 607 608 protected Panel buttonPanel = new Panel(); 609 610 protected GridLayout gridLayout = new GridLayout(); 611 612 Panel okcancelPanel = new Panel(); 613 614 protected Button okButton = new Button(); 615 616 protected Button applyButton = new Button(); 617 618 protected Button cancelButton = new Button(); 619 620 protected Scrollbar rScroller = new Scrollbar(); 621 622 Label label1 = new Label(); 623 624 protected TextField rText = new TextField(); 625 626 Label label4 = new Label(); 627 628 protected Scrollbar gScroller = new Scrollbar(); 629 630 protected TextField gText = new TextField(); 631 632 Label label5 = new Label(); 633 634 protected Scrollbar bScroller = new Scrollbar(); 635 636 protected TextField bText = new TextField(); 637 638 protected Panel target = new Panel(); 639 jbInit()640 private void jbInit() throws Exception 641 { 642 this.setLayout(null); 643 buttonPanel.setLayout(gridLayout); 644 gridLayout.setColumns(6); 645 gridLayout.setRows(4); 646 okButton.setFont(new java.awt.Font("Verdana", 0, 11)); 647 okButton.setLabel(MessageManager.getString("action.ok")); 648 okButton.addActionListener(this); 649 applyButton.setFont(new java.awt.Font("Verdana", 0, 11)); 650 applyButton.setLabel(MessageManager.getString("action.apply")); 651 applyButton.addActionListener(this); 652 cancelButton.setFont(new java.awt.Font("Verdana", 0, 11)); 653 cancelButton.setLabel(MessageManager.getString("action.cancel")); 654 cancelButton.addActionListener(this); 655 this.setBackground(new Color(212, 208, 223)); 656 okcancelPanel.setBounds(new Rectangle(0, 265, 400, 35)); 657 buttonPanel.setBounds(new Rectangle(0, 123, 400, 142)); 658 rScroller.setMaximum(256); 659 rScroller.setMinimum(0); 660 rScroller.setOrientation(0); 661 rScroller.setUnitIncrement(1); 662 rScroller.setVisibleAmount(1); 663 rScroller.setBounds(new Rectangle(36, 27, 119, 19)); 664 rScroller.addAdjustmentListener(this); 665 label1.setAlignment(Label.RIGHT); 666 label1.setText("R"); 667 label1.setBounds(new Rectangle(19, 30, 16, 15)); 668 rText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10)); 669 rText.setText("0 "); 670 rText.setBounds(new Rectangle(156, 27, 53, 19)); 671 rText.addActionListener(this); 672 rText.addFocusListener(this); 673 label4.setAlignment(Label.RIGHT); 674 label4.setText("G"); 675 label4.setBounds(new Rectangle(15, 56, 20, 15)); 676 gScroller.setMaximum(256); 677 gScroller.setMinimum(0); 678 gScroller.setOrientation(0); 679 gScroller.setUnitIncrement(1); 680 gScroller.setVisibleAmount(1); 681 gScroller.setBounds(new Rectangle(35, 52, 120, 20)); 682 gScroller.addAdjustmentListener(this); 683 gText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10)); 684 gText.setText("0 "); 685 gText.setBounds(new Rectangle(156, 52, 53, 20)); 686 gText.addActionListener(this); 687 gText.addFocusListener(this); 688 label5.setAlignment(Label.RIGHT); 689 label5.setText("B"); 690 label5.setBounds(new Rectangle(14, 82, 20, 15)); 691 bScroller.setMaximum(256); 692 bScroller.setMinimum(0); 693 bScroller.setOrientation(0); 694 bScroller.setUnitIncrement(1); 695 bScroller.setVisibleAmount(1); 696 bScroller.setBounds(new Rectangle(35, 78, 120, 20)); 697 bScroller.addAdjustmentListener(this); 698 bText.setFont(new java.awt.Font("Dialog", Font.PLAIN, 10)); 699 bText.setText("0 "); 700 bText.setBounds(new Rectangle(157, 78, 52, 20)); 701 bText.addActionListener(this); 702 bText.addFocusListener(this); 703 target.setBackground(Color.black); 704 target.setBounds(new Rectangle(229, 26, 134, 79)); 705 this.add(okcancelPanel, null); 706 okcancelPanel.add(okButton, null); 707 okcancelPanel.add(applyButton, null); 708 okcancelPanel.add(cancelButton, null); 709 this.add(rText); 710 this.add(gText); 711 this.add(bText); 712 this.add(buttonPanel, null); 713 this.add(target, null); 714 this.add(gScroller); 715 this.add(rScroller); 716 this.add(bScroller); 717 this.add(label5); 718 this.add(label4); 719 this.add(label1); 720 } 721 722 @Override focusGained(FocusEvent e)723 public void focusGained(FocusEvent e) 724 { 725 // noop 726 } 727 728 /** 729 * This method applies any change to an RGB value if the user tabs out of the 730 * field instead of pressing Enter 731 */ 732 @Override focusLost(FocusEvent e)733 public void focusLost(FocusEvent e) 734 { 735 Component c = e.getComponent(); 736 if (c == rText) 737 { 738 rText_actionPerformed(); 739 } 740 else 741 { 742 if (c == gText) 743 { 744 gText_actionPerformed(); 745 } 746 else 747 { 748 if (c == bText) 749 { 750 bText_actionPerformed(); 751 } 752 } 753 } 754 } 755 756 } 757