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.AlignmentI;
24 import jalview.util.ColorUtils;
26 import java.awt.Color;
27 import java.awt.Dimension;
28 import java.awt.Frame;
29 import java.awt.Graphics;
30 import java.awt.Image;
31 import java.awt.Panel;
32 import java.awt.event.ComponentAdapter;
33 import java.awt.event.ComponentEvent;
34 import java.awt.event.MouseEvent;
35 import java.awt.event.MouseListener;
36 import java.awt.event.MouseMotionListener;
38 public class OverviewPanel extends Panel implements Runnable,
39 MouseMotionListener, MouseListener
53 public int width, sequencesHeight;
57 int boxX = -1, boxY = -1, boxWidth = -1, boxHeight = -1;
59 boolean resizing = false;
61 // Can set different properties in this seqCanvas than
62 // main visible SeqCanvas
69 public OverviewPanel(AlignmentPanel ap)
74 nullFrame = new Frame();
75 nullFrame.addNotify();
77 sr = new SequenceRenderer(av);
78 sr.graphics = nullFrame.getGraphics();
79 sr.renderGaps = false;
80 sr.forOverview = true;
81 fr = new FeatureRenderer(av);
83 // scale the initial size of overviewpanel to shape of alignment
84 float initialScale = (float) av.getAlignment().getWidth()
85 / (float) av.getAlignment().getHeight();
87 if (av.getSequenceConsensusHash() == null)
92 if (av.getAlignment().getWidth() > av.getAlignment().getHeight())
96 sequencesHeight = (int) (400f / initialScale);
97 if (sequencesHeight < 40)
105 width = (int) (400f * initialScale);
106 sequencesHeight = 300;
113 setSize(new Dimension(width, sequencesHeight + graphHeight));
114 addComponentListener(new ComponentAdapter()
118 public void componentResized(ComponentEvent evt)
120 if (getSize().width != width
121 || getSize().height != sequencesHeight + graphHeight)
123 updateOverviewImage();
128 addMouseMotionListener(this);
130 addMouseListener(this);
132 updateOverviewImage();
137 public void mouseEntered(MouseEvent evt)
142 public void mouseExited(MouseEvent evt)
147 public void mouseClicked(MouseEvent evt)
152 public void mouseMoved(MouseEvent evt)
157 public void mousePressed(MouseEvent evt)
165 public void mouseReleased(MouseEvent evt)
173 public void mouseDragged(MouseEvent evt)
187 if (boxY > (sequencesHeight - boxHeight))
189 boxY = sequencesHeight - boxHeight + 1;
197 if (boxX > (width - boxWidth))
199 if (av.hasHiddenColumns())
201 // Try smallest possible box
202 boxWidth = (int) ((av.endRes - av.startRes + 1) * av.getCharWidth() * scalew);
204 boxX = width - boxWidth;
207 int col = (int) (boxX / scalew / av.getCharWidth());
208 int row = (int) (boxY / scaleh / av.getCharHeight());
210 if (av.hasHiddenColumns())
212 if (!av.getColumnSelection().isVisible(col))
217 col = av.getColumnSelection().findColumnPosition(col);
220 if (av.hasHiddenRows())
222 row = av.getAlignment().getHiddenSequences()
223 .findIndexWithoutHiddenSeqs(row);
226 ap.setScrollValues(col, row);
227 ap.paintAlignment(false);
233 public void updateOverviewImage()
241 if (av.isShowSequenceFeatures())
243 fr.transferSettings(ap.seqPanel.seqCanvas.fr);
248 if ((getSize().width > 0) && (getSize().height > 0))
250 width = getSize().width;
251 sequencesHeight = getSize().height - graphHeight;
253 setSize(new Dimension(width, sequencesHeight + graphHeight));
255 Thread thread = new Thread(this);
260 // This is set true if the user resizes whilst
261 // the overview is being calculated
262 boolean resizeAgain = false;
268 int alwidth = av.getAlignment().getWidth();
269 int alheight = av.getAlignment().getHeight()
270 + av.getAlignment().getHiddenSequences().getSize();
272 if (av.isShowSequenceFeatures())
274 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
277 if (getSize().width > 0 && getSize().height > 0)
279 width = getSize().width;
280 sequencesHeight = getSize().height - graphHeight;
283 setSize(new Dimension(width, sequencesHeight + graphHeight));
285 int fullsizeWidth = alwidth * av.getCharWidth();
286 int fullsizeHeight = alheight * av.getCharHeight();
288 scalew = (float) width / (float) fullsizeWidth;
289 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
291 miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);
292 offscreen = nullFrame.createImage(width, sequencesHeight + graphHeight);
294 Graphics mg = miniMe.getGraphics();
295 float sampleCol = (float) alwidth / (float) width;
296 float sampleRow = (float) alheight / (float) sequencesHeight;
298 int lastcol = 0, lastrow = 0;
299 int xstart = 0, ystart = 0;
300 Color color = Color.yellow;
301 int row, col, sameRow = 0, sameCol = 0;
302 jalview.datamodel.SequenceI seq;
303 final boolean hasHiddenRows = av.hasHiddenRows(), hasHiddenCols = av
305 boolean hiddenRow = false;
306 AlignmentI alignment = av.getAlignment();
307 for (row = 0; row <= sequencesHeight; row++)
313 if ((int) (row * sampleRow) == lastrow)
322 seq = alignment.getHiddenSequences().getHiddenSequence(lastrow);
325 int index = alignment.getHiddenSequences()
326 .findIndexWithoutHiddenSeqs(lastrow);
328 seq = alignment.getSequenceAt(index);
337 seq = alignment.getSequenceAt(lastrow);
340 for (col = 0; col < width; col++)
342 if ((int) (col * sampleCol) == lastcol
343 && (int) (row * sampleRow) == lastrow)
349 lastcol = (int) (col * sampleCol);
351 if (seq.getLength() > lastcol)
353 color = ColorUtils.getColor(sr.getResidueBoxColour(seq, lastcol));
355 if (av.isShowSequenceFeatures())
357 color = ColorUtils.getColor(fr.findFeatureColour(color, seq,
363 color = Color.white; // White
367 || (hasHiddenCols && !av.getColumnSelection().isVisible(
370 color = color.darker().darker();
374 if (sameCol == 1 && sameRow == 1)
376 mg.drawLine(xstart, ystart, xstart, ystart);
380 mg.fillRect(xstart, ystart, sameCol, sameRow);
386 lastrow = (int) (row * sampleRow);
391 if (av.getAlignmentConservationAnnotation() != null)
393 for (col = 0; col < width; col++)
399 lastcol = (int) (col * sampleCol);
401 mg.translate(col, sequencesHeight);
402 ap.annotationPanel.renderer.drawGraph(mg,
403 av.getAlignmentConservationAnnotation(),
404 av.getAlignmentConservationAnnotation().annotations,
405 (int) (sampleCol) + 1, graphHeight,
406 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
407 mg.translate(-col, -sequencesHeight);
420 updateOverviewImage();
424 public void setBoxPosition()
426 int fullsizeWidth = av.getAlignment().getWidth() * av.getCharWidth();
427 int fullsizeHeight = (av.getAlignment().getHeight() + av.getAlignment()
428 .getHiddenSequences().getSize())
429 * av.getCharHeight();
431 int startRes = av.getStartRes();
432 int endRes = av.getEndRes();
434 if (av.hasHiddenColumns())
436 startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
437 endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
440 int startSeq = av.startSeq;
441 int endSeq = av.endSeq;
443 if (av.hasHiddenRows())
445 startSeq = av.getAlignment().getHiddenSequences()
446 .adjustForHiddenSeqs(startSeq);
448 endSeq = av.getAlignment().getHiddenSequences()
449 .adjustForHiddenSeqs(endSeq);
453 scalew = (float) width / (float) fullsizeWidth;
454 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
456 boxX = (int) (startRes * av.getCharWidth() * scalew);
457 boxY = (int) (startSeq * av.getCharHeight() * scaleh);
459 if (av.hasHiddenColumns())
461 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
465 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
468 boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
474 public void update(Graphics g)
480 public void paint(Graphics g)
482 Graphics og = offscreen.getGraphics();
485 og.drawImage(miniMe, 0, 0, this);
486 og.setColor(Color.red);
487 og.drawRect(boxX, boxY, boxWidth, boxHeight);
488 og.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
489 g.drawImage(offscreen, 0, 0, this);