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;
26 import java.awt.event.*;
28 public class OverviewPanel extends Panel implements Runnable,
29 MouseMotionListener, MouseListener
43 public int width, sequencesHeight;
47 int boxX = -1, boxY = -1, boxWidth = -1, boxHeight = -1;
49 boolean resizing = false;
51 // Can set different properties in this seqCanvas than
52 // main visible SeqCanvas
59 public OverviewPanel(AlignmentPanel ap)
64 nullFrame = new Frame();
65 nullFrame.addNotify();
67 sr = new SequenceRenderer(av);
68 sr.graphics = nullFrame.getGraphics();
69 sr.renderGaps = false;
70 sr.forOverview = true;
71 fr = new FeatureRenderer(av);
73 // scale the initial size of overviewpanel to shape of alignment
74 float initialScale = (float) av.getAlignment().getWidth()
75 / (float) av.getAlignment().getHeight();
77 if (av.getSequenceConsensusHash() == null)
82 if (av.getAlignment().getWidth() > av.getAlignment().getHeight())
86 sequencesHeight = (int) (400f / initialScale);
87 if (sequencesHeight < 40)
95 width = (int) (400f * initialScale);
96 sequencesHeight = 300;
103 setSize(new Dimension(width, sequencesHeight + graphHeight));
104 addComponentListener(new ComponentAdapter()
108 public void componentResized(ComponentEvent evt)
110 if (getSize().width != width
111 || getSize().height != sequencesHeight + graphHeight)
113 updateOverviewImage();
118 addMouseMotionListener(this);
120 addMouseListener(this);
122 updateOverviewImage();
127 public void mouseEntered(MouseEvent evt)
132 public void mouseExited(MouseEvent evt)
137 public void mouseClicked(MouseEvent evt)
142 public void mouseMoved(MouseEvent evt)
147 public void mousePressed(MouseEvent evt)
155 public void mouseReleased(MouseEvent evt)
163 public void mouseDragged(MouseEvent evt)
177 if (boxY > (sequencesHeight - boxHeight))
179 boxY = sequencesHeight - boxHeight + 1;
187 if (boxX > (width - boxWidth))
189 if (av.hasHiddenColumns())
191 // Try smallest possible box
192 boxWidth = (int) ((av.endRes - av.startRes + 1) * av.getCharWidth() * scalew);
194 boxX = width - boxWidth;
197 int col = (int) (boxX / scalew / av.getCharWidth());
198 int row = (int) (boxY / scaleh / av.getCharHeight());
200 if (av.hasHiddenColumns())
202 if (!av.getColumnSelection().isVisible(col))
207 col = av.getColumnSelection().findColumnPosition(col);
210 if (av.hasHiddenRows())
212 row = av.getAlignment().getHiddenSequences()
213 .findIndexWithoutHiddenSeqs(row);
216 ap.setScrollValues(col, row);
217 ap.paintAlignment(false);
223 public void updateOverviewImage()
231 if (av.isShowSequenceFeatures())
233 fr.transferSettings(ap.seqPanel.seqCanvas.fr);
238 if ((getSize().width > 0) && (getSize().height > 0))
240 width = getSize().width;
241 sequencesHeight = getSize().height - graphHeight;
243 setSize(new Dimension(width, sequencesHeight + graphHeight));
245 Thread thread = new Thread(this);
250 // This is set true if the user resizes whilst
251 // the overview is being calculated
252 boolean resizeAgain = false;
258 int alwidth = av.getAlignment().getWidth();
259 int alheight = av.getAlignment().getHeight();
261 if (av.isShowSequenceFeatures())
263 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
266 if (getSize().width > 0 && getSize().height > 0)
268 width = getSize().width;
269 sequencesHeight = getSize().height - graphHeight;
272 setSize(new Dimension(width, sequencesHeight + graphHeight));
274 int fullsizeWidth = alwidth * av.getCharWidth();
275 int fullsizeHeight = alheight * av.getCharHeight();
277 scalew = (float) width / (float) fullsizeWidth;
278 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
280 miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);
281 offscreen = nullFrame.createImage(width, sequencesHeight + graphHeight);
283 Graphics mg = miniMe.getGraphics();
284 float sampleCol = (float) alwidth / (float) width;
285 float sampleRow = (float) alheight / (float) sequencesHeight;
287 int lastcol = 0, lastrow = 0;
288 int xstart = 0, ystart = 0;
289 Color color = Color.yellow;
290 int row, col, sameRow = 0, sameCol = 0;
291 jalview.datamodel.SequenceI seq;
292 boolean hiddenRow = false;
293 AlignmentI alignment = av.getAlignment();
294 for (row = 0; row <= sequencesHeight; row++)
296 if ((int) (row * sampleRow) == lastrow)
303 if (av.hasHiddenRows())
305 seq = alignment.getHiddenSequences().getHiddenSequence(lastrow);
308 int index = alignment.getHiddenSequences()
309 .findIndexWithoutHiddenSeqs(lastrow);
311 seq = alignment.getSequenceAt(index);
320 seq = alignment.getSequenceAt(lastrow);
323 for (col = 0; col < width; col++)
325 if ((int) (col * sampleCol) == lastcol
326 && (int) (row * sampleRow) == lastrow)
332 lastcol = (int) (col * sampleCol);
334 if (seq.getLength() > lastcol)
336 color = sr.getResidueBoxColour(seq, lastcol);
338 if (av.isShowSequenceFeatures())
340 color = fr.findFeatureColour(color, seq, lastcol);
345 color = Color.white; // White
349 || (av.hasHiddenColumns() && !av.getColumnSelection()
350 .isVisible(lastcol)))
352 color = color.darker().darker();
356 if (sameCol == 1 && sameRow == 1)
358 mg.drawLine(xstart, ystart, xstart, ystart);
362 mg.fillRect(xstart, ystart, sameCol, sameRow);
368 lastrow = (int) (row * sampleRow);
373 if (av.getAlignmentConservationAnnotation() != null)
375 for (col = 0; col < width; col++)
377 lastcol = (int) (col * sampleCol);
379 mg.translate(col, sequencesHeight);
380 ap.annotationPanel.renderer.drawGraph(mg,
381 av.getAlignmentConservationAnnotation(),
382 av.getAlignmentConservationAnnotation().annotations,
383 (int) (sampleCol) + 1, graphHeight,
384 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
385 mg.translate(-col, -sequencesHeight);
398 updateOverviewImage();
402 public void setBoxPosition()
404 int fullsizeWidth = av.getAlignment().getWidth() * av.getCharWidth();
405 int fullsizeHeight = (av.getAlignment().getHeight() + av.getAlignment()
406 .getHiddenSequences().getSize())
407 * av.getCharHeight();
409 int startRes = av.getStartRes();
410 int endRes = av.getEndRes();
412 if (av.hasHiddenColumns())
414 startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
415 endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
418 int startSeq = av.startSeq;
419 int endSeq = av.endSeq;
421 if (av.hasHiddenRows())
423 startSeq = av.getAlignment().getHiddenSequences()
424 .adjustForHiddenSeqs(startSeq);
426 endSeq = av.getAlignment().getHiddenSequences()
427 .adjustForHiddenSeqs(endSeq);
431 scalew = (float) width / (float) fullsizeWidth;
432 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
434 boxX = (int) (startRes * av.getCharWidth() * scalew);
435 boxY = (int) (startSeq * av.getCharHeight() * scaleh);
437 if (av.hasHiddenColumns())
439 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
443 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
446 boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
452 public void update(Graphics g)
458 public void paint(Graphics g)
460 Graphics og = offscreen.getGraphics();
463 og.drawImage(miniMe, 0, 0, this);
464 og.setColor(Color.red);
465 og.drawRect(boxX, boxY, boxWidth, boxHeight);
466 og.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
467 g.drawImage(offscreen, 0, 0, this);