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(), av.isShowAnnotation());
82 setSize(new Dimension(od.getWidth(), od.getHeight()));
83 addComponentListener(new ComponentAdapter()
87 public void componentResized(ComponentEvent evt)
89 if ((getWidth() != od.getWidth())
90 || (getHeight() != (od.getHeight())))
92 updateOverviewImage();
97 addMouseMotionListener(this);
99 addMouseListener(this);
101 updateOverviewImage();
106 public void mouseEntered(MouseEvent evt)
111 public void mouseExited(MouseEvent evt)
116 public void mouseClicked(MouseEvent evt)
121 public void mouseMoved(MouseEvent evt)
126 public void mousePressed(MouseEvent evt)
132 public void mouseReleased(MouseEvent evt)
138 public void mouseDragged(MouseEvent evt)
143 private void mouseAction(MouseEvent evt)
145 od.updateViewportFromMouse(evt.getX(), evt.getY(), av.getAlignment()
146 .getHiddenSequences(), av.getColumnSelection(), av
148 ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
149 ap.paintAlignment(false);
153 * Updates the overview image when the related alignment panel is updated
155 public void updateOverviewImage()
163 if (av.isShowSequenceFeatures())
165 fr.transferSettings(ap.seqPanel.seqCanvas.fr);
170 if ((getSize().width > 0) && (getSize().height > 0))
172 od.setWidth(getSize().width);
173 od.setHeight(getSize().height);
175 setSize(new Dimension(od.getWidth(), od.getHeight()));
177 Thread thread = new Thread(this);
187 if (av.isShowSequenceFeatures())
189 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
192 if (getSize().width > 0 && getSize().height > 0)
194 od.setWidth(getSize().width);
195 od.setHeight(getSize().height);
198 setSize(new Dimension(od.getWidth(), od.getHeight()));
200 miniMe = nullFrame.createImage(od.getWidth(), od.getHeight());
201 offscreen = nullFrame.createImage(od.getWidth(), od.getHeight());
203 Graphics mg = miniMe.getGraphics();
205 int alwidth = av.getAlignment().getWidth();
206 int alheight = av.getAlignment().getAbsoluteHeight();
207 float sampleCol = alwidth / (float) od.getWidth();
208 float sampleRow = alheight / (float) od.getSequencesHeight();
210 buildImage(sampleRow, sampleCol, mg);
212 if (av.isShowAnnotation())
214 for (int col = 0; col < od.getWidth() && !resizeAgain; col++)
216 mg.translate(col, od.getSequencesHeight());
217 ap.annotationPanel.renderer.drawGraph(mg,
218 av.getAlignmentConservationAnnotation(),
219 av.getAlignmentConservationAnnotation().annotations,
220 (int) (sampleCol) + 1, od.getGraphHeight(),
221 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
222 mg.translate(-col, -od.getSequencesHeight());
234 updateOverviewImage();
239 * Build the overview panel image
241 private void buildImage(float sampleRow, float sampleCol, Graphics mg)
247 Color color = Color.yellow;
251 SequenceI seq = null;
252 FeatureColourFinder finder = new FeatureColourFinder(fr);
254 final boolean hasHiddenCols = av.hasHiddenColumns();
255 boolean hiddenRow = false;
257 for (int row = 0; row <= od.getSequencesHeight() && !resizeAgain; row++)
259 if ((int) (row * sampleRow) == lastrow)
265 // get the sequence which would be at alignment index 'lastrow' if no
266 // columns were hidden, and determine whether it is hidden or not
267 hiddenRow = av.getAlignment().isHidden(lastrow);
268 seq = av.getAlignment().getSequenceAtAbsoluteIndex(lastrow);
270 for (int col = 0; col < od.getWidth(); col++)
272 if ((int) (col * sampleCol) == lastcol
273 && (int) (row * sampleRow) == lastrow)
279 lastcol = (int) (col * sampleCol);
281 color = getColumnColourFromSequence(seq, hiddenRow,
282 hasHiddenCols, lastcol, finder);
285 if (sameCol == 1 && sameRow == 1)
287 mg.drawLine(xstart, ystart, xstart, ystart);
291 mg.fillRect(xstart, ystart, sameCol, sameRow);
298 lastrow = (int) (row * sampleRow);
306 * Find the colour of a sequence at a specified column position
308 private Color getColumnColourFromSequence(
309 jalview.datamodel.SequenceI seq, boolean hiddenRow,
310 boolean hasHiddenCols, int lastcol, FeatureColourFinder finder)
312 Color color = Color.white;
313 if (seq.getLength() > lastcol)
315 color = sr.getResidueColour(seq, lastcol, finder);
319 || (hasHiddenCols && !av.getColumnSelection()
320 .isVisible(lastcol)))
322 color = color.darker().darker();
328 * Update the overview panel box when the associated alignment panel is
332 public void setBoxPosition()
334 od.setBoxPosition(av.getAlignment()
335 .getHiddenSequences(), av.getColumnSelection(), av.getRanges());
340 public void update(Graphics g)
346 public void paint(Graphics g)
348 Graphics og = offscreen.getGraphics();
351 og.drawImage(miniMe, 0, 0, this);
352 og.setColor(Color.red);
354 g.drawImage(offscreen, 0, 0, this);