--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.appletgui;
+
+import jalview.datamodel.SequenceI;
+import jalview.renderer.seqfeatures.FeatureColourFinder;
+import jalview.viewmodel.OverviewDimensions;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Image;
+
+import javax.swing.JComponent;
+
+public class OverviewCanvas extends JComponent
+{
+ // This is set true if the alignment view changes whilst
+ // the overview is being calculated
+ private volatile boolean restart = false;
+
+ private volatile boolean updaterunning = false;
+
+ private OverviewDimensions od;
+
+ private Image miniMe;
+
+ private Image offscreen;
+
+ private AlignViewport av;
+
+ private AlignmentPanel ap;
+
+ // Can set different properties in this seqCanvas than
+ // main visible SeqCanvas
+ private SequenceRenderer sr;
+
+ private FeatureRenderer fr;
+
+ private Frame nullFrame;
+
+ public OverviewCanvas(OverviewDimensions overviewDims,
+ AlignViewport alignvp, AlignmentPanel alignp)
+ {
+ od = overviewDims;
+ av = alignp.av;
+ ap = alignp;
+
+ nullFrame = new Frame();
+ nullFrame.addNotify();
+
+ sr = new SequenceRenderer(av);
+ sr.graphics = nullFrame.getGraphics();
+ sr.renderGaps = false;
+ sr.forOverview = true;
+ fr = new FeatureRenderer(av);
+ }
+
+ /*
+ * Signals to drawing code that the associated alignment viewport
+ * has changed and a redraw will be required
+ */
+ public boolean restartDraw()
+ {
+ synchronized (this)
+ {
+ if (updaterunning)
+ {
+ restart = true;
+ }
+ else
+ {
+ updaterunning = true;
+ }
+ return restart;
+ }
+ }
+
+ public void draw(boolean showSequenceFeatures, boolean showAnnotation)
+ {
+ miniMe = null;
+
+ if (av.isShowSequenceFeatures())
+ {
+ fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
+ }
+
+ setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
+
+ miniMe = nullFrame.createImage(od.getWidth(), od.getHeight());
+ offscreen = nullFrame.createImage(od.getWidth(), od.getHeight());
+
+ Graphics mg = miniMe.getGraphics();
+
+ int alwidth = av.getAlignment().getWidth();
+ int alheight = av.getAlignment().getAbsoluteHeight();
+ float sampleCol = alwidth / (float) od.getWidth();
+ float sampleRow = alheight / (float) od.getSequencesHeight();
+
+ buildImage(sampleRow, sampleCol, mg);
+
+ // check for conservation annotation to make sure overview works for DNA too
+ if (showAnnotation)
+ {
+ for (int col = 0; col < od.getWidth() && !restart; col++)
+ {
+ mg.translate(col, od.getSequencesHeight());
+ ap.annotationPanel.renderer.drawGraph(mg,
+ av.getAlignmentConservationAnnotation(),
+ av.getAlignmentConservationAnnotation().annotations,
+ (int) (sampleCol) + 1, od.getGraphHeight(),
+ (int) (col * sampleCol), (int) (col * sampleCol) + 1);
+ mg.translate(-col, -od.getSequencesHeight());
+ }
+ }
+ System.gc();
+
+ if (restart)
+ {
+ restart = false;
+ draw(showSequenceFeatures, showAnnotation);
+ }
+ else
+ {
+ updaterunning = false;
+ }
+ }
+
+ /*
+ * Build the overview panel image
+ */
+ private void buildImage(float sampleRow, float sampleCol, Graphics mg)
+ {
+ int lastcol = 0;
+ int lastrow = 0;
+ int xstart = 0;
+ int ystart = 0;
+ Color color = Color.yellow;
+ int sameRow = 0;
+ int sameCol = 0;
+
+ SequenceI seq = null;
+ FeatureColourFinder finder = new FeatureColourFinder(fr);
+
+ final boolean hasHiddenCols = av.hasHiddenColumns();
+ boolean hiddenRow = false;
+
+ for (int row = 0; row < od.getSequencesHeight() && !restart; row++)
+ {
+ if ((int) (row * sampleRow) == lastrow)
+ {
+ sameRow++;
+ }
+ else
+ {
+ // get the sequence which would be at alignment index 'lastrow' if no
+ // rows were hidden, and determine whether it is hidden or not
+ hiddenRow = av.getAlignment().isHidden(lastrow);
+ seq = av.getAlignment().getSequenceAtAbsoluteIndex(lastrow);
+
+ for (int col = 0; col < od.getWidth(); col++)
+ {
+ if ((int) (col * sampleCol) == lastcol
+ && (int) (row * sampleRow) == lastrow)
+ {
+ sameCol++;
+ }
+ else
+ {
+ lastcol = (int) (col * sampleCol);
+
+ color = getColumnColourFromSequence(seq, hiddenRow,
+ hasHiddenCols, lastcol, finder);
+
+ mg.setColor(color);
+ if (sameCol == 1 && sameRow == 1)
+ {
+ mg.drawLine(xstart, ystart, xstart, ystart);
+ }
+ else
+ {
+ mg.fillRect(xstart, ystart, sameCol, sameRow);
+ }
+
+ xstart = col;
+ sameCol = 1;
+ }
+ }
+ lastrow = (int) (row * sampleRow);
+ ystart = row;
+ sameRow = 1;
+ }
+ }
+ }
+
+ /*
+ * Find the colour of a sequence at a specified column position
+ */
+ private Color getColumnColourFromSequence(
+ jalview.datamodel.SequenceI seq, boolean hiddenRow,
+ boolean hasHiddenCols, int lastcol, FeatureColourFinder finder)
+ {
+ Color color = Color.white;
+ if (seq.getLength() > lastcol)
+ {
+ color = sr.getResidueColour(seq, lastcol, finder);
+ }
+
+ if (hiddenRow
+ || (hasHiddenCols && !av.getColumnSelection()
+ .isVisible(lastcol)))
+ {
+ color = color.darker().darker();
+ }
+ return color;
+ }
+
+ @Override
+ public void update(Graphics g)
+ {
+ paint(g);
+ }
+
+ @Override
+ public void paint(Graphics g)
+ {
+ Graphics og = offscreen.getGraphics();
+ if (miniMe != null)
+ {
+ og.drawImage(miniMe, 0, 0, this);
+ og.setColor(Color.red);
+ od.drawBox(og);
+ g.drawImage(offscreen, 0, 0, this);
+ }
+ }
+
+}
*/
package jalview.appletgui;
-import jalview.datamodel.SequenceI;
-import jalview.renderer.seqfeatures.FeatureColourFinder;
import jalview.viewmodel.OverviewDimensions;
-import java.awt.Color;
+import java.awt.BorderLayout;
import java.awt.Dimension;
-import java.awt.Frame;
-import java.awt.Graphics;
-import java.awt.Image;
import java.awt.Panel;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
{
private OverviewDimensions od;
- private Image miniMe;
-
- private Image offscreen;
+ private OverviewCanvas oviewCanvas;
private AlignViewport av;
private AlignmentPanel ap;
- private boolean resizing = false;
-
- // This is set true if the user resizes whilst
- // the overview is being calculated
- private boolean resizeAgain = false;
-
- // Can set different properties in this seqCanvas than
- // main visible SeqCanvas
- private SequenceRenderer sr;
-
- private FeatureRenderer fr;
-
- private Frame nullFrame;
+ private boolean updateRunning = false;
public OverviewPanel(AlignmentPanel alPanel)
{
this.av = alPanel.av;
this.ap = alPanel;
setLayout(null);
- nullFrame = new Frame();
- nullFrame.addNotify();
-
- sr = new SequenceRenderer(av);
- sr.graphics = nullFrame.getGraphics();
- sr.renderGaps = false;
- sr.forOverview = true;
- fr = new FeatureRenderer(av);
od = new OverviewDimensions(av.getRanges(),
(av.isShowAnnotation() && av.getSequenceConsensusHash() != null));
+ oviewCanvas = new OverviewCanvas(od, av, ap);
+ setLayout(new BorderLayout());
+ add(oviewCanvas, BorderLayout.CENTER);
+
setSize(new Dimension(od.getWidth(), od.getHeight()));
addComponentListener(new ComponentAdapter()
{
*/
public void updateOverviewImage()
{
- if (resizing)
- {
- resizeAgain = true;
- return;
- }
-
- if (av.isShowSequenceFeatures())
- {
- fr.transferSettings(ap.seqPanel.seqCanvas.fr);
- }
-
- resizing = true;
-
if ((getSize().width > 0) && (getSize().height > 0))
{
od.setWidth(getSize().width);
}
setSize(new Dimension(od.getWidth(), od.getHeight()));
+ if (updateRunning)
+ {
+ oviewCanvas.restartDraw();
+ return;
+ }
+
+ updateRunning = true;
Thread thread = new Thread(this);
thread.start();
repaint();
+ updateRunning = false;
}
@Override
public void run()
{
- miniMe = null;
-
- if (av.isShowSequenceFeatures())
- {
- fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
- }
-
- if (getSize().width > 0 && getSize().height > 0)
- {
- od.setWidth(getSize().width);
- od.setHeight(getSize().height);
- }
-
- setSize(new Dimension(od.getWidth(), od.getHeight()));
-
- miniMe = nullFrame.createImage(od.getWidth(), od.getHeight());
- offscreen = nullFrame.createImage(od.getWidth(), od.getHeight());
-
- Graphics mg = miniMe.getGraphics();
-
- int alwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getAbsoluteHeight();
- float sampleCol = alwidth / (float) od.getWidth();
- float sampleRow = alheight / (float) od.getSequencesHeight();
-
- buildImage(sampleRow, sampleCol, mg);
-
- // check for conservation annotation to make sure overview works for DNA too
- if (av.isShowAnnotation()
- && (av.getAlignmentConservationAnnotation() != null))
- {
- for (int col = 0; col < od.getWidth() && !resizeAgain; col++)
- {
- mg.translate(col, od.getSequencesHeight());
- ap.annotationPanel.renderer.drawGraph(mg,
- av.getAlignmentConservationAnnotation(),
- av.getAlignmentConservationAnnotation().annotations,
- (int) (sampleCol) + 1, od.getGraphHeight(),
- (int) (col * sampleCol), (int) (col * sampleCol) + 1);
- mg.translate(-col, -od.getSequencesHeight());
- }
- }
- System.gc();
-
- resizing = false;
-
+ oviewCanvas.draw(av.isShowSequenceFeatures(),
+ (av.isShowAnnotation() && av
+ .getAlignmentConservationAnnotation() != null));
setBoxPosition();
-
- if (resizeAgain)
- {
- resizeAgain = false;
- updateOverviewImage();
- }
- }
-
- /*
- * Build the overview panel image
- */
- private void buildImage(float sampleRow, float sampleCol, Graphics mg)
- {
- int lastcol = 0;
- int lastrow = 0;
- int xstart = 0;
- int ystart = 0;
- Color color = Color.yellow;
- int sameRow = 0;
- int sameCol = 0;
-
- SequenceI seq = null;
- FeatureColourFinder finder = new FeatureColourFinder(fr);
-
- final boolean hasHiddenCols = av.hasHiddenColumns();
- boolean hiddenRow = false;
-
- for (int row = 0; row <= od.getSequencesHeight() && !resizeAgain; row++)
- {
- if ((int) (row * sampleRow) == lastrow)
- {
- sameRow++;
- }
- else
- {
- // get the sequence which would be at alignment index 'lastrow' if no
- // columns were hidden, and determine whether it is hidden or not
- hiddenRow = av.getAlignment().isHidden(lastrow);
- seq = av.getAlignment().getSequenceAtAbsoluteIndex(lastrow);
-
- for (int col = 0; col < od.getWidth(); col++)
- {
- if ((int) (col * sampleCol) == lastcol
- && (int) (row * sampleRow) == lastrow)
- {
- sameCol++;
- }
- else
- {
- lastcol = (int) (col * sampleCol);
-
- color = getColumnColourFromSequence(seq, hiddenRow,
- hasHiddenCols, lastcol, finder);
-
- mg.setColor(color);
- if (sameCol == 1 && sameRow == 1)
- {
- mg.drawLine(xstart, ystart, xstart, ystart);
- }
- else
- {
- mg.fillRect(xstart, ystart, sameCol, sameRow);
- }
-
- xstart = col;
- sameCol = 1;
- }
- }
- lastrow = (int) (row * sampleRow);
- ystart = row;
- sameRow = 1;
- }
- }
- }
-
- /*
- * Find the colour of a sequence at a specified column position
- */
- private Color getColumnColourFromSequence(
- jalview.datamodel.SequenceI seq, boolean hiddenRow,
- boolean hasHiddenCols, int lastcol, FeatureColourFinder finder)
- {
- Color color = Color.white;
- if (seq.getLength() > lastcol)
- {
- color = sr.getResidueColour(seq, lastcol, finder);
- }
-
- if (hiddenRow
- || (hasHiddenCols && !av.getColumnSelection()
- .isVisible(lastcol)))
- {
- color = color.darker().darker();
- }
- return color;
}
/**
repaint();
}
- @Override
- public void update(Graphics g)
- {
- paint(g);
- }
- @Override
- public void paint(Graphics g)
- {
- Graphics og = offscreen.getGraphics();
- if (miniMe != null)
- {
- og.drawImage(miniMe, 0, 0, this);
- og.setColor(Color.red);
- od.drawBox(og);
- g.drawImage(offscreen, 0, 0, this);
- }
- }
+
}
// the overview is being calculated
private volatile boolean restart = false;
+ private volatile boolean updaterunning = false;
+
private BufferedImage miniMe;
private BufferedImage lastMiniMe = null;
* Signals to drawing code that the associated alignment viewport
* has changed and a redraw will be required
*/
- public void restartDraw()
+ public boolean restartDraw()
{
- restart = true;
+ synchronized (this)
+ {
+ if (updaterunning)
+ {
+ restart = true;
+ }
+ else
+ {
+ updaterunning = true;
+ }
+ return restart;
+ }
}
public void draw(boolean showSequenceFeatures, boolean showAnnotation)
}
else
{
+ updaterunning = false;
lastMiniMe = miniMe;
}
}
private AlignmentPanel ap;
- boolean updateRunning = false;
-
/**
* Creates a new OverviewPanel object.
*
setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
- if (updateRunning)
+ if (oviewCanvas.restartDraw())
{
- oviewCanvas.restartDraw();
return;
}
- updateRunning = true;
Thread thread = new Thread(this);
thread.start();
repaint();
- updateRunning = false;
+
}
@Override