2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
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
10 * of the License, or (at your option) any later version.
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.
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.
21 package jalview.appletgui;
23 import jalview.datamodel.SequenceI;
24 import jalview.renderer.seqfeatures.FeatureColourFinder;
25 import jalview.viewmodel.OverviewDimensions;
27 import java.awt.Color;
28 import java.awt.Dimension;
29 import java.awt.Frame;
30 import java.awt.Graphics;
31 import java.awt.Image;
32 import java.awt.Panel;
33 import java.awt.event.ComponentAdapter;
34 import java.awt.event.ComponentEvent;
35 import java.awt.event.MouseEvent;
36 import java.awt.event.MouseListener;
37 import java.awt.event.MouseMotionListener;
39 public class OverviewPanel extends Panel implements Runnable,
40 MouseMotionListener, MouseListener
42 private OverviewDimensions od;
46 private Image offscreen;
48 private AlignViewport av;
50 private AlignmentPanel ap;
52 private boolean resizing = false;
54 // This is set true if the user resizes whilst
55 // the overview is being calculated
56 private boolean resizeAgain = false;
58 // Can set different properties in this seqCanvas than
59 // main visible SeqCanvas
60 private SequenceRenderer sr;
62 private FeatureRenderer fr;
64 private Frame nullFrame;
66 public OverviewPanel(AlignmentPanel alPanel)
71 nullFrame = new Frame();
72 nullFrame.addNotify();
74 sr = new SequenceRenderer(av);
75 sr.graphics = nullFrame.getGraphics();
76 sr.renderGaps = false;
77 sr.forOverview = true;
78 fr = new FeatureRenderer(av);
80 od = new OverviewDimensions(av.getRanges(),
81 (av.isShowAnnotation() && av.getSequenceConsensusHash() != null));
83 setSize(new Dimension(od.getWidth(), od.getHeight()));
84 addComponentListener(new ComponentAdapter()
88 public void componentResized(ComponentEvent evt)
90 if ((getWidth() != od.getWidth())
91 || (getHeight() != (od.getHeight())))
93 updateOverviewImage();
98 addMouseMotionListener(this);
100 addMouseListener(this);
102 updateOverviewImage();
107 public void mouseEntered(MouseEvent evt)
112 public void mouseExited(MouseEvent evt)
117 public void mouseClicked(MouseEvent evt)
122 public void mouseMoved(MouseEvent evt)
127 public void mousePressed(MouseEvent evt)
133 public void mouseReleased(MouseEvent evt)
139 public void mouseDragged(MouseEvent evt)
144 private void mouseAction(MouseEvent evt)
146 od.updateViewportFromMouse(evt.getX(), evt.getY(), av.getAlignment()
147 .getHiddenSequences(), av.getColumnSelection(), av
149 ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
150 ap.paintAlignment(false);
154 * Updates the overview image when the related alignment panel is updated
156 public void updateOverviewImage()
164 if (av.isShowSequenceFeatures())
166 fr.transferSettings(ap.seqPanel.seqCanvas.fr);
171 if ((getSize().width > 0) && (getSize().height > 0))
173 od.setWidth(getSize().width);
174 od.setHeight(getSize().height);
176 setSize(new Dimension(od.getWidth(), od.getHeight()));
178 Thread thread = new Thread(this);
188 if (av.isShowSequenceFeatures())
190 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
193 if (getSize().width > 0 && getSize().height > 0)
195 od.setWidth(getSize().width);
196 od.setHeight(getSize().height);
199 setSize(new Dimension(od.getWidth(), od.getHeight()));
201 miniMe = nullFrame.createImage(od.getWidth(), od.getHeight());
202 offscreen = nullFrame.createImage(od.getWidth(), od.getHeight());
204 Graphics mg = miniMe.getGraphics();
206 int alwidth = av.getAlignment().getWidth();
207 int alheight = av.getAlignment().getAbsoluteHeight();
208 float sampleCol = alwidth / (float) od.getWidth();
209 float sampleRow = alheight / (float) od.getSequencesHeight();
211 buildImage(sampleRow, sampleCol, mg);
213 // check for conservation annotation to make sure overview works for DNA too
214 if (av.isShowAnnotation()
215 && (av.getAlignmentConservationAnnotation() != null))
217 for (int col = 0; col < od.getWidth() && !resizeAgain; col++)
219 mg.translate(col, od.getSequencesHeight());
220 ap.annotationPanel.renderer.drawGraph(mg,
221 av.getAlignmentConservationAnnotation(),
222 av.getAlignmentConservationAnnotation().annotations,
223 (int) (sampleCol) + 1, od.getGraphHeight(),
224 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
225 mg.translate(-col, -od.getSequencesHeight());
237 updateOverviewImage();
242 * Build the overview panel image
244 private void buildImage(float sampleRow, float sampleCol, Graphics mg)
250 Color color = Color.yellow;
254 SequenceI seq = null;
255 FeatureColourFinder finder = new FeatureColourFinder(fr);
257 final boolean hasHiddenCols = av.hasHiddenColumns();
258 boolean hiddenRow = false;
260 for (int row = 0; row <= od.getSequencesHeight() && !resizeAgain; row++)
262 if ((int) (row * sampleRow) == lastrow)
268 // get the sequence which would be at alignment index 'lastrow' if no
269 // columns were hidden, and determine whether it is hidden or not
270 hiddenRow = av.getAlignment().isHidden(lastrow);
271 seq = av.getAlignment().getSequenceAtAbsoluteIndex(lastrow);
273 for (int col = 0; col < od.getWidth(); col++)
275 if ((int) (col * sampleCol) == lastcol
276 && (int) (row * sampleRow) == lastrow)
282 lastcol = (int) (col * sampleCol);
284 color = getColumnColourFromSequence(seq, hiddenRow,
285 hasHiddenCols, lastcol, finder);
288 if (sameCol == 1 && sameRow == 1)
290 mg.drawLine(xstart, ystart, xstart, ystart);
294 mg.fillRect(xstart, ystart, sameCol, sameRow);
301 lastrow = (int) (row * sampleRow);
309 * Find the colour of a sequence at a specified column position
311 private Color getColumnColourFromSequence(
312 jalview.datamodel.SequenceI seq, boolean hiddenRow,
313 boolean hasHiddenCols, int lastcol, FeatureColourFinder finder)
315 Color color = Color.white;
316 if (seq.getLength() > lastcol)
318 color = sr.getResidueColour(seq, lastcol, finder);
322 || (hasHiddenCols && !av.getColumnSelection()
323 .isVisible(lastcol)))
325 color = color.darker().darker();
331 * Update the overview panel box when the associated alignment panel is
335 public void setBoxPosition()
337 od.setBoxPosition(av.getAlignment()
338 .getHiddenSequences(), av.getColumnSelection(), av.getRanges());
343 public void update(Graphics g)
349 public void paint(Graphics g)
351 Graphics og = offscreen.getGraphics();
354 og.drawImage(miniMe, 0, 0, this);
355 og.setColor(Color.red);
357 g.drawImage(offscreen, 0, 0, this);