From: hansonr Date: Mon, 29 Jul 2019 20:24:46 +0000 (-0500) Subject: JAL-3369 JAL-3253-applet adds embedded dim checking for overview frame X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=04e88679fd837e9fe36d186e5eacdd5f13a89927;p=jalview.git JAL-3369 JAL-3253-applet adds embedded dim checking for overview frame --- diff --git a/src/jalview/api/AlignmentViewPanel.java b/src/jalview/api/AlignmentViewPanel.java index ad7800c..9593a5b 100644 --- a/src/jalview/api/AlignmentViewPanel.java +++ b/src/jalview/api/AlignmentViewPanel.java @@ -23,6 +23,8 @@ package jalview.api; import jalview.datamodel.AlignmentI; import jalview.structure.StructureSelectionManager; +import java.awt.image.BufferedImage; + /** * abstract interface implemented by alignment panels holding an alignment view * @@ -65,4 +67,7 @@ public interface AlignmentViewPanel extends OOMHandlerI String getViewName(); SequenceRenderer getSequenceRenderer(); + + void overviewDone(BufferedImage miniMe); + } diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java index 58569cd..df8fe87 100644 --- a/src/jalview/appletgui/AlignmentPanel.java +++ b/src/jalview/appletgui/AlignmentPanel.java @@ -43,6 +43,7 @@ import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; +import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.util.List; @@ -178,6 +179,7 @@ public class AlignmentPanel extends Panel return av; } + @Override public SequenceRenderer getSequenceRenderer() { return seqPanel.seqCanvas.sr; @@ -1158,4 +1160,10 @@ public class AlignmentPanel extends Panel } + @Override + public void overviewDone(BufferedImage miniMe) + { + overviewPanel.canvas.finalizeDraw(miniMe); + } + } diff --git a/src/jalview/appletgui/OverviewCanvas.java b/src/jalview/appletgui/OverviewCanvas.java index 07f5919..5ea9c04 100644 --- a/src/jalview/appletgui/OverviewCanvas.java +++ b/src/jalview/appletgui/OverviewCanvas.java @@ -30,7 +30,9 @@ import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; +import java.awt.image.BufferedImage; +@SuppressWarnings("serial") public class OverviewCanvas extends Component { // This is set true if the alignment view changes whilst @@ -49,13 +51,23 @@ public class OverviewCanvas extends Component private AlignViewport av; + private boolean showSequenceFeatures; + + private boolean showAnnotation; + + private jalview.api.FeatureRenderer featureRenderer; + private jalview.renderer.seqfeatures.FeatureRenderer fr; private Frame nullFrame; - public OverviewCanvas(OverviewDimensions overviewDims, + private OverviewPanel panel; + + public OverviewCanvas(OverviewPanel panel, + OverviewDimensions overviewDims, AlignViewport alignvp) { + this.panel = panel; od = overviewDims; av = alignvp; @@ -101,46 +113,24 @@ public class OverviewCanvas extends Component } public void draw(boolean showSequenceFeatures, boolean showAnnotation, - FeatureRenderer transferRenderer) + jalview.api.FeatureRenderer featureRenderer) { - miniMe = null; + this.showSequenceFeatures = showSequenceFeatures; + this.showAnnotation = showAnnotation; + this.featureRenderer = featureRenderer; if (showSequenceFeatures) { - fr.transferSettings(transferRenderer); + fr.transferSettings(featureRenderer); } setPreferredSize(new Dimension(od.getWidth(), od.getHeight())); - or = new OverviewRenderer(fr, od, av.getAlignment(), + or = new OverviewRenderer(panel.ap, fr, od, av.getAlignment(), av.getResidueShading(), new OverviewResColourFinder()); - miniMe = nullFrame.createImage(od.getWidth(), od.getHeight()); offscreen = nullFrame.createImage(od.getWidth(), od.getHeight()); - - miniMe = or.draw(od.getRows(av.getAlignment()), + or.draw(od.getRows(av.getAlignment()), od.getColumns(av.getAlignment())); - - Graphics mg = miniMe.getGraphics(); - - // checks for conservation annotation to make sure overview works for DNA - // too - if (showAnnotation) - { - mg.translate(0, od.getSequencesHeight()); - or.drawGraph(mg, av.getAlignmentConservationAnnotation(), - od.getGraphHeight(), od.getColumns(av.getAlignment())); - mg.translate(0, -od.getSequencesHeight()); - } - - if (restart) - { - restart = false; - draw(showSequenceFeatures, showAnnotation, transferRenderer); - } - else - { - updaterunning = false; - } } @Override @@ -152,13 +142,14 @@ public class OverviewCanvas extends Component @Override public void paint(Graphics g) { - Graphics og = offscreen.getGraphics(); if (miniMe != null) { + Graphics og = offscreen.getGraphics(); og.drawImage(miniMe, 0, 0, this); og.setColor(Color.red); od.drawBox(og); g.drawImage(offscreen, 0, 0, this); + og.dispose(); } } @@ -170,4 +161,29 @@ public class OverviewCanvas extends Component od = null; } + public void finalizeDraw(BufferedImage miniMe) + { + Graphics mg = miniMe.getGraphics(); + + // checks for conservation annotation to make sure overview works for DNA + // too + if (showAnnotation) + { + mg.translate(0, od.getSequencesHeight()); + or.drawGraph(mg, av.getAlignmentConservationAnnotation(), + od.getGraphHeight(), od.getColumns(av.getAlignment())); + mg.translate(0, -od.getSequencesHeight()); + } + + if (restart) + { + restart = false; + draw(showSequenceFeatures, showAnnotation, featureRenderer); + } + else + { + updaterunning = false; + } + } + } diff --git a/src/jalview/appletgui/OverviewPanel.java b/src/jalview/appletgui/OverviewPanel.java index 4e69399..ef684f7 100755 --- a/src/jalview/appletgui/OverviewPanel.java +++ b/src/jalview/appletgui/OverviewPanel.java @@ -46,16 +46,17 @@ import java.beans.PropertyChangeEvent; import javax.swing.SwingUtilities; +@SuppressWarnings("serial") public class OverviewPanel extends Panel implements Runnable, MouseMotionListener, MouseListener, ViewportListenerI { - private OverviewDimensions od; + OverviewDimensions od; - private OverviewCanvas oviewCanvas; + OverviewCanvas canvas; private AlignViewport av; - private AlignmentPanel ap; + AlignmentPanel ap; private boolean showHidden = true; @@ -73,9 +74,9 @@ public class OverviewPanel extends Panel implements Runnable, (av.isShowAnnotation() && av.getSequenceConsensusHash() != null)); - oviewCanvas = new OverviewCanvas(od, av); + canvas = new OverviewCanvas(this, od, av); setLayout(new BorderLayout()); - add(oviewCanvas, BorderLayout.CENTER); + add(canvas, BorderLayout.CENTER); setSize(new Dimension(od.getWidth(), od.getHeight())); @@ -220,7 +221,7 @@ public class OverviewPanel extends Panel implements Runnable, */ public void updateOverviewImage() { - if (oviewCanvas == null) + if (canvas == null) { /* * panel has been disposed @@ -239,7 +240,7 @@ public class OverviewPanel extends Panel implements Runnable, { if (updateRunning) { - oviewCanvas.restartDraw(); + canvas.restartDraw(); return; } @@ -254,7 +255,7 @@ public class OverviewPanel extends Panel implements Runnable, @Override public void run() { - oviewCanvas.draw(av.isShowSequenceFeatures(), + canvas.draw(av.isShowSequenceFeatures(), (av.isShowAnnotation() && av.getAlignmentConservationAnnotation() != null), ap.seqPanel.seqCanvas.getFeatureRenderer()); @@ -321,7 +322,7 @@ public class OverviewPanel extends Panel implements Runnable, (av.isShowAnnotation() && av.getAlignmentConservationAnnotation() != null)); } - oviewCanvas.resetOviewDims(od); + canvas.resetOviewDims(od); updateOverviewImage(); } @@ -339,11 +340,11 @@ public class OverviewPanel extends Panel implements Runnable, } finally { av = null; - if (oviewCanvas != null) + if (canvas != null) { - oviewCanvas.dispose(); + canvas.dispose(); } - oviewCanvas = null; + canvas = null; ap = null; od = null; } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 01aa9b0..4fa8408 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -3385,12 +3385,38 @@ public class AlignFrame extends GAlignFrame } JInternalFrame frame = new JInternalFrame(); - final OverviewPanel overview = new OverviewPanel(alignPanel); + + // BH 2019.07.26 we allow for an embedded + // undecorated overview with defined size + frame.setName(Jalview.getAppID("overview")); + // + Dimension dim = (Dimension) Platform.getEmbeddedAttribute(frame, + Platform.EMBEDDED_DIM); + if (dim != null && dim.width == 0) + { + dim = null; // hidden, not embedded + } + + OverviewPanel overview = new OverviewPanel(alignPanel, dim); + frame.setContentPane(overview); + if (dim == null) + { + dim = new Dimension(); + // was frame.getSize(), but that is 0,0 at this point; + } + else + { + // we are imbedding, and so we have an undecorated frame + // and we can set the the frame dimensions accordingly. + } + // allowing for unresizable option using, style="resize:none" + boolean resizable = (Platform.getEmbeddedAttribute(frame, + "resize") != "none"); Desktop.addInternalFrame(frame, MessageManager .formatMessage("label.overview_params", new Object[] - { this.getTitle() }), true, frame.getWidth(), frame.getHeight(), - true, true, "overview"); + { this.getTitle() }), true, dim.width, dim.height, resizable, + true); frame.pack(); frame.setLayer(JLayeredPane.PALETTE_LAYER); frame.addInternalFrameListener( diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index 5fa8fdf..d305183 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -1840,4 +1840,10 @@ public class AlignmentPanel extends GAlignmentPanel implements return true; } + @Override + public void overviewDone(BufferedImage miniMe) + { + overviewPanel.canvas.finalizeDraw(miniMe); + } + } diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 957fb96..9fbfb83 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -864,7 +864,7 @@ public class Desktop extends GDesktop final JInternalFrame frame, String title, int w, int h, boolean resizable) { - addInternalFrame(frame, title, true, w, h, resizable, false, null); + addInternalFrame(frame, title, true, w, h, resizable, false); } /** @@ -887,38 +887,8 @@ public class Desktop extends GDesktop * Do not set the default minimum size for frame */ public static synchronized void addInternalFrame( - JInternalFrame frame, String title, boolean makeVisible, int w, - int h, boolean resizable, boolean ignoreMinSize) - { - addInternalFrame(frame, title, makeVisible, w, h, resizable, - ignoreMinSize, null); - } - - /** - * Add an internal frame to the Jalview desktop - * - * @param frame - * Frame to show - * @param title - * Visible Title - * @param makeVisible - * When true, display frame immediately, otherwise, caller must call - * setVisible themselves. - * @param w - * width - * @param h - * height - * @param resizable - * Allow resize - * @param ignoreMinSize - * Do not set the default minimum size for frame - * @param name - * for HTML div embedding - */ - public static synchronized void addInternalFrame( final JInternalFrame frame, String title, boolean makeVisible, - int w, int h, boolean resizable, boolean ignoreMinSize, - String name) + int w, int h, boolean resizable, boolean ignoreMinSize) { @@ -927,13 +897,8 @@ public class Desktop extends GDesktop // TODO: consider fixing method to update entries in the window submenu with // the current window title - if (name != null) - { - frame.setName(Jalview.getAppID(name)); - } - frame.setTitle(title); - if (frame.getWidth() < 1 || frame.getHeight() < 1) + if (w > 0 && (frame.getWidth() < 1 || frame.getHeight() < 1)) { frame.setSize(w, h); } diff --git a/src/jalview/gui/OverviewCanvas.java b/src/jalview/gui/OverviewCanvas.java index ca27a9c..aafac38 100644 --- a/src/jalview/gui/OverviewCanvas.java +++ b/src/jalview/gui/OverviewCanvas.java @@ -22,6 +22,7 @@ package jalview.gui; import jalview.api.AlignViewportI; import jalview.bin.Cache; +import jalview.datamodel.AlignmentI; import jalview.renderer.OverviewRenderer; import jalview.renderer.OverviewResColourFinder; import jalview.viewmodel.OverviewDimensions; @@ -33,6 +34,7 @@ import java.awt.image.BufferedImage; import javax.swing.JPanel; +@SuppressWarnings("serial") public class OverviewCanvas extends JPanel { private static final Color TRANS_GREY = new Color(100, 100, 100, 25); @@ -43,9 +45,7 @@ public class OverviewCanvas extends JPanel private volatile boolean updaterunning = false; - private boolean dispose = false; - - private BufferedImage miniMe; + private boolean disposed = false; private BufferedImage lastMiniMe = null; @@ -65,9 +65,19 @@ public class OverviewCanvas extends JPanel private ProgressPanel progressPanel; - public OverviewCanvas(OverviewDimensions overviewDims, + private boolean showSequenceFeatures; + + private boolean showAnnotation; + + private jalview.api.FeatureRenderer featureRenderer; + + private OverviewPanel panel; + + public OverviewCanvas(OverviewPanel panel, + OverviewDimensions overviewDims, AlignViewportI alignvp, ProgressPanel pp) { + this.panel = panel; od = overviewDims; av = alignvp; progressPanel = pp; @@ -84,6 +94,7 @@ public class OverviewCanvas extends JPanel cf = new OverviewResColourFinder(useLegacy, gapCol, hiddenCol); setSize(od.getWidth(), od.getHeight()); + setPreferredSize(getSize()); // BH 2019.07.29 added } /** @@ -107,11 +118,7 @@ public class OverviewCanvas extends JPanel { if (updaterunning) { - restart = true; - if (or != null) - { - or.setRedraw(true); - } + setRestart("restartDraw"); } else { @@ -121,6 +128,16 @@ public class OverviewCanvas extends JPanel } } + private void setRestart(String why) + { + // System.out.println("OC restart true " + why); + restart = true; + if (or != null) + { + or.setRedraw(true); + } + } + /** * Draw the overview sequences * @@ -128,31 +145,40 @@ public class OverviewCanvas extends JPanel * true if sequence features are to be shown * @param showAnnotation * true if the annotation is to be shown - * @param transferRenderer + * @param featureRenderer * the renderer to transfer feature colouring from */ public void draw(boolean showSequenceFeatures, boolean showAnnotation, - FeatureRenderer transferRenderer) + jalview.api.FeatureRenderer featureRenderer) { - miniMe = null; + this.showSequenceFeatures = showSequenceFeatures; + this.showAnnotation = showAnnotation; + this.featureRenderer = featureRenderer; + + // System.out.println("OC draw " + ++ndraw + " showseqf=" + // + showSequenceFeatures + " showAnno=" + showAnnotation); if (showSequenceFeatures) { - fr.transferSettings(transferRenderer); + fr.transferSettings(featureRenderer); } setPreferredSize(new Dimension(od.getWidth(), od.getHeight())); - or = new OverviewRenderer(fr, od, av.getAlignment(), - av.getResidueShading(), cf); - - or.addPropertyChangeListener(progressPanel); - - miniMe = or.draw(od.getRows(av.getAlignment()), - od.getColumns(av.getAlignment())); + AlignmentI al = av.getAlignment(); + or = new OverviewRenderer(panel.ap, fr, od, al, + av.getResidueShading(), cf, + progressPanel != null); + if (progressPanel != null) + { + or.addPropertyChangeListener(progressPanel); + } + or.draw(od.getRows(al), od.getColumns(al)); + } + void finalizeDraw(BufferedImage miniMe) + { Graphics mg = miniMe.getGraphics(); - if (showAnnotation) { mg.translate(0, od.getSequencesHeight()); @@ -160,113 +186,125 @@ public class OverviewCanvas extends JPanel od.getGraphHeight(), od.getColumns(av.getAlignment())); mg.translate(0, -od.getSequencesHeight()); } - - or.removePropertyChangeListener(progressPanel); + mg.dispose(); // BH 2019 + if (progressPanel != null) + { + or.removePropertyChangeListener(progressPanel); + } or = null; if (restart) { restart = false; - if (!dispose) + if (!disposed) { - draw(showSequenceFeatures, showAnnotation, transferRenderer); + draw(showSequenceFeatures, showAnnotation, featureRenderer); } } else { updaterunning = false; lastMiniMe = miniMe; + repaint(); } - } + } @Override public void paintComponent(Graphics g) { - //super.paintComponent(g); + int w = getWidth(); + int h = getHeight(); + if (w == 0 || od.getBoxWidth() <= 0) + { + // BH 2019.07.27 removes two unnecessary paints, since boxwidth can be -1 + // or 0 during early-stage painting + return; + } + + boolean drawMe = (lastMiniMe != null); if (restart) { - if (lastMiniMe == null) + if (drawMe) { - g.setColor(Color.white); - g.fillRect(0, 0, getWidth(), getHeight()); + g.drawImage(lastMiniMe, 0, 0, w, h, this); } else { - g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this); + g.setColor(Color.white); + g.fillRect(0, 0, w, h); } g.setColor(TRANS_GREY); - g.fillRect(0, 0, getWidth(), getHeight()); + g.fillRect(0, 0, w, h); + drawMe = false; } - else if (lastMiniMe != null) + else if (drawMe) { // is this a resize? - if ((getWidth() > 0) && (getHeight() > 0) - && ((getWidth() != od.getWidth()) - || (getHeight() != od.getHeight()))) + if (w != od.getWidth() || h != od.getHeight()) { + // if there is annotation, scale the alignment and annotation + // separately + if (od.getGraphHeight() <= 0 && od.getSequencesHeight() <= 0) { - // if there is annotation, scale the alignment and annotation - // separately - if (od.getGraphHeight() > 0 - && od.getSequencesHeight() > 0 // BH 2019 - ) - { - BufferedImage topImage = lastMiniMe.getSubimage(0, 0, - od.getWidth(), od.getSequencesHeight()); - BufferedImage bottomImage = lastMiniMe.getSubimage(0, - od.getSequencesHeight(), od.getWidth(), - od.getGraphHeight()); - - // must be done at this point as we rely on using old width/height - // above, and new width/height below - od.setWidth(getWidth()); - od.setHeight(getHeight()); - - // stick the images back together so lastMiniMe is consistent in the - // event of a repaint - BUT probably not thread safe - lastMiniMe = new BufferedImage(od.getWidth(), od.getHeight(), - BufferedImage.TYPE_INT_RGB); - Graphics lg = lastMiniMe.getGraphics(); - lg.drawImage(topImage, 0, 0, od.getWidth(), - od.getSequencesHeight(), null); - lg.drawImage(bottomImage, 0, od.getSequencesHeight(), - od.getWidth(), od.getGraphHeight(), this); - lg.dispose(); - } - else - { - od.setWidth(getWidth()); - od.setHeight(getHeight()); - } - - // make sure the box is in the right place - od.setBoxPosition(av.getAlignment().getHiddenSequences(), - av.getAlignment().getHiddenColumns()); + od.setWidth(w); + od.setHeight(h); + return; + } + // System.out.println("OC new subimages"); + BufferedImage topImage = lastMiniMe.getSubimage(0, 0, od.getWidth(), + od.getSequencesHeight()); + BufferedImage bottomImage = lastMiniMe.getSubimage(0, + od.getSequencesHeight(), od.getWidth(), od.getGraphHeight()); + + // must be done at this point as we rely on using old width/height + // above, and new width/height below + od.setWidth(w); + od.setHeight(h); + + // stick the images back together so lastMiniMe is consistent in the + // event of a repaint - BUT probably not thread safe + // System.out.println("OC new lastminime " + w + " " + h); + lastMiniMe = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics lg = lastMiniMe.getGraphics(); + lg.drawImage(topImage, 0, 0, w, od.getSequencesHeight(), null); + lg.drawImage(bottomImage, 0, od.getSequencesHeight(), w, + od.getGraphHeight(), this); + lg.dispose(); + // BH 2019: removed -- this is now taken care of using vpbox in + // OverviewDimension + // // make sure the box is in the right place + // od.setBoxPosition(av.getAlignment().getHiddenSequences(), + // av.getAlignment().getHiddenColumns()); } - // fall back to normal behaviour - g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this); } - else + + if (drawMe) { - g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this); + g.drawImage(lastMiniMe, 0, 0, w, h, this); } - // draw the box g.setColor(Color.red); + // System.out.println("OC paintComponent nd=" + ndraw + " nr=" + nrepaint + // + " np=" + ++npaint); od.drawBox(g); } + private int ndraw, npaint, nrepaint; + + // @Override + // public void repaint() + // { + // System.out.println("OC repaint " + (++nrepaint)); + // super.repaint(); + // } public void dispose() { - dispose = true; + disposed = true; od = null; synchronized (this) { - restart = true; - if (or != null) - { - or.setRedraw(true); - } + setRestart("dispose"); } } + } diff --git a/src/jalview/gui/OverviewPanel.java b/src/jalview/gui/OverviewPanel.java index a5aaf7c..8f24185 100755 --- a/src/jalview/gui/OverviewPanel.java +++ b/src/jalview/gui/OverviewPanel.java @@ -20,6 +20,8 @@ */ package jalview.gui; +import jalview.api.AlignViewportI; +import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.renderer.OverviewRenderer; import jalview.util.MessageManager; @@ -61,11 +63,11 @@ public class OverviewPanel extends JPanel { protected OverviewDimensions od; - private OverviewCanvas oviewCanvas; + OverviewCanvas canvas; - protected AlignViewport av; + protected AlignViewportI av; - private AlignmentPanel ap; + AlignmentViewPanel ap; protected JCheckBoxMenuItem displayToggle; @@ -75,70 +77,79 @@ public class OverviewPanel extends JPanel protected ProgressPanel progressPanel; + private Dimension dim; + + private boolean showProgress = !Platform.isJS(); // Jalview.getInstance().getShowStatus() + /** * Creates a new OverviewPanel object. * * @param alPanel * The alignment panel which is shown in the overview panel */ - public OverviewPanel(AlignmentPanel alPanel) + public OverviewPanel(AlignmentViewPanel alPanel, Dimension dim) { - this.av = alPanel.av; + this.av = alPanel.getAlignViewport(); this.ap = alPanel; + this.dim = dim; showHidden = Cache.getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false); - if (showHidden) - { - od = new OverviewDimensionsShowHidden(av.getRanges(), - (av.isShowAnnotation() - && av.getAlignmentConservationAnnotation() != null)); - } - else - { - od = new OverviewDimensionsHideHidden(av.getRanges(), - (av.isShowAnnotation() - && av.getAlignmentConservationAnnotation() != null)); - } - + createOverviewDimensions(); setLayout(new BorderLayout()); progressPanel = new ProgressPanel(OverviewRenderer.UPDATE, MessageManager.getString("label.oview_calc"), getWidth()); - this.add(progressPanel, BorderLayout.SOUTH); - oviewCanvas = new OverviewCanvas(od, av, progressPanel); - - add(oviewCanvas, BorderLayout.CENTER); + if (showProgress) // BH 2019 + { + add(progressPanel, BorderLayout.SOUTH); + } + canvas = new OverviewCanvas(this, od, av, + showProgress ? progressPanel : null); + canvas.setPreferredSize(canvas.getSize()); + add(canvas, BorderLayout.CENTER); av.getRanges().addPropertyChangeListener(this); // without this the overview window does not size to fit the overview canvas - setPreferredSize(new Dimension(od.getWidth(), od.getHeight())); - + // BH - no,no! - This does not include the progressPanel! + // BH the problem was that OverviewCanvas.setPreferredSize() had not been set. + // setPreferredSize(new Dimension(od.getWidth(), od.getHeight())); + addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent evt) { + int ph = (progressPanel.getParent() == null ? 0 + : progressPanel.getHeight()); // Resize is called on the initial display of the overview. // This code adjusts sizes to account for the progress bar if it has not // already been accounted for, which triggers another resize call for // the correct sizing, at which point the overview image is updated. // (This avoids a double recalculation of the image.) - if (getWidth() == od.getWidth() && getHeight() == od.getHeight() - + progressPanel.getHeight()) + if (getWidth() == od.getWidth() + && getHeight() == od.getHeight() + ph) { updateOverviewImage(); } else { - if ((getWidth() > 0) && (getHeight() > 0)) + int w = getWidth(); + int h = getHeight(); + if ((w > 0) && (h > 0)) { - od.setWidth(getWidth()); - od.setHeight(getHeight() - progressPanel.getHeight()); + if (dim != null) + { + dim.setSize(w, h - ph); + } + od.setWidth(w); + od.setHeight(h - ph); + repaint(); } - - setPreferredSize(new Dimension(od.getWidth(), - od.getHeight() + progressPanel.getHeight())); + // BH 2019.07.29 this is unnecessary -- it is what layout managers are + // for: + // setPreferredSize(new Dimension(od.getWidth(), od.getHeight() + + // ph)); } } @@ -195,37 +206,39 @@ public class OverviewPanel extends JPanel @Override public void mousePressed(MouseEvent evt) { - - if (Platform.isWinRightButton(evt)) { - showPopupMenu(evt); - return; - } - if (SwingUtilities.isRightMouseButton(evt)) { - return; + + if (Platform.isWinRightButton(evt)) + { + showPopupMenu(evt); + return; } - // don't do anything if the mouse press is in the overview's box - // (wait to see if it's a drag instead) - // otherwise update the viewport - if (!od.isPositionInBox(evt.getX(), evt.getY())) - { - draggingBox = false; + if (SwingUtilities.isRightMouseButton(evt)) + { + return; + } + // don't do anything if the mouse press is in the overview's box + // (wait to see if it's a drag instead) + // otherwise update the viewport + if (!od.isPositionInBox(evt.getX(), evt.getY())) + { + draggingBox = false; - // display drag cursor at mouse position - setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + // display drag cursor at mouse position + setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); - od.updateViewportFromMouse(evt.getX(), evt.getY(), - av.getAlignment().getHiddenSequences(), - av.getAlignment().getHiddenColumns()); - getParent().setCursor( - Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - else - { - draggingBox = true; - od.setDragPoint(evt.getX(), evt.getY(), - av.getAlignment().getHiddenSequences(), - av.getAlignment().getHiddenColumns()); - } + od.updateViewportFromMouse(evt.getX(), evt.getY(), + av.getAlignment().getHiddenSequences(), + av.getAlignment().getHiddenColumns()); + getParent().setCursor( + Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + else + { + draggingBox = true; + od.setDragPoint(evt.getX(), evt.getY(), + av.getAlignment().getHiddenSequences(), + av.getAlignment().getHiddenColumns()); + } } @Override @@ -255,6 +268,26 @@ public class OverviewPanel extends JPanel } } + /** + * Create the appropriate type of OverViewDimensions, with the desired size. + */ + private void createOverviewDimensions() + { + boolean showAnnotation = (av.isShowAnnotation() + && av.getAlignmentConservationAnnotation() != null); + if (showHidden) + { + od = new OverviewDimensionsShowHidden(av.getRanges(), showAnnotation, + dim); + } + else + { + od = new OverviewDimensionsHideHidden(av.getRanges(), showAnnotation, + dim); + } + + } + /* * Displays the popup menu and acts on user input */ @@ -285,21 +318,9 @@ public class OverviewPanel extends JPanel */ protected void toggleHiddenColumns() { - if (showHidden) - { - showHidden = false; - od = new OverviewDimensionsHideHidden(av.getRanges(), - (av.isShowAnnotation() - && av.getAlignmentConservationAnnotation() != null)); - } - else - { - showHidden = true; - od = new OverviewDimensionsShowHidden(av.getRanges(), - (av.isShowAnnotation() - && av.getAlignmentConservationAnnotation() != null)); - } - oviewCanvas.resetOviewDims(od); + showHidden = !showHidden; + createOverviewDimensions(); + canvas.resetOviewDims(od); updateOverviewImage(); setBoxPosition(); } @@ -309,7 +330,7 @@ public class OverviewPanel extends JPanel */ public void updateOverviewImage() { - if (oviewCanvas == null) + if (canvas == null) { /* * panel has been disposed @@ -317,36 +338,35 @@ public class OverviewPanel extends JPanel return; } + int ph = (progressPanel.getParent() == null ? 0 + : progressPanel.getHeight()); + if ((getWidth() > 0) && (getHeight() > 0)) { od.setWidth(getWidth()); - od.setHeight(getHeight() - progressPanel.getHeight()); + od.setHeight(getHeight() - ph); } - - setPreferredSize(new Dimension(od.getWidth(), - od.getHeight() + progressPanel.getHeight())); - if (oviewCanvas.restartDraw()) + setPreferredSize(new Dimension(od.getWidth(), od.getHeight() + ph)); + + if (canvas.restartDraw()) { return; } Thread thread = new Thread(this); thread.start(); - repaint(); - - } @Override public void run() { - if (oviewCanvas != null) + if (canvas != null) { - oviewCanvas.draw(av.isShowSequenceFeatures(), + canvas.draw(av.isShowSequenceFeatures(), (av.isShowAnnotation() && av.getAlignmentConservationAnnotation() != null), - ap.getSeqPanel().seqCanvas.getFeatureRenderer()); + ap.getFeatureRenderer()); setBoxPosition(); } } @@ -360,6 +380,7 @@ public class OverviewPanel extends JPanel { if (od != null) { + od.updateBox(); int oldX = od.getBoxX(); int oldY = od.getBoxY(); int oldWidth = od.getBoxWidth(); @@ -400,14 +421,15 @@ public class OverviewPanel extends JPanel av.getRanges().removePropertyChangeListener(this); } - oviewCanvas.dispose(); + canvas.dispose(); /* * close the parent frame (which also removes it from the * Desktop Windows menu) */ - ((JInternalFrame) SwingUtilities.getAncestorOfClass( - JInternalFrame.class, (this))).setClosed(true); + ((JInternalFrame) SwingUtilities + .getAncestorOfClass(JInternalFrame.class, (this))) + .setClosed(true); } catch (PropertyVetoException e) { // ignore @@ -415,7 +437,7 @@ public class OverviewPanel extends JPanel { progressPanel = null; av = null; - oviewCanvas = null; + canvas = null; ap = null; od = null; } diff --git a/src/jalview/renderer/OverviewRenderer.java b/src/jalview/renderer/OverviewRenderer.java index c9096e2..45cc944 100644 --- a/src/jalview/renderer/OverviewRenderer.java +++ b/src/jalview/renderer/OverviewRenderer.java @@ -22,6 +22,7 @@ package jalview.renderer; import jalview.api.AlignmentColsCollectionI; import jalview.api.AlignmentRowsCollectionI; +import jalview.api.AlignmentViewPanel; import jalview.api.RendererListenerI; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; @@ -30,14 +31,23 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.renderer.seqfeatures.FeatureColourFinder; import jalview.renderer.seqfeatures.FeatureRenderer; +import jalview.util.Platform; import jalview.viewmodel.OverviewDimensions; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.awt.image.WritableRaster; import java.beans.PropertyChangeSupport; +import java.util.BitSet; +import java.util.Iterator; + +import javax.swing.Timer; public class OverviewRenderer { @@ -75,10 +85,25 @@ public class OverviewRenderer private OverviewResColourFinder resColFinder; - public OverviewRenderer(FeatureRenderer fr, OverviewDimensions od, + private boolean showProgress; + + private AlignmentViewPanel panel; + + public OverviewRenderer(AlignmentViewPanel panel, FeatureRenderer fr, + OverviewDimensions od, AlignmentI alignment, ResidueShaderI resshader, OverviewResColourFinder colFinder) { + this(panel, fr, od, alignment, resshader, colFinder, true); + } + + public OverviewRenderer(AlignmentViewPanel panel, + jalview.api.FeatureRenderer fr, + OverviewDimensions od, + AlignmentI alignment, ResidueShaderI resshader, + OverviewResColourFinder colFinder, boolean showProgress) + { + this.panel = panel; finder = new FeatureColourFinder(fr); resColFinder = colFinder; @@ -90,108 +115,243 @@ public class OverviewRenderer graphHeight = od.getGraphHeight(); miniMe = new BufferedImage(od.getWidth(), od.getHeight(), BufferedImage.TYPE_INT_RGB); + this.showProgress = showProgress; } - /** - * Draw alignment rows and columns onto an image - * - * @param rit - * Iterator over rows to be drawn - * @param cit - * Iterator over columns to be drawn - * @return image containing the drawing - */ - public BufferedImage draw(AlignmentRowsCollectionI rows, - AlignmentColsCollectionI cols) + final static int STATE_INIT = 0; + final static int STATE_NEXT = 1; + final static int STATE_DONE = 2; + + int state; + + boolean isJS = Platform.isJS(); + + Timer timer; + int delay = (isJS ? 1 : 0); + + int seqIndex; + + int pixelRow; + + private Integer row; + + void mainLoop() + { + while (!redraw) + { + switch (state) + { + case STATE_INIT: + seqIndex = 0; + pixelRow = 0; + state = STATE_NEXT; + continue; + case STATE_NEXT: + if (iter.hasNext()) + { + nextRow(); + } + else + { + state = STATE_DONE; + } + break; + case STATE_DONE: + done(); + return; + } + if (delay > 0) + { + jsloop(); + return; + } + } + done(); + } + + private void jsloop() + { + if (timer == null) + { + timer = new Timer(delay, new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + mainLoop(); + } + + }); + timer.setRepeats(false); + timer.start(); + } + else + { + timer.restart(); + } + } + + private void nextRow() { - int rgbcolor = Color.white.getRGB(); - int seqIndex = 0; - int pixelRow = 0; - int alignmentHeight = miniMe.getHeight() - graphHeight; - int totalPixels = miniMe.getWidth() * alignmentHeight; + row = iter.next(); + // System.out.println("OR row " + r); + // get details of this alignment row + SequenceI seq = rows.getSequence(row); - int lastRowUpdate = 0; - int lastUpdate = 0; - changeSupport.firePropertyChange(UPDATE, -1, 0); + // rate limiting step when rendering overview for lots of groups + SequenceGroup[] allGroups = al.findAllGroups(seq); - for (int alignmentRow : rows) + // calculate where this row extends to in pixels + int endRow = Math.min(Math.round((++seqIndex) * pixelsPerSeq), h); + + for (int pixelCol = 0, colIndex = 0, c = bscol + .nextSetBit(0); c >= 0; c = bscol.nextSetBit(c + 1)) { if (redraw) { break; } - - // get details of this alignment row - SequenceI seq = rows.getSequence(alignmentRow); - // rate limiting step when rendering overview for lots of groups - SequenceGroup[] allGroups = al.findAllGroups(seq); + // calculate where this column extends to in pixels + int endCol = Math.min(Math.round((++colIndex) * pixelsPerCol), w); - // calculate where this row extends to in pixels - int endRow = Math.min(Math.round((seqIndex + 1) * pixelsPerSeq) - 1, - miniMe.getHeight() - 1); - - int colIndex = 0; - int pixelCol = 0; - for (int alignmentCol : cols) + // don't do expensive colour determination if we're not going to use it + // NB this is important to avoid performance issues in the overview + // panel + + if (pixelCol < endCol) { - if (redraw) - { - break; - } - - // calculate where this column extends to in pixels - int endCol = Math.min(Math.round((colIndex + 1) * pixelsPerCol) - 1, - miniMe.getWidth() - 1); - - // don't do expensive colour determination if we're not going to use it - // NB this is important to avoid performance issues in the overview - // panel - if (pixelCol <= endCol) + // System.out.println("OR pc ec " + pixelCol + " " + endCol); + int rgb = getColumnColourFromSequence(allGroups, seq, c); + // fill in the appropriate number of pixels + for (int row = pixelRow; row < endRow; ++row) { - rgbcolor = getColumnColourFromSequence(allGroups, seq, - alignmentCol); - - // fill in the appropriate number of pixels - for (int row = pixelRow; row <= endRow; ++row) + for (int col = pixelCol; col < endCol; ++col) { - for (int col = pixelCol; col <= endCol; ++col) - { - miniMe.setRGB(col, row, rgbcolor); - } + // BH 2019.07.27 was: + // + // miniMe.setRGB(col, row, rgbcolor); + // + // but just directly writing to the int[] pixel buffer + // is three times faster by my experimentation + pixels[row * w + col] = rgb; + ndone++; } + } + // } - // store last update value - lastUpdate = sendProgressUpdate( - (pixelCol + 1) * (endRow - pixelRow), totalPixels, - lastRowUpdate, lastUpdate); - - pixelCol = endCol + 1; + pixelCol = endCol; + // store last update value + if (showProgress) + { + lastUpdate = sendProgressUpdate(endCol * (endRow - 1 - pixelRow), + totalPixels, lastRowUpdate, lastUpdate); } - colIndex++; } - - if (pixelRow != endRow + 1) + } + if (pixelRow < endRow) + { + pixelRow = endRow; + // store row offset and last update value + if (showProgress) { - // store row offset and last update value - lastRowUpdate = sendProgressUpdate(endRow + 1, alignmentHeight, 0, + // BH 2019.07.29 was (old) endRow + 1 (now endRow), but should be + // pixelRow + 1, surely + lastRowUpdate = sendProgressUpdate(endRow, alignmentHeight, 0, lastUpdate); lastUpdate = lastRowUpdate; - pixelRow = endRow + 1; } - seqIndex++; } + } + + private void done() + { + Platform.timeCheck( + "overviewrender " + ndone + " pixels row:" + row + " redraw:" + + redraw, + Platform.TIME_MARK); overlayHiddenRegions(rows, cols); - // final update to progress bar if present - if (redraw) + if (showProgress) { - sendProgressUpdate(pixelRow - 1, alignmentHeight, 0, 0); + // final update to progress bar if present + if (redraw) + { + // aborted in Java + // BH was pixelRow - 1, but that could go negative + sendProgressUpdate(pixelRow, alignmentHeight, 0, 0); + } + else + { + // sendProgressUpdate(alignmentHeight, miniMe.getHeight(), 0, 0); + sendProgressUpdate(1, 1, 0, 0); + } } - else + panel.overviewDone(miniMe); + } + + int ndone = 0; + + private AlignmentRowsCollectionI rows; + + private AlignmentColsCollectionI cols; + + Iterator iter; + + int alignmentHeight; + + int totalPixels; + + int lastRowUpdate; + + int lastUpdate; + + int[] pixels; + + BitSet bscol = new BitSet(); + + int w, h; + + /** + * Draw alignment rows and columns onto an image + * + * @param rit + * Iterator over rows to be drawn + * @param cit + * Iterator over columns to be drawn + * @return image containing the drawing + */ + public BufferedImage draw(AlignmentRowsCollectionI rows, + AlignmentColsCollectionI cols) + { + this.rows = rows; + this.cols = cols; + iter = rows.iterator(); + + w = miniMe.getWidth(); + h = miniMe.getHeight(); + alignmentHeight = h - graphHeight; + totalPixels = w * alignmentHeight; + lastRowUpdate = 0; + lastUpdate = 0; + + if (showProgress) + { + changeSupport.firePropertyChange(UPDATE, -1, 0); + } + + WritableRaster raster = miniMe.getRaster(); + DataBufferInt db = (DataBufferInt) raster.getDataBuffer(); + Platform.timeCheck(null, Platform.TIME_MARK); + pixels = db.getBankData()[0]; + bscol.clear(); + for (int c : cols) { - sendProgressUpdate(alignmentHeight, miniMe.getHeight(), 0, 0); + bscol.set(c); } + state = STATE_INIT; + mainLoop(); + return miniMe; } @@ -222,18 +382,13 @@ public class OverviewRenderer * column position to get colour for * @return colour of sequence at this position, as RGB */ - int getColumnColourFromSequence(SequenceGroup[] allGroups, - SequenceI seq, int lastcol) + int getColumnColourFromSequence(SequenceGroup[] allGroups, SequenceI seq, + int icol) { - Color color = resColFinder.GAP_COLOUR; - - if ((seq != null) && (seq.getLength() > lastcol)) - { - color = resColFinder.getResidueColour(true, shader, allGroups, seq, - lastcol, finder); - } - - return color.getRGB(); + return (seq == null || icol >= seq.getLength() + ? resColFinder.GAP_COLOUR + : resColFinder.getResidueColour(true, shader, allGroups, seq, + icol, finder)).getRGB(); } /** @@ -256,6 +411,7 @@ public class OverviewRenderer g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, TRANSPARENCY)); g.drawImage(mask, 0, 0, miniMe.getWidth(), miniMe.getHeight(), null); + g.dispose(); } } @@ -280,9 +436,6 @@ public class OverviewRenderer BufferedImage hiddenImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - int colIndex = 0; - int pixelCol = 0; - Color hidden = resColFinder.getHiddenColour(); Graphics2D g2d = (Graphics2D) hiddenImage.getGraphics(); @@ -294,55 +447,59 @@ public class OverviewRenderer // set next colour to opaque g2d.setComposite(AlphaComposite.Src); - for (int alignmentCol : cols) + if (cols.hasHidden()) { - if (redraw) + int colIndex = 0; + int pixelCol = 0; + for (int alignmentCol : cols) { - break; - } + if (redraw) + { + break; + } - // calculate where this column extends to in pixels - int endCol = Math.min(Math.round((colIndex + 1) * pixelsPerCol) - 1, - hiddenImage.getWidth() - 1); + // calculate where this column extends to in pixels + int endCol = Math.min(Math.round((++colIndex) * pixelsPerCol), + width); - if (pixelCol <= endCol) - { - // determine the colour based on the sequence and column position - if (cols.isHidden(alignmentCol)) + // endCol is one more than old endCol + if (pixelCol < endCol) { - g2d.setColor(hidden); - g2d.fillRect(pixelCol, 0, endCol - pixelCol + 1, height); + // determine the colour based on the sequence and column position + if (cols.isHidden(alignmentCol)) + { + g2d.setColor(hidden); + g2d.fillRect(pixelCol, 0, endCol - pixelCol, height); + } + pixelCol = endCol; } - - pixelCol = endCol + 1; } - colIndex++; - } - - int seqIndex = 0; - int pixelRow = 0; - for (int alignmentRow : rows) + if (rows.hasHidden()) { - if (redraw) + int seqIndex = 0; + int pixelRow = 0; + for (int alignmentRow : rows) { - break; - } + if (redraw) + { + break; + } - // calculate where this row extends to in pixels - int endRow = Math.min(Math.round((seqIndex + 1) * pixelsPerSeq) - 1, - miniMe.getHeight() - 1); + // calculate where this row extends to in pixels + int endRow = Math.min(Math.round((++seqIndex) * pixelsPerSeq), + height); - // get details of this alignment row - if (rows.isHidden(alignmentRow)) - { - g2d.setColor(hidden); - g2d.fillRect(0, pixelRow, width, endRow - pixelRow + 1); + // get details of this alignment row + if (rows.isHidden(alignmentRow)) + { + g2d.setColor(hidden); + g2d.fillRect(0, pixelRow, width, endRow - 1 - pixelRow); + } + pixelRow = endRow; } - pixelRow = endRow + 1; - seqIndex++; } - + g2d.dispose(); return hiddenImage; } @@ -362,56 +519,45 @@ public class OverviewRenderer AlignmentColsCollectionI cols) { Annotation[] annotations = anno.annotations; + float max = anno.graphMax; g.setColor(Color.white); - g.fillRect(0, 0, miniMe.getWidth(), y); + int width = miniMe.getWidth(); + g.fillRect(0, 0, width, y); - int height; int colIndex = 0; int pixelCol = 0; - for (int alignmentCol : cols) + for (int icol : cols) { if (redraw) { - changeSupport.firePropertyChange(UPDATE, MAX_PROGRESS - 1, 0); + if (showProgress) + { + changeSupport.firePropertyChange(UPDATE, MAX_PROGRESS - 1, 0); + } break; } - if (alignmentCol >= annotations.length) + if (icol >= annotations.length) { break; // no more annotations to draw here } - else + int endCol = Math.min(Math.round((++colIndex) * pixelsPerCol), width); + Annotation ann = annotations[icol]; + if (ann != null) { - int endCol = Math.min(Math.round((colIndex + 1) * pixelsPerCol) - 1, - miniMe.getWidth() - 1); - - if (annotations[alignmentCol] != null) - { - if (annotations[alignmentCol].colour == null) - { - g.setColor(Color.black); - } - else - { - g.setColor(annotations[alignmentCol].colour); - } - - height = (int) ((annotations[alignmentCol].value / anno.graphMax) - * y); - if (height > y) - { - height = y; - } - - g.fillRect(pixelCol, y - height, endCol - pixelCol + 1, height); - } + Color color = ann.colour; + g.setColor(color == null ? Color.black : color); - pixelCol = endCol + 1; - colIndex++; + int height = Math.min(y, (int) ((ann.value / max) * y)); + g.fillRect(pixelCol, y - height, endCol - pixelCol, height); } + pixelCol = endCol; + } + if (showProgress) + { + changeSupport.firePropertyChange(UPDATE, MAX_PROGRESS - 1, + MAX_PROGRESS); } - changeSupport.firePropertyChange(UPDATE, MAX_PROGRESS - 1, - MAX_PROGRESS); } /** diff --git a/src/jalview/viewmodel/OverviewDimensions.java b/src/jalview/viewmodel/OverviewDimensions.java index 0235081..3ac236d 100644 --- a/src/jalview/viewmodel/OverviewDimensions.java +++ b/src/jalview/viewmodel/OverviewDimensions.java @@ -26,7 +26,9 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.HiddenColumns; import jalview.datamodel.HiddenSequences; +import java.awt.Dimension; import java.awt.Graphics; +import java.awt.Rectangle; public abstract class OverviewDimensions { @@ -62,6 +64,8 @@ public abstract class OverviewDimensions protected float heightRatio; + private Rectangle vpbox = new Rectangle(); + /** * Create an OverviewDimensions object * @@ -71,17 +75,23 @@ public abstract class OverviewDimensions * true if the annotation panel is to be shown, false otherwise */ public OverviewDimensions(ViewportRanges ranges, - boolean showAnnotationPanel) + boolean showAnnotationPanel, Dimension dim) { + if (!showAnnotationPanel) + { + graphHeight = 0; + } + // scale the initial size of overviewpanel to shape of alignment float initialScale = (float) ranges.getAbsoluteAlignmentWidth() / (float) ranges.getAbsoluteAlignmentHeight(); - if (!showAnnotationPanel) + if (dim != null) { - graphHeight = 0; + width = dim.width; + sequencesHeight = dim.height; + return; } - if (ranges.getAbsoluteAlignmentWidth() > ranges .getAbsoluteAlignmentHeight()) { @@ -114,6 +124,9 @@ public abstract class OverviewDimensions */ public void drawBox(Graphics g) { + // System.out.println("OD drawBox " + boxX + " " + boxY + " " + boxWidth + // + " " + boxHeight); + updateBox(); g.drawRect(boxX, boxY, boxWidth, boxHeight); g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2); } @@ -178,6 +191,9 @@ public abstract class OverviewDimensions public void setHeight(int h) { + // BH 2019 problem was that component.resize() can come + // after setBoxPosition(). + // Solution was to move setting of box dimensions to paint sequencesHeight = h - graphHeight; heightRatio = (float) alheight / sequencesHeight; } @@ -276,17 +292,22 @@ public abstract class OverviewDimensions int vpheight) { resetAlignmentDims(); + vpbox = new Rectangle(startRes, startSeq, vpwidth, vpheight); + updateBox(); + } + public void updateBox() + { // boxX, boxY is the x,y location equivalent to startRes, startSeq - int xPos = Math.min(startRes, alwidth - vpwidth + 1); + int xPos = Math.min(vpbox.x, alwidth - vpbox.width + 1); boxX = Math.round(xPos / widthRatio); - boxY = Math.round(startSeq / heightRatio); + boxY = Math.round(vpbox.y / heightRatio); // boxWidth is the width in residues translated to pixels - boxWidth = Math.round(vpwidth / widthRatio); + boxWidth = Math.round(vpbox.width / widthRatio); // boxHeight is the height in sequences translated to pixels - boxHeight = Math.round(vpheight / heightRatio); + boxHeight = Math.round(vpbox.height / heightRatio); } /** diff --git a/src/jalview/viewmodel/OverviewDimensionsHideHidden.java b/src/jalview/viewmodel/OverviewDimensionsHideHidden.java index de90a21..d2dc607 100644 --- a/src/jalview/viewmodel/OverviewDimensionsHideHidden.java +++ b/src/jalview/viewmodel/OverviewDimensionsHideHidden.java @@ -28,6 +28,8 @@ import jalview.datamodel.HiddenSequences; import jalview.datamodel.VisibleColsCollection; import jalview.datamodel.VisibleRowsCollection; +import java.awt.Dimension; + public class OverviewDimensionsHideHidden extends OverviewDimensions { private ViewportRanges ranges; @@ -41,7 +43,13 @@ public class OverviewDimensionsHideHidden extends OverviewDimensions public OverviewDimensionsHideHidden(ViewportRanges vpranges, boolean showAnnotationPanel) { - super(vpranges, showAnnotationPanel); + this(vpranges, showAnnotationPanel, null); + } + + public OverviewDimensionsHideHidden(ViewportRanges vpranges, + boolean showAnnotationPanel, Dimension dim) + { + super(vpranges, showAnnotationPanel, dim); ranges = vpranges; resetAlignmentDims(); } diff --git a/src/jalview/viewmodel/OverviewDimensionsShowHidden.java b/src/jalview/viewmodel/OverviewDimensionsShowHidden.java index 3aa6e1b..0752097 100644 --- a/src/jalview/viewmodel/OverviewDimensionsShowHidden.java +++ b/src/jalview/viewmodel/OverviewDimensionsShowHidden.java @@ -28,6 +28,8 @@ import jalview.datamodel.AllRowsCollection; import jalview.datamodel.HiddenColumns; import jalview.datamodel.HiddenSequences; +import java.awt.Dimension; + public class OverviewDimensionsShowHidden extends OverviewDimensions { private ViewportRanges ranges; @@ -38,6 +40,12 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions private int ydiff; // when dragging, difference in alignment units between // start sequence and original mouse click position + public OverviewDimensionsShowHidden(ViewportRanges vpranges, + boolean showAnnotationPanel) + { + this(vpranges, showAnnotationPanel, null); + } + /** * Create an OverviewDimensions object * @@ -47,9 +55,9 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions * true if the annotation panel is to be shown, false otherwise */ public OverviewDimensionsShowHidden(ViewportRanges vpranges, - boolean showAnnotationPanel) + boolean showAnnotationPanel, Dimension dim) { - super(vpranges, showAnnotationPanel); + super(vpranges, showAnnotationPanel, dim); ranges = vpranges; resetAlignmentDims(); } diff --git a/test/jalview/renderer/OverviewRendererTest.java b/test/jalview/renderer/OverviewRendererTest.java index 1d532f7..0a77b65 100644 --- a/test/jalview/renderer/OverviewRendererTest.java +++ b/test/jalview/renderer/OverviewRendererTest.java @@ -54,7 +54,7 @@ public class OverviewRendererTest OverviewDimensions od = new OverviewDimensionsShowHidden(new ViewportRanges(al), false); ResidueShaderI rs = new ResidueShader(new ZappoColourScheme()); FeatureRenderer fr = new FeatureRenderer(av); - OverviewRenderer or = new OverviewRenderer(fr, od, al, rs, cf); + OverviewRenderer or = new OverviewRenderer(null, fr, od, al, rs, cf); // P is magenta (see ResidueProperties.zappo) assertEquals(or.getColumnColourFromSequence(null, seq1, 0), Color.magenta.getRGB());