2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
3 * Copyright (C) 2010 J Procter, AM Waterhouse, 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.image.BufferedImage;
26 import jalview.datamodel.*;
28 public class AnnotationLabels extends Panel implements ActionListener,
29 MouseListener, MouseMotionListener
33 boolean active = false;
39 boolean resizing = false;
43 static String ADDNEW = "Add New Row";
45 static String EDITNAME = "Edit Label/Description";
47 static String HIDE = "Hide This Row";
49 static String SHOWALL = "Show All Hidden Rows";
51 static String OUTPUT_TEXT = "Show Values In Textbox";
53 static String COPYCONS_SEQ = "Copy Consensus Sequence";
61 private boolean hasHiddenRows;
63 public AnnotationLabels(AlignmentPanel ap)
70 * this retrieves the adjustable height glyph from resources. we don't use it at the moment.
71 java.net.URL url = getClass().getResource("/images/idwidth.gif");
76 temp = java.awt.Toolkit.getDefaultToolkit().createImage(url);
81 MediaTracker mt = new MediaTracker(this);
84 } catch (Exception ex)
88 BufferedImage bi = new BufferedImage(temp.getHeight(this),
89 temp.getWidth(this), BufferedImage.TYPE_INT_RGB);
90 Graphics2D g = (Graphics2D) bi.getGraphics();
91 g.rotate(Math.toRadians(90));
92 g.drawImage(temp, 0, -bi.getWidth(this), this);
95 addMouseListener(this);
96 addMouseMotionListener(this);
99 public AnnotationLabels(AlignViewport av)
104 public void setScrollOffset(int y)
113 * @return -2 if no rows are visible at all, -1 if no visible rows were
116 int getSelectedRow(int y)
119 AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();
126 for (int i = 0; i < aa.length; i++)
133 height += aa[i].height;
144 public void actionPerformed(ActionEvent evt)
146 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
148 if (evt.getActionCommand().equals(ADDNEW))
150 AlignmentAnnotation newAnnotation = new AlignmentAnnotation("", null,
151 new Annotation[ap.av.alignment.getWidth()]);
153 if (!editLabelDescription(newAnnotation))
158 ap.av.alignment.addAnnotation(newAnnotation);
159 ap.av.alignment.setAnnotationIndex(newAnnotation, 0);
161 else if (evt.getActionCommand().equals(EDITNAME))
163 editLabelDescription(aa[selectedRow]);
165 else if (evt.getActionCommand().equals(HIDE))
167 aa[selectedRow].visible = false;
169 else if (evt.getActionCommand().equals(SHOWALL))
171 for (int i = 0; i < aa.length; i++)
173 aa[i].visible = (aa[i].annotations == null) ? false : true;
176 else if (evt.getActionCommand().equals(OUTPUT_TEXT))
178 CutAndPasteTransfer cap = new CutAndPasteTransfer(false,
180 Frame frame = new Frame();
182 jalview.bin.JalviewLite.addFrame(frame, ap.alignFrame.getTitle()
183 + " - " + aa[selectedRow].label, 500, 100);
184 cap.setText(aa[selectedRow].toString());
186 else if (evt.getActionCommand().equals(COPYCONS_SEQ))
188 SequenceI cons = av.getConsensusSeq();
191 copy_annotseqtoclipboard(cons);
195 ap.annotationPanel.adjustPanelHeight();
196 setSize(getSize().width, ap.annotationPanel.getSize().height);
198 ap.paintAlignment(true);
201 boolean editLabelDescription(AlignmentAnnotation annotation)
203 Checkbox padGaps = new Checkbox("Fill Empty Gaps With \""
204 + ap.av.getGapCharacter() + "\"", annotation.padGaps);
206 EditNameDialog dialog = new EditNameDialog(annotation.label,
207 annotation.description, " Annotation Label",
208 "Annotation Description", ap.alignFrame,
209 "Edit Annotation Name / Description", 500, 180, false);
211 Panel empty = new Panel(new FlowLayout());
216 dialog.setVisible(true);
220 annotation.label = dialog.getName();
221 annotation.description = dialog.getDescription();
222 annotation.setPadGaps(padGaps.getState(), av.getGapCharacter());
231 boolean resizePanel = false;
233 public void mouseMoved(MouseEvent evt)
235 resizePanel = evt.getY() < 10;
237 int row = getSelectedRow(evt.getY() + scrollOffset);
243 tooltip = new Tooltip(
244 ap.av.alignment.getAlignmentAnnotation()[row]
245 .getDescription(true),
250 tooltip.setTip(ap.av.alignment.getAlignmentAnnotation()[row]
251 .getDescription(true));
254 else if (tooltip != null)
261 MouseEvent dragEvent = null;
263 public void mouseDragged(MouseEvent evt)
269 Dimension d = ap.annotationPanelHolder.getSize(),e = ap.annotationSpaceFillerHolder.getSize();;
270 int dif = evt.getY() - oldY;
272 dif /= ap.av.charHeight;
273 dif *= ap.av.charHeight;
275 if ((d.height - dif) > 20)
278 setSize(new Dimension(e.width,d.height-dif));
279 ap.annotationSpaceFillerHolder.setSize(new Dimension(e.width, d.height - dif));
280 ap.annotationPanelHolder.setSize(new Dimension(d.width, d.height - dif));
281 ap.apvscroll.setValues(ap.apvscroll.getValue(), d.height-dif, 0, ap.annotationPanel.adjustPanelHeight(false));
284 //ap.paintAlignment(true);
295 public void mouseClicked(MouseEvent evt)
299 public void mouseReleased(MouseEvent evt)
304 ap.annotationPanel.repaint();
307 public void mouseEntered(MouseEvent evt)
316 public void mouseExited(MouseEvent evt)
319 if (dragEvent == null)
333 public void mousePressed(MouseEvent evt)
336 // todo: move below to mouseClicked ?
337 selectedRow = getSelectedRow(evt.getY() + scrollOffset);
339 AlignmentAnnotation[] aa = ap.av.alignment.getAlignmentAnnotation();
341 // DETECT RIGHT MOUSE BUTTON IN AWT
342 if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK)
345 PopupMenu popup = new PopupMenu("Annotations");
347 MenuItem item = new MenuItem(ADDNEW);
348 item.addActionListener(this);
352 // this never happens at moment: - see comment on JAL-563
355 item = new MenuItem(SHOWALL);
356 item.addActionListener(this);
360 popup.show(this, evt.getX(), evt.getY());
363 // add the rest if there are actually rows to show
364 item = new MenuItem(EDITNAME);
365 item.addActionListener(this);
367 item = new MenuItem(HIDE);
368 item.addActionListener(this);
372 item = new MenuItem(SHOWALL);
373 item.addActionListener(this);
377 item = new MenuItem(OUTPUT_TEXT);
378 item.addActionListener(this);
381 if (aa[selectedRow] == ap.av.consensus)
383 popup.addSeparator();
384 final CheckboxMenuItem cbmi = new CheckboxMenuItem(
385 "Ignore Gaps In Consensus", ap.av.getIgnoreGapsConsensus());
387 cbmi.addItemListener(new ItemListener()
389 public void itemStateChanged(ItemEvent e)
391 ap.av.setIgnoreGapsConsensus(cbmi.getState());
392 ap.paintAlignment(true);
396 item = new MenuItem(COPYCONS_SEQ);
397 item.addActionListener(this);
401 popup.show(this, evt.getX(), evt.getY());
406 if (selectedRow > -1 && selectedRow < aa.length)
408 if (aa[selectedRow].groupRef != null)
410 if (evt.getClickCount() >= 2)
412 // todo: make the ap scroll to the selection - not necessary, first
413 // click highlights/scrolls, second selects
414 ap.seqPanel.ap.idPanel.highlightSearchResults(null);
415 ap.av.setSelectionGroup(// new SequenceGroup(
416 aa[selectedRow].groupRef); // );
417 ap.av.sendSelection();
418 ap.paintAlignment(false);
419 PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
423 ap.seqPanel.ap.idPanel
424 .highlightSearchResults(aa[selectedRow].groupRef
425 .getSequences(null));
429 else if (aa[selectedRow].sequenceRef != null)
431 Vector sr = new Vector();
432 sr.addElement(aa[selectedRow].sequenceRef);
433 if (evt.getClickCount() == 1)
435 ap.seqPanel.ap.idPanel.highlightSearchResults(sr);
437 else if (evt.getClickCount() >= 2)
439 ap.seqPanel.ap.idPanel.highlightSearchResults(null);
440 SequenceGroup sg = new SequenceGroup();
441 sg.addSequence(aa[selectedRow].sequenceRef, false);
442 ap.av.setSelectionGroup(sg);
443 ap.paintAlignment(false);
444 PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
445 ap.av.sendSelection();
460 protected void copy_annotseqtoclipboard(SequenceI sq)
462 if (sq == null || sq.getLength() < 1)
466 jalview.appletgui.AlignFrame.copiedSequences = new StringBuffer();
467 jalview.appletgui.AlignFrame.copiedSequences.append(sq.getName() + "\t"
468 + sq.getStart() + "\t" + sq.getEnd() + "\t"
469 + sq.getSequenceAsString() + "\n");
470 if (av.hasHiddenColumns)
472 jalview.appletgui.AlignFrame.copiedHiddenColumns = new Vector();
473 for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)
475 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
478 jalview.appletgui.AlignFrame.copiedHiddenColumns
479 .addElement(new int[]
480 { region[0], region[1] });
485 public void update(Graphics g)
490 public void paint(Graphics g)
492 int w = getSize().width;
493 if (image == null || w != image.getWidth(this))
495 image = createImage(w, ap.annotationPanel.getSize().height);
498 drawComponent(image.getGraphics(), w);
499 g.drawImage(image, 0, 0, this);
502 public void drawComponent(Graphics g, int width)
504 g.setFont(av.getFont());
505 FontMetrics fm = g.getFontMetrics(av.getFont());
506 g.setColor(Color.white);
507 g.fillRect(0, 0, getSize().width, getSize().height);
509 g.translate(0, -scrollOffset);
510 g.setColor(Color.black);
512 AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
513 int y = 0, fy = g.getFont().getSize();
518 hasHiddenRows = false;
519 for (int i = 0; i < aa.length; i++)
523 hasHiddenRows = true;
527 x = width - fm.stringWidth(aa[i].label) - 3;
530 offset = -(aa[i].height - fy) / 2;
532 g.drawString(aa[i].label, x, y + offset);
535 g.translate(0, +scrollOffset);
538 g.setColor(Color.red);
540 g.drawLine(2, 8, 5, 2);
541 g.drawLine(5, 2, 8, 8);
543 else if (dragEvent != null && aa != null)
545 g.setColor(Color.lightGray);
546 g.drawString(aa[selectedRow].label, dragEvent.getX(),
550 if ((aa == null) || (aa.length < 1))
552 g.setColor(Color.black);
553 g.drawString("Right click", 2, 8);
554 g.drawString("to add annotation", 2, 18);