2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 package jalview.appletgui;
23 import java.awt.event.*;
25 import jalview.datamodel.*;
27 public class AlignmentPanel
28 extends Panel implements AdjustmentListener
31 public AlignViewport av;
32 OverviewPanel overviewPanel;
35 IdwidthAdjuster idwidthAdjuster;
36 public AlignFrame alignFrame;
37 ScalePanel scalePanel;
38 AnnotationPanel annotationPanel;
39 AnnotationLabels alabels;
41 // this value is set false when selection area being dragged
42 boolean fastPaint = true;
44 public AlignmentPanel(AlignFrame af, final AlignViewport av)
57 seqPanel = new SeqPanel(av, this);
58 idPanel = new IdPanel(av, this);
59 scalePanel = new ScalePanel(av, this);
60 idwidthAdjuster = new IdwidthAdjuster(this);
61 annotationPanel = new AnnotationPanel(this);
63 sequenceHolderPanel.add(annotationPanel, BorderLayout.SOUTH);
65 alabels = new AnnotationLabels(this);
67 setAnnotationVisible(av.showAnnotation);
69 idPanelHolder.add(idPanel, BorderLayout.CENTER);
70 idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);
71 annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);
72 scalePanelHolder.add(scalePanel, BorderLayout.CENTER);
73 seqPanelHolder.add(seqPanel, BorderLayout.CENTER);
76 setScrollValues(0, 0);
78 hscroll.addAdjustmentListener(this);
79 vscroll.addAdjustmentListener(this);
81 addComponentListener(new ComponentAdapter()
83 public void componentResized(ComponentEvent evt)
85 setScrollValues(av.getStartRes(), av.getStartSeq());
90 Dimension d = calculateIdWidth();
91 idPanel.idCanvas.setSize(d);
93 hscrollFillerPanel.setSize(d.width, annotationPanel.getSize().height);
95 idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);
96 annotationSpaceFillerHolder.setSize(d.width,
97 annotationPanel.getSize().height);
98 alabels.setSize(d.width, annotationPanel.getSize().height);
100 final AlignmentPanel ap = this;
101 av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
103 public void propertyChange(java.beans.PropertyChangeEvent evt)
105 if (evt.getPropertyName().equals("alignment"))
107 PaintRefresher.Refresh(ap,
108 av.getSequenceSetId(),
118 public SequenceRenderer getSequenceRenderer()
120 return seqPanel.seqCanvas.sr;
123 public FeatureRenderer getFeatureRenderer()
125 return seqPanel.seqCanvas.fr;
128 public void alignmentChanged()
130 av.alignmentChanged(this);
132 if (overviewPanel != null)
134 overviewPanel.updateOverviewImage();
137 alignFrame.updateEditMenuBar();
142 public void fontChanged()
144 // set idCanvas bufferedImage to null
145 // to prevent drawing old image
146 idPanel.idCanvas.image = null;
147 FontMetrics fm = getFontMetrics(av.getFont());
149 scalePanel.setSize(new Dimension(10, av.charHeight + fm.getDescent()));
150 idwidthAdjuster.setSize(new Dimension(10, av.charHeight + fm.getDescent()));
151 av.updateSequenceIdColours();
152 annotationPanel.image = null;
153 int ap = annotationPanel.adjustPanelHeight();
154 annotationPanel.repaint();
155 Dimension d = calculateIdWidth();
156 d.setSize(d.width + 4, seqPanel.seqCanvas.getSize().height);
157 alabels.setSize(d.width + 4, ap);
158 idPanel.idCanvas.setSize(d);
159 hscrollFillerPanel.setSize(d);
164 if (overviewPanel != null)
166 overviewPanel.updateOverviewImage();
170 public void setIdWidth(int w, int h)
172 idPanel.idCanvas.setSize(w, h);
173 idPanelHolder.setSize(w, idPanelHolder.getSize().height);
174 alabels.setSize(w, alabels.getSize().height);
178 Dimension calculateIdWidth()
180 if (av.nullFrame == null)
182 av.nullFrame = new Frame();
183 av.nullFrame.addNotify();
186 Graphics g = av.nullFrame.getGraphics();
188 FontMetrics fm = g.getFontMetrics(av.font);
189 AlignmentI al = av.getAlignment();
194 while (i < al.getHeight() && al.getSequenceAt(i) != null)
196 SequenceI s = al.getSequenceAt(i);
197 id = s.getDisplayId(av.getShowJVSuffix());
199 if (fm.stringWidth(id) > idWidth)
201 idWidth = fm.stringWidth(id);
206 // Also check annotation label widths
208 if (al.getAlignmentAnnotation() != null)
210 fm = g.getFontMetrics(av.nullFrame.getFont());
211 while (i < al.getAlignmentAnnotation().length)
213 String label = al.getAlignmentAnnotation()[i].label;
214 if (fm.stringWidth(label) > idWidth)
216 idWidth = fm.stringWidth(label);
222 return new Dimension(idWidth, idPanel.idCanvas.getSize().height);
225 public void highlightSearchResults(SearchResults results)
227 seqPanel.seqCanvas.highlightSearchResults(results);
229 // do we need to scroll the panel?
232 SequenceI seq = results.getResultSequence(0);
233 int seqIndex = av.alignment.findIndex(seq);
234 int start = seq.findIndex(results.getResultStart(0)) - 1;
235 int end = seq.findIndex(results.getResultEnd(0)) - 1;
237 if (!av.wrapAlignment)
239 if ( (av.getStartRes() > end) || (av.getEndRes() < start) ||
240 ( (av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))
242 if (start > av.alignment.getWidth() - hextent)
244 start = av.alignment.getWidth() - hextent;
250 if (seqIndex > av.alignment.getHeight() - vextent)
252 seqIndex = av.alignment.getHeight() - vextent;
258 setScrollValues(start, seqIndex);
263 scrollToWrappedVisible(start);
270 void scrollToWrappedVisible(int res)
272 int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.
274 if (res <= av.getStartRes() || res >= (av.getStartRes() + cwidth))
276 vscroll.setValue(res / cwidth);
277 av.startRes = vscroll.getValue() * cwidth;
281 public OverviewPanel getOverviewPanel()
283 return overviewPanel;
286 public void setOverviewPanel(OverviewPanel op)
291 public void setAnnotationVisible(boolean b)
293 if (!av.wrapAlignment)
295 annotationSpaceFillerHolder.setVisible(b);
296 annotationPanel.setVisible(b);
302 public void setWrapAlignment(boolean wrap)
306 scalePanelHolder.setVisible(!wrap);
308 hscroll.setVisible(!wrap);
309 idwidthAdjuster.setVisible(!wrap);
313 annotationPanel.setVisible(false);
314 annotationSpaceFillerHolder.setVisible(false);
316 else if (av.showAnnotation)
318 annotationPanel.setVisible(true);
319 annotationSpaceFillerHolder.setVisible(true);
322 idSpaceFillerPanel1.setVisible(!wrap);
324 fontChanged(); //This is so that the scalePanel is resized correctly
334 // return value is true if the scroll is valid
335 public boolean scrollUp(boolean up)
339 if (vscroll.getValue() < 1)
343 setScrollValues(hscroll.getValue(), vscroll.getValue() - 1);
347 if (vextent + vscroll.getValue() >= av.getAlignment().getHeight())
351 setScrollValues(hscroll.getValue(), vscroll.getValue() + 1);
358 public boolean scrollRight(boolean right)
362 if (hscroll.getValue() < 1)
366 setScrollValues(hscroll.getValue() - 1, vscroll.getValue());
370 if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())
374 setScrollValues(hscroll.getValue() + 1, vscroll.getValue());
381 public void setScrollValues(int x, int y)
383 int width = av.alignment.getWidth();
384 int height = av.alignment.getHeight();
386 if (av.hasHiddenColumns)
388 width = av.getColumnSelection().findColumnPosition(width);
392 av.setEndRes( (x + (seqPanel.seqCanvas.getSize().width / av.charWidth)) - 1);
394 hextent = seqPanel.seqCanvas.getSize().width / av.charWidth;
395 vextent = seqPanel.seqCanvas.getSize().height / av.charHeight;
402 if (vextent > height)
407 if ( (hextent + x) > width)
412 if ( (vextent + y) > height)
414 y = height - vextent;
429 int endSeq = y + vextent;
430 if (endSeq > av.alignment.getHeight())
432 endSeq = av.alignment.getHeight();
435 av.setEndSeq(endSeq);
436 hscroll.setValues(x, hextent, 0, width);
437 vscroll.setValues(y, vextent, 0, height);
439 if (overviewPanel != null)
441 overviewPanel.setBoxPosition();
446 public void adjustmentValueChanged(AdjustmentEvent evt)
448 int oldX = av.getStartRes();
449 int oldY = av.getStartSeq();
451 if (evt == null || evt.getSource() == hscroll)
453 int x = hscroll.getValue();
455 av.setEndRes(x + seqPanel.seqCanvas.getSize().width / av.getCharWidth() -
459 if (evt == null || evt.getSource() == vscroll)
461 int offy = vscroll.getValue();
462 if (av.getWrapAlignment())
464 int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.
465 seqCanvas.getSize().width);
466 av.setStartRes(vscroll.getValue() * rowSize);
467 av.setEndRes( (vscroll.getValue() + 1) * rowSize);
471 av.setStartSeq(offy);
473 seqPanel.seqCanvas.getSize().height / av.getCharHeight());
477 if (overviewPanel != null)
479 overviewPanel.setBoxPosition();
482 int scrollX = av.startRes - oldX;
483 int scrollY = av.startSeq - oldY;
485 if (av.getWrapAlignment() || !fastPaint || av.MAC)
491 // Make sure we're not trying to draw a panel
492 // larger than the visible window
493 if (scrollX > av.endRes - av.startRes)
495 scrollX = av.endRes - av.startRes;
497 else if (scrollX < av.startRes - av.endRes)
499 scrollX = av.startRes - av.endRes;
502 idPanel.idCanvas.fastPaint(scrollY);
503 seqPanel.seqCanvas.fastPaint(scrollX,
506 scalePanel.repaint();
507 if (av.getShowAnnotation())
509 annotationPanel.fastPaint(av.getStartRes() - oldX);
515 public void paintAlignment(boolean updateOverview)
521 jalview.structure.StructureSelectionManager.getStructureSelectionManager()
522 .sequenceColoursChanged(this);
524 if (overviewPanel != null)
526 overviewPanel.updateOverviewImage();
531 public void update(Graphics g)
536 public void paint(Graphics g)
539 Dimension d = idPanel.idCanvas.getSize();
540 idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);
541 annotationSpaceFillerHolder.setSize(d.width,
542 annotationPanel.getSize().height);
544 alabels.setSize(d.width, annotationPanel.getSize().height);
546 if (av.getWrapAlignment())
548 int maxwidth = av.alignment.getWidth();
550 if (av.hasHiddenColumns)
552 maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
555 int canvasWidth = seqPanel.seqCanvas.getWrappedCanvasWidth
556 (seqPanel.seqCanvas.getSize().width);
560 int max = maxwidth / canvasWidth;
561 vscroll.setMaximum(max);
562 vscroll.setUnitIncrement(1);
563 vscroll.setVisibleAmount(1);
568 setScrollValues(av.getStartRes(), av.getStartSeq());
573 seqPanel.seqCanvas.repaint();
574 scalePanel.repaint();
575 annotationPanel.repaint();
576 idPanel.idCanvas.repaint();
579 protected Panel sequenceHolderPanel = new Panel();
580 protected Scrollbar vscroll = new Scrollbar();
581 protected Scrollbar hscroll = new Scrollbar();
582 protected Panel seqPanelHolder = new Panel();
583 BorderLayout borderLayout1 = new BorderLayout();
584 BorderLayout borderLayout3 = new BorderLayout();
585 protected Panel scalePanelHolder = new Panel();
586 protected Panel idPanelHolder = new Panel();
587 BorderLayout borderLayout5 = new BorderLayout();
588 protected Panel idSpaceFillerPanel1 = new Panel();
589 public Panel annotationSpaceFillerHolder = new Panel();
590 BorderLayout borderLayout6 = new BorderLayout();
591 BorderLayout borderLayout7 = new BorderLayout();
592 Panel hscrollHolder = new Panel();
593 BorderLayout borderLayout10 = new BorderLayout();
594 protected Panel hscrollFillerPanel = new Panel();
595 BorderLayout borderLayout11 = new BorderLayout();
596 BorderLayout borderLayout4 = new BorderLayout();
597 BorderLayout borderLayout2 = new BorderLayout();
599 private void jbInit()
602 // idPanelHolder.setPreferredSize(new Dimension(70, 10));
603 this.setLayout(borderLayout7);
605 // sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));
606 sequenceHolderPanel.setLayout(borderLayout3);
607 seqPanelHolder.setLayout(borderLayout1);
608 scalePanelHolder.setBackground(Color.white);
610 // scalePanelHolder.setPreferredSize(new Dimension(10, 30));
611 scalePanelHolder.setLayout(borderLayout6);
612 idPanelHolder.setLayout(borderLayout5);
613 idSpaceFillerPanel1.setBackground(Color.white);
615 // idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));
616 idSpaceFillerPanel1.setLayout(borderLayout11);
617 annotationSpaceFillerHolder.setBackground(Color.white);
619 // annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));
620 annotationSpaceFillerHolder.setLayout(borderLayout4);
621 hscroll.setOrientation(Scrollbar.HORIZONTAL);
622 hscrollHolder.setLayout(borderLayout10);
623 hscrollFillerPanel.setBackground(Color.white);
625 // hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));
626 hscrollHolder.setBackground(Color.white);
628 // annotationScroller.setPreferredSize(new Dimension(10, 80));
629 // this.setPreferredSize(new Dimension(220, 166));
630 seqPanelHolder.setBackground(Color.white);
631 idPanelHolder.setBackground(Color.white);
632 sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);
633 sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);
634 seqPanelHolder.add(vscroll, BorderLayout.EAST);
636 // Panel3.add(secondaryPanelHolder, BorderLayout.SOUTH);
637 this.add(idPanelHolder, BorderLayout.WEST);
638 idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);
639 idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);
640 this.add(hscrollHolder, BorderLayout.SOUTH);
641 hscrollHolder.add(hscroll, BorderLayout.CENTER);
642 hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);
643 this.add(sequenceHolderPanel, BorderLayout.CENTER);