2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, 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()
106 public void componentResized(ComponentEvent evt)
108 if (getSize().width != width
109 || getSize().height != sequencesHeight + graphHeight)
111 updateOverviewImage();
116 addMouseMotionListener(this);
118 addMouseListener(this);
120 updateOverviewImage();
125 public void mouseEntered(MouseEvent evt)
130 public void mouseExited(MouseEvent evt)
135 public void mouseClicked(MouseEvent evt)
140 public void mouseMoved(MouseEvent evt)
145 public void mousePressed(MouseEvent evt)
153 public void mouseReleased(MouseEvent evt)
161 public void mouseDragged(MouseEvent evt)
175 if (boxY > (sequencesHeight - boxHeight))
177 boxY = sequencesHeight - boxHeight + 1;
185 if (boxX > (width - boxWidth))
187 if (av.hasHiddenColumns())
189 // Try smallest possible box
190 boxWidth = (int) ((av.endRes - av.startRes + 1) * av.getCharWidth() * scalew);
192 boxX = width - boxWidth;
195 int col = (int) (boxX / scalew / av.getCharWidth());
196 int row = (int) (boxY / scaleh / av.getCharHeight());
198 if (av.hasHiddenColumns())
200 if (!av.getColumnSelection().isVisible(col))
205 col = av.getColumnSelection().findColumnPosition(col);
208 if (av.hasHiddenRows())
210 row = av.getAlignment().getHiddenSequences()
211 .findIndexWithoutHiddenSeqs(row);
214 ap.setScrollValues(col, row);
215 ap.paintAlignment(false);
221 public void updateOverviewImage()
229 if (av.showSequenceFeatures)
231 fr.featureGroups = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups;
232 fr.featureColours = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours;
237 if ((getSize().width > 0) && (getSize().height > 0))
239 width = getSize().width;
240 sequencesHeight = getSize().height - graphHeight;
242 setSize(new Dimension(width, sequencesHeight + graphHeight));
244 Thread thread = new Thread(this);
249 // This is set true if the user resizes whilst
250 // the overview is being calculated
251 boolean resizeAgain = false;
257 int alwidth = av.getAlignment().getWidth();
258 int alheight = av.getAlignment().getHeight();
260 if (av.showSequenceFeatures)
262 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
265 if (getSize().width > 0 && getSize().height > 0)
267 width = getSize().width;
268 sequencesHeight = getSize().height - graphHeight;
271 setSize(new Dimension(width, sequencesHeight + graphHeight));
273 int fullsizeWidth = alwidth * av.getCharWidth();
274 int fullsizeHeight = alheight * av.getCharHeight();
276 scalew = (float) width / (float) fullsizeWidth;
277 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
279 miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);
280 offscreen = nullFrame.createImage(width, sequencesHeight + graphHeight);
282 Graphics mg = miniMe.getGraphics();
283 float sampleCol = (float) alwidth / (float) width;
284 float sampleRow = (float) alheight / (float) sequencesHeight;
286 int lastcol = 0, lastrow = 0;
287 int xstart = 0, ystart = 0;
288 Color color = Color.yellow;
289 int row, col, sameRow = 0, sameCol = 0;
290 jalview.datamodel.SequenceI seq;
291 boolean hiddenRow = false;
292 AlignmentI alignment = av.getAlignment();
293 for (row = 0; row <= sequencesHeight; row++)
295 if ((int) (row * sampleRow) == lastrow)
302 if (av.hasHiddenRows())
304 seq = alignment.getHiddenSequences().getHiddenSequence(lastrow);
307 int index = alignment.getHiddenSequences()
308 .findIndexWithoutHiddenSeqs(lastrow);
310 seq = alignment.getSequenceAt(index);
319 seq = alignment.getSequenceAt(lastrow);
322 for (col = 0; col < width; col++)
324 if ((int) (col * sampleCol) == lastcol
325 && (int) (row * sampleRow) == lastrow)
331 lastcol = (int) (col * sampleCol);
333 if (seq.getLength() > lastcol)
335 color = sr.getResidueBoxColour(seq, lastcol);
337 if (av.showSequenceFeatures)
339 color = fr.findFeatureColour(color, seq, lastcol);
344 color = Color.white; // White
348 || (av.hasHiddenColumns() && !av.getColumnSelection()
349 .isVisible(lastcol)))
351 color = color.darker().darker();
355 if (sameCol == 1 && sameRow == 1)
357 mg.drawLine(xstart, ystart, xstart, ystart);
361 mg.fillRect(xstart, ystart, sameCol, sameRow);
367 lastrow = (int) (row * sampleRow);
372 if (av.getAlignmentConservationAnnotation() != null)
374 for (col = 0; col < width; col++)
376 lastcol = (int) (col * sampleCol);
378 mg.translate(col, sequencesHeight);
379 ap.annotationPanel.renderer.drawGraph(mg,
380 av.getAlignmentConservationAnnotation(),
381 av.getAlignmentConservationAnnotation().annotations,
382 (int) (sampleCol) + 1, graphHeight,
383 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
384 mg.translate(-col, -sequencesHeight);
397 updateOverviewImage();
401 public void setBoxPosition()
403 int fullsizeWidth = av.getAlignment().getWidth() * av.getCharWidth();
404 int fullsizeHeight = (av.getAlignment().getHeight() + av.getAlignment()
405 .getHiddenSequences().getSize())
406 * av.getCharHeight();
408 int startRes = av.getStartRes();
409 int endRes = av.getEndRes();
411 if (av.hasHiddenColumns())
413 startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
414 endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
417 int startSeq = av.startSeq;
418 int endSeq = av.endSeq;
420 if (av.hasHiddenRows())
422 startSeq = av.getAlignment().getHiddenSequences()
423 .adjustForHiddenSeqs(startSeq);
425 endSeq = av.getAlignment().getHiddenSequences()
426 .adjustForHiddenSeqs(endSeq);
430 scalew = (float) width / (float) fullsizeWidth;
431 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
433 boxX = (int) (startRes * av.getCharWidth() * scalew);
434 boxY = (int) (startSeq * av.getCharHeight() * scaleh);
436 if (av.hasHiddenColumns())
438 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
442 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
445 boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
451 public void update(Graphics g)
457 public void paint(Graphics g)
459 Graphics og = offscreen.getGraphics();
462 og.drawImage(miniMe, 0, 0, this);
463 og.setColor(Color.red);
464 og.drawRect(boxX, boxY, boxWidth, boxHeight);
465 og.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
466 g.drawImage(offscreen, 0, 0, this);