2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
18 package jalview.appletgui;
23 import java.awt.event.*;
24 import java.awt.font.LineMetrics;
25 import java.awt.geom.AffineTransform;
27 import jalview.analysis.AAFrequency;
28 import jalview.datamodel.*;
29 import jalview.renderer.AnnotationRenderer;
30 import jalview.renderer.AwtRenderPanelI;
31 import jalview.schemes.ColourSchemeI;
33 public class AnnotationPanel extends Panel implements AwtRenderPanelI, AdjustmentListener,
34 ActionListener, MouseListener, MouseMotionListener
44 static String HELIX = "Helix";
46 static String SHEET = "Sheet";
48 static String LABEL = "Label";
50 static String REMOVE = "Remove Annotation";
52 static String COLOUR = "Colour";
54 static Color HELIX_COLOUR = Color.red.darker();
56 static Color SHEET_COLOUR = Color.green.darker().darker();
66 boolean fastPaint = false;
68 // Used For mouse Dragging and resizing graphs
69 int graphStretch = -1;
71 int graphStretchY = -1;
73 boolean mouseDragging = false;
75 public static int GRAPH_HEIGHT = 40;
79 public final AnnotationRenderer renderer;
81 public AnnotationPanel(AlignmentPanel ap)
83 MAC = new jalview.util.Platform().isAMac();
87 int height = adjustPanelHeight();
88 ap.apvscroll.setValues(0, getSize().height, 0, height);
90 addMouseMotionListener(this);
92 addMouseListener(this);
94 // ap.annotationScroller.getVAdjustable().addAdjustmentListener( this );
95 renderer = new AnnotationRenderer();
98 public AnnotationPanel(AlignViewport av)
101 renderer = new AnnotationRenderer();
104 public void adjustmentValueChanged(AdjustmentEvent evt)
114 public void actionPerformed(ActionEvent evt)
116 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
121 Annotation[] anot = aa[activeRow].annotations;
123 if (anot.length < av.getColumnSelection().getMax())
125 Annotation[] temp = new Annotation[av.getColumnSelection().getMax() + 2];
126 System.arraycopy(anot, 0, temp, 0, anot.length);
128 aa[activeRow].annotations = anot;
132 if (av.colSel != null && av.colSel.size() > 0
133 && anot[av.colSel.getMin()] != null)
134 label = anot[av.getColumnSelection().getMin()].displayCharacter;
136 if (evt.getActionCommand().equals(REMOVE))
138 for (int i = 0; i < av.getColumnSelection().size(); i++)
140 anot[av.getColumnSelection().columnAt(i)] = null;
143 else if (evt.getActionCommand().equals(LABEL))
145 label = enterLabel(label, "Enter Label");
152 if ((label.length() > 0) && !aa[activeRow].hasText)
154 aa[activeRow].hasText = true;
157 for (int i = 0; i < av.getColumnSelection().size(); i++)
159 int index = av.getColumnSelection().columnAt(i);
161 if (!av.colSel.isVisible(index))
164 if (anot[index] == null)
166 anot[index] = new Annotation(label, "", ' ', 0);
169 anot[index].displayCharacter = label;
172 else if (evt.getActionCommand().equals(COLOUR))
174 UserDefinedColours udc = new UserDefinedColours(this, Color.black,
177 Color col = udc.getColor();
179 for (int i = 0; i < av.getColumnSelection().size(); i++)
181 int index = av.getColumnSelection().columnAt(i);
183 if (!av.colSel.isVisible(index))
186 if (anot[index] == null)
188 anot[index] = new Annotation("", "", ' ', 0);
191 anot[index].colour = col;
198 String symbol = "\u03B1";
200 if (evt.getActionCommand().equals(HELIX))
204 else if (evt.getActionCommand().equals(SHEET))
210 if (!aa[activeRow].hasIcons)
212 aa[activeRow].hasIcons = true;
215 label = enterLabel(symbol, "Enter Label");
222 if ((label.length() > 0) && !aa[activeRow].hasText)
224 aa[activeRow].hasText = true;
227 for (int i = 0; i < av.getColumnSelection().size(); i++)
229 int index = av.getColumnSelection().columnAt(i);
231 if (!av.colSel.isVisible(index))
234 if (anot[index] == null)
236 anot[index] = new Annotation(label, "", type, 0);
239 anot[index].secondaryStructure = type;
240 anot[index].displayCharacter = label;
250 String enterLabel(String text, String label)
252 EditNameDialog dialog = new EditNameDialog(text, null, label, null,
253 ap.alignFrame, "Enter Label", 400, 200, true);
256 return dialog.getName();
261 public void mousePressed(MouseEvent evt)
263 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
269 int height = -scrollOffset;
272 for (int i = 0; i < aa.length; i++)
276 height += aa[i].height;
279 if (evt.getY() < height)
285 else if (aa[i].graph > 0)
289 graphStretchY = evt.getY();
296 if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK
299 if (av.getColumnSelection() == null)
304 PopupMenu pop = new PopupMenu("Structure type");
305 MenuItem item = new MenuItem(HELIX);
306 item.addActionListener(this);
308 item = new MenuItem(SHEET);
309 item.addActionListener(this);
311 item = new MenuItem(LABEL);
312 item.addActionListener(this);
314 item = new MenuItem(COLOUR);
315 item.addActionListener(this);
317 item = new MenuItem(REMOVE);
318 item.addActionListener(this);
320 ap.alignFrame.add(pop);
321 pop.show(this, evt.getX(), evt.getY());
331 ap.scalePanel.mousePressed(evt);
334 public void mouseReleased(MouseEvent evt)
338 mouseDragging = false;
342 needValidating = false;
344 ap.scalePanel.mouseReleased(evt);
347 public void mouseClicked(MouseEvent evt)
351 boolean needValidating = false;
353 public void mouseDragged(MouseEvent evt)
355 if (graphStretch > -1)
357 av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight += graphStretchY
359 if (av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight < 0)
361 av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight = 0;
363 graphStretchY = evt.getY();
365 needValidating = true;
366 ap.paintAlignment(true);
370 ap.scalePanel.mouseDragged(evt);
374 public void mouseMoved(MouseEvent evt)
376 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
383 int height = -scrollOffset;
384 for (int i = 0; i < aa.length; i++)
389 height += aa[i].height;
392 if (evt.getY() < height)
399 int res = evt.getX() / av.getCharWidth() + av.getStartRes();
401 if (av.hasHiddenColumns)
403 res = av.getColumnSelection().adjustForHiddenColumns(res);
406 if (row > -1 && res < aa[row].annotations.length
407 && aa[row].annotations[res] != null)
409 StringBuffer text = new StringBuffer("Sequence position " + (res + 1));
410 if (aa[row].annotations[res].description != null)
412 text.append(" " + aa[row].annotations[res].description);
414 ap.alignFrame.statusBar.setText(text.toString());
418 public void mouseEntered(MouseEvent evt)
420 ap.scalePanel.mouseEntered(evt);
423 public void mouseExited(MouseEvent evt)
425 ap.scalePanel.mouseExited(evt);
428 public int adjustPanelHeight()
430 return adjustPanelHeight(true);
433 public int adjustPanelHeight(boolean repaint)
435 int height = calcPanelHeight();
436 this.setSize(new Dimension(getSize().width, height));
444 * calculate the height for visible annotation, revalidating bounds where necessary
445 * ABSTRACT GUI METHOD
446 * @return total height of annotation
448 public int calcPanelHeight()
450 // setHeight of panels
451 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
456 for (int i = 0; i < aa.length; i++)
467 aa[i].height += av.charHeight;
477 aa[i].height += aa[i].graphHeight;
480 if (aa[i].height == 0)
485 height += aa[i].height;
497 public void addEditableColumn(int i)
501 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
507 for (int j = 0; j < aa.length; j++)
517 if (activeRes == null)
519 activeRes = new Vector();
520 activeRes.addElement(String.valueOf(i));
524 activeRes.addElement(String.valueOf(i));
527 public void update(Graphics g)
532 public void paint(Graphics g)
534 Dimension d = getSize();
536 // (av.endRes - av.startRes + 1) * av.charWidth;
537 if (imgWidth<1 || d.height<1)
541 if (image == null || imgWidth != image.getWidth(this) || d.height != image.getHeight(this))
543 image = createImage(imgWidth, d.height);
544 gg = image.getGraphics();
545 gg.setFont(av.getFont());
546 fm = gg.getFontMetrics();
552 g.drawImage(image, 0, 0, this);
557 gg.setColor(Color.white);
558 gg.fillRect(0, 0, getSize().width, getSize().height);
559 drawComponent(gg, av.startRes, av.endRes + 1);
561 g.drawImage(image, 0, 0, this);
564 public void fastPaint(int horizontal)
566 if (horizontal == 0 || av.alignment.getAlignmentAnnotation() == null
567 || av.alignment.getAlignmentAnnotation().length < 1)
573 gg.copyArea(0, 0, imgWidth, getSize().height, -horizontal
575 int sr = av.startRes, er = av.endRes + 1, transX = 0;
577 if (horizontal > 0) // scrollbar pulled right, image to the left
579 transX = (er - sr - horizontal) * av.charWidth;
580 sr = er - horizontal;
582 else if (horizontal < 0)
584 er = sr - horizontal;
587 gg.translate(transX, 0);
589 drawComponent(gg, sr, er);
591 gg.translate(-transX, 0);
607 public void drawComponent(Graphics g, int startRes, int endRes)
609 Font ofont = av.getFont();
612 g.setColor(Color.white);
613 g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getSize().height);
617 fm = g.getFontMetrics();
620 if ((av.alignment.getAlignmentAnnotation() == null)
621 || (av.alignment.getAlignmentAnnotation().length < 1))
623 g.setColor(Color.white);
624 g.fillRect(0, 0, getSize().width, getSize().height);
625 g.setColor(Color.black);
626 if (av.validCharWidth)
628 g.drawString("Alignment has no annotations", 20, 15);
633 renderer.drawComponent(this, av, g, activeRow, startRes, endRes);
636 int scrollOffset = 0;
638 public void setScrollOffset(int value)
640 scrollOffset = value;
645 public FontMetrics getFontMetrics()
651 public Image getFadedImage()
657 public int getFadedImageWidth()