2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
18 package jalview.appletgui;
20 import jalview.datamodel.AlignmentI;
23 import java.awt.event.*;
25 public class OverviewPanel extends Panel implements Runnable,
26 MouseMotionListener, MouseListener
40 public int width, sequencesHeight;
44 int boxX = -1, boxY = -1, boxWidth = -1, boxHeight = -1;
46 boolean resizing = false;
48 // Can set different properties in this seqCanvas than
49 // main visible SeqCanvas
56 public OverviewPanel(AlignmentPanel ap)
61 nullFrame = new Frame();
62 nullFrame.addNotify();
64 sr = new SequenceRenderer(av);
65 sr.graphics = nullFrame.getGraphics();
66 sr.renderGaps = false;
67 sr.forOverview = true;
68 fr = new FeatureRenderer(av);
71 // scale the initial size of overviewpanel to shape of alignment
72 float initialScale = (float) av.getAlignment().getWidth()
73 / (float) av.getAlignment().getHeight();
75 if (av.getSequenceConsensusHash() == null)
80 if (av.getAlignment().getWidth() > av.getAlignment().getHeight())
84 sequencesHeight = (int) (400f / initialScale);
85 if (sequencesHeight < 40)
93 width = (int) (400f * initialScale);
94 sequencesHeight = 300;
101 setSize(new Dimension(width, sequencesHeight + graphHeight));
102 addComponentListener(new ComponentAdapter()
105 public void componentResized(ComponentEvent evt)
107 if (getSize().width != width
108 || getSize().height != sequencesHeight + graphHeight)
110 updateOverviewImage();
115 addMouseMotionListener(this);
117 addMouseListener(this);
119 updateOverviewImage();
123 public void mouseEntered(MouseEvent evt)
127 public void mouseExited(MouseEvent evt)
131 public void mouseClicked(MouseEvent evt)
135 public void mouseMoved(MouseEvent evt)
139 public void mousePressed(MouseEvent evt)
146 public void mouseReleased(MouseEvent evt)
153 public void mouseDragged(MouseEvent evt)
167 if (boxY > (sequencesHeight - boxHeight))
169 boxY = sequencesHeight - boxHeight + 1;
177 if (boxX > (width - boxWidth))
179 if (av.hasHiddenColumns())
181 // Try smallest possible box
182 boxWidth = (int) ((av.endRes - av.startRes + 1) * av.getCharWidth() * scalew);
184 boxX = width - boxWidth;
187 int col = (int) (boxX / scalew / av.getCharWidth());
188 int row = (int) (boxY / scaleh / av.getCharHeight());
190 if (av.hasHiddenColumns())
192 if (!av.getColumnSelection().isVisible(col))
197 col = av.getColumnSelection().findColumnPosition(col);
200 if (av.hasHiddenRows())
202 row = av.getAlignment().getHiddenSequences().findIndexWithoutHiddenSeqs(
206 ap.setScrollValues(col, row);
207 ap.paintAlignment(false);
213 public void updateOverviewImage()
221 if (av.showSequenceFeatures)
223 fr.featureGroups = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups;
224 fr.featureColours = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours;
229 if ((getSize().width > 0) && (getSize().height > 0))
231 width = getSize().width;
232 sequencesHeight = getSize().height - graphHeight;
234 setSize(new Dimension(width, sequencesHeight + graphHeight));
236 Thread thread = new Thread(this);
241 // This is set true if the user resizes whilst
242 // the overview is being calculated
243 boolean resizeAgain = false;
248 int alwidth = av.getAlignment().getWidth();
249 int alheight = av.getAlignment().getHeight();
251 if (av.showSequenceFeatures)
253 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
256 if (getSize().width > 0 && getSize().height > 0)
258 width = getSize().width;
259 sequencesHeight = getSize().height - graphHeight;
262 setSize(new Dimension(width, sequencesHeight + graphHeight));
264 int fullsizeWidth = alwidth * av.getCharWidth();
265 int fullsizeHeight = alheight * av.getCharHeight();
267 scalew = (float) width / (float) fullsizeWidth;
268 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
270 miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);
271 offscreen = nullFrame.createImage(width, sequencesHeight + graphHeight);
273 Graphics mg = miniMe.getGraphics();
274 float sampleCol = (float) alwidth / (float) width;
275 float sampleRow = (float) alheight / (float) sequencesHeight;
277 int lastcol = 0, lastrow = 0;
278 int xstart = 0, ystart = 0;
279 Color color = Color.yellow;
280 int row, col, sameRow = 0, sameCol = 0;
281 jalview.datamodel.SequenceI seq;
282 boolean hiddenRow = false;
283 AlignmentI alignment=av.getAlignment();
284 for (row = 0; row <= sequencesHeight; row++)
286 if ((int) (row * sampleRow) == lastrow)
293 if (av.hasHiddenRows())
295 seq = alignment.getHiddenSequences().getHiddenSequence(lastrow);
298 int index = alignment.getHiddenSequences()
299 .findIndexWithoutHiddenSeqs(lastrow);
301 seq = alignment.getSequenceAt(index);
310 seq = alignment.getSequenceAt(lastrow);
313 for (col = 0; col < width; col++)
315 if ((int) (col * sampleCol) == lastcol
316 && (int) (row * sampleRow) == lastrow)
322 lastcol = (int) (col * sampleCol);
324 if (seq.getLength() > lastcol)
326 color = sr.getResidueBoxColour(seq, lastcol);
328 if (av.showSequenceFeatures)
330 color = fr.findFeatureColour(color, seq, lastcol);
335 color = Color.white; // White
339 || (av.hasHiddenColumns() && !av.getColumnSelection()
340 .isVisible(lastcol)))
342 color = color.darker().darker();
346 if (sameCol == 1 && sameRow == 1)
348 mg.drawLine(xstart, ystart, xstart, ystart);
352 mg.fillRect(xstart, ystart, sameCol, sameRow);
358 lastrow = (int) (row * sampleRow);
363 if (av.getAlignmentConservationAnnotation()!= null)
365 for (col = 0; col < width; col++)
367 lastcol = (int) (col * sampleCol);
369 mg.translate(col, sequencesHeight);
370 ap.annotationPanel.renderer.drawGraph(mg, av.getAlignmentConservationAnnotation(),
371 (int) (sampleCol) + 1, graphHeight,
372 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
373 mg.translate(-col, -sequencesHeight);
386 updateOverviewImage();
390 public void setBoxPosition()
392 int fullsizeWidth = av.getAlignment().getWidth() * av.getCharWidth();
393 int fullsizeHeight = (av.getAlignment().getHeight() + av.getAlignment()
394 .getHiddenSequences().getSize()) * av.getCharHeight();
396 int startRes = av.getStartRes();
397 int endRes = av.getEndRes();
399 if (av.hasHiddenColumns())
401 startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
402 endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
405 int startSeq = av.startSeq;
406 int endSeq = av.endSeq;
408 if (av.hasHiddenRows())
410 startSeq = av.getAlignment().getHiddenSequences().adjustForHiddenSeqs(
413 endSeq = av.getAlignment().getHiddenSequences()
414 .adjustForHiddenSeqs(endSeq);
418 scalew = (float) width / (float) fullsizeWidth;
419 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
421 boxX = (int) (startRes * av.getCharWidth() * scalew);
422 boxY = (int) (startSeq * av.getCharHeight() * scaleh);
424 if (av.hasHiddenColumns())
426 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
430 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
433 boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
438 public void update(Graphics g)
443 public void paint(Graphics g)
445 Graphics og = offscreen.getGraphics();
448 og.drawImage(miniMe, 0, 0, this);
449 og.setColor(Color.red);
450 og.drawRect(boxX, boxY, boxWidth, boxHeight);
451 og.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
452 g.drawImage(offscreen, 0, 0, this);