X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAnnotationPanel.java;h=411c2448e579498bdcf2b96f2eab28179c923e66;hb=90d38cfe94515a5c34f37ecf709b387bcec82073;hp=eb0189eee5b29fb84c19818ef1cbfe0c59b129e9;hpb=298c2b85845dbaabda7e3304751cc856e7b0ad30;p=jalview.git diff --git a/src/jalview/gui/AnnotationPanel.java b/src/jalview/gui/AnnotationPanel.java index eb0189e..411c244 100755 --- a/src/jalview/gui/AnnotationPanel.java +++ b/src/jalview/gui/AnnotationPanel.java @@ -1,18 +1,18 @@ /* * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle - * + * * 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 + * 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 + * + * 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 . */ package jalview.gui; @@ -20,25 +20,20 @@ package jalview.gui; import java.awt.*; import java.awt.event.*; import java.awt.image.*; -import java.util.Hashtable; - import javax.swing.*; -import jalview.analysis.AAFrequency; -import jalview.analysis.StructureFrequency; import jalview.datamodel.*; import jalview.renderer.AnnotationRenderer; import jalview.renderer.AwtRenderPanelI; /** - * DOCUMENT ME! - * + * AnnotationPanel displays visible portion of annotation rows below unwrapped alignment * @author $author$ * @version $Revision$ */ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, - MouseListener, MouseMotionListener, ActionListener, - AdjustmentListener + MouseListener, MouseWheelListener, MouseMotionListener, + ActionListener, AdjustmentListener, Scrollable { final String HELIX = "Helix"; @@ -70,7 +65,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, public BufferedImage image; - public BufferedImage fadedImage; + public volatile BufferedImage fadedImage; Graphics2D gg; @@ -100,9 +95,11 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, public final AnnotationRenderer renderer; + private MouseWheelListener[] _mwl; + /** * Creates a new AnnotationPanel object. - * + * * @param ap * DOCUMENT ME! */ @@ -121,6 +118,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, addMouseMotionListener(this); ap.annotationScroller.getVerticalScrollBar() .addAdjustmentListener(this); + // save any wheel listeners on the scroller, so we can propagate scroll events to them. + _mwl = ap.annotationScroller.getMouseWheelListeners(); + // and then set our own listener to consume all mousewheel events + ap.annotationScroller.addMouseWheelListener(this); renderer = new AnnotationRenderer(); } @@ -130,14 +131,78 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, renderer = new AnnotationRenderer(); } - /** - * DOCUMENT ME! - * - * @param evt - * DOCUMENT ME! + @Override + public void mouseWheelMoved(MouseWheelEvent e) + { + if (e.isShiftDown()) + { + e.consume(); + if (e.getWheelRotation() > 0) + { + ap.scrollRight(true); + } + else + { + ap.scrollRight(false); + } + } + else + { + // TODO: find the correct way to let the event bubble up to ap.annotationScroller + for (MouseWheelListener mwl : _mwl) + { + if (mwl != null) + { + mwl.mouseWheelMoved(e); + } + if (e.isConsumed()) + { + break; + } + } + } + } + + @Override + public Dimension getPreferredScrollableViewportSize() + { + return getPreferredSize(); + } + + @Override + public int getScrollableBlockIncrement(Rectangle visibleRect, + int orientation, int direction) + { + return 30; + } + + @Override + public boolean getScrollableTracksViewportHeight() + { + return false; + } + + @Override + public boolean getScrollableTracksViewportWidth() + { + return true; + } + + @Override + public int getScrollableUnitIncrement(Rectangle visibleRect, + int orientation, int direction) + { + return 30; + } + + /* + * (non-Javadoc) + * @see java.awt.event.AdjustmentListener#adjustmentValueChanged(java.awt.event.AdjustmentEvent) */ + @Override public void adjustmentValueChanged(AdjustmentEvent evt) { + // update annotation label display ap.alabels.setScrollOffset(-evt.getValue()); } @@ -145,11 +210,11 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, * Calculates the height of the annotation displayed in the annotation panel. * Callers should normally call the ap.adjustAnnotationHeight method to ensure * all annotation associated components are updated correctly. - * + * */ public int adjustPanelHeight() { - int height = calcPanelHeight(); + int height = av.calcPanelHeight(); this.setPreferredSize(new Dimension(1, height)); if (ap != null) { @@ -161,73 +226,15 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, } /** - * calculate the height for visible annotation, revalidating bounds where - * necessary ABSTRACT GUI METHOD - * - * @return total height of annotation - */ - public int calcPanelHeight() - { - // setHeight of panels - AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation(); - int height = 0; - - if (aa != null) - { - for (int i = 0; i < aa.length; i++) - { - if (aa[i] == null) - { - System.err.println("Null annotation row: ignoring."); - continue; - } - if (!aa[i].visible) - { - continue; - } - - aa[i].height = 0; - - if (aa[i].hasText) - { - aa[i].height += av.charHeight; - } - - if (aa[i].hasIcons) - { - aa[i].height += 16; - } - - if (aa[i].graph > 0) - { - aa[i].height += aa[i].graphHeight; - } - - if (aa[i].height == 0) - { - aa[i].height = 20; - } - - height += aa[i].height; - } - } - if (height == 0) - { - // set minimum - height = 20; - } - return height; - } - - /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void actionPerformed(ActionEvent evt) { - AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation(); + AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); if (aa == null) { return; @@ -269,7 +276,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, { int index = av.getColumnSelection().columnAt(i); - if (!av.colSel.isVisible(index)) + if (!av.getColumnSelection().isVisible(index)) continue; if (anot[index] == null) @@ -294,7 +301,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, { int index = av.getColumnSelection().columnAt(i); - if (!av.colSel.isVisible(index)) + if (!av.getColumnSelection().isVisible(index)) continue; if (anot[index] == null) @@ -350,7 +357,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, { int index = av.getColumnSelection().columnAt(i); - if (!av.colSel.isVisible(index)) + if (!av.getColumnSelection().isVisible(index)) continue; if (anot[index] == null) @@ -362,8 +369,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, anot[index].displayCharacter = label; } } + aa[activeRow].validateRangeAndDisplay(); adjustPanelHeight(); + ap.alignmentChanged(); repaint(); return; @@ -374,11 +383,13 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, { String collatedInput = ""; String last = ""; + ColumnSelection viscols=av.getColumnSelection(); + // TODO: refactor and save av.getColumnSelection for efficiency for (int i = 0; i < columnSelection.size(); i++) { int index = columnSelection.columnAt(i); // always check for current display state - just in case - if (!av.colSel.isVisible(index)) + if (!viscols.isVisible(index)) continue; String tlabel = null; if (anot[index] != null) @@ -415,14 +426,15 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void mousePressed(MouseEvent evt) { - AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation(); + AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); if (aa == null) { return; @@ -467,7 +479,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /* * Just display the needed structure options */ - if (av.alignment.isNucleotide() == true) + if (av.getAlignment().isNucleotide() == true) { item = new JMenuItem(STEM); item.addActionListener(this); @@ -507,10 +519,11 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void mouseReleased(MouseEvent evt) { graphStretch = -1; @@ -521,10 +534,11 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void mouseEntered(MouseEvent evt) { ap.scalePanel.mouseEntered(evt); @@ -532,10 +546,11 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void mouseExited(MouseEvent evt) { ap.scalePanel.mouseExited(evt); @@ -543,19 +558,20 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void mouseDragged(MouseEvent evt) { if (graphStretch > -1) { - av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight += graphStretchY + av.getAlignment().getAlignmentAnnotation()[graphStretch].graphHeight += graphStretchY - evt.getY(); - if (av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight < 0) + if (av.getAlignment().getAlignmentAnnotation()[graphStretch].graphHeight < 0) { - av.alignment.getAlignmentAnnotation()[graphStretch].graphHeight = 0; + av.getAlignment().getAlignmentAnnotation()[graphStretch].graphHeight = 0; } graphStretchY = evt.getY(); adjustPanelHeight(); @@ -569,13 +585,14 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void mouseMoved(MouseEvent evt) { - AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation(); + AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); if (aa == null) { @@ -609,13 +626,13 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, int res = (evt.getX() / av.getCharWidth()) + av.getStartRes(); - if (av.hasHiddenColumns) + if (av.hasHiddenColumns()) { res = av.getColumnSelection().adjustForHiddenColumns(res); } if (row > -1 && aa[row].annotations != null - && res < (int) aa[row].annotations.length) + && res < aa[row].annotations.length) { if (aa[row].graphGroup > -1) { @@ -668,15 +685,16 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, /** * DOCUMENT ME! - * + * * @param evt * DOCUMENT ME! */ + @Override public void mouseClicked(MouseEvent evt) { if (activeRow != -1) { - AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation(); + AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); AlignmentAnnotation anot = aa[activeRow]; if (anot.description.equals("secondary structure")) @@ -707,13 +725,14 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, } } - + private volatile boolean imageFresh=false; /** * DOCUMENT ME! - * + * * @param g * DOCUMENT ME! */ + @Override public void paintComponent(Graphics g) { g.setColor(Color.white); @@ -749,15 +768,17 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, fm = gg.getFontMetrics(); gg.setColor(Color.white); gg.fillRect(0, 0, imgWidth, image.getHeight()); + imageFresh=true; } drawComponent(gg, av.startRes, av.endRes + 1); + imageFresh=false; g.drawImage(image, 0, 0, this); } /** * non-Thread safe repaint - * + * * @param horizontal * repaint with horizontal shift in alignment */ @@ -765,9 +786,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, { if ((horizontal == 0) || gg == null - || av.alignment.getAlignmentAnnotation() == null - || av.alignment.getAlignmentAnnotation().length < 1 - || av.updatingConsensus || av.updatingConservation) + || av.getAlignment().getAlignmentAnnotation() == null + || av.getAlignment().getAlignmentAnnotation().length < 1 + || av.isCalcInProgress()) { repaint(); return; @@ -798,10 +819,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, repaint(); } - + private volatile boolean lastImageGood=false; /** * DOCUMENT ME! - * + * * @param g * DOCUMENT ME! * @param startRes @@ -811,18 +832,21 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, */ public void drawComponent(Graphics g, int startRes, int endRes) { - if (av.updatingConsensus || av.updatingConservation) + BufferedImage oldFaded=fadedImage; + if (av.isCalcInProgress()) { if (image == null) { + lastImageGood=false; return; } // We'll keep a record of the old image, // and draw a faded image until the calculation // has completed - if (fadedImage == null || fadedImage.getWidth() != imgWidth - || fadedImage.getHeight() != image.getHeight()) + if (lastImageGood && (fadedImage == null || fadedImage.getWidth() != imgWidth + || fadedImage.getHeight() != image.getHeight())) { +// System.err.println("redraw faded image ("+(fadedImage==null ? "null image" : "") + " lastGood="+lastImageGood+")"); fadedImage = new BufferedImage(imgWidth, image.getHeight(), BufferedImage.TYPE_INT_RGB); @@ -836,10 +860,16 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, fadedG.drawImage(image, 0, 0, this); } + // make sure we don't overwrite the last good faded image until all calculations have finished + lastImageGood=false; } else { + if (fadedImage!=null) + { + oldFaded=fadedImage; + } fadedImage = null; } @@ -852,8 +882,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, fm = g.getFontMetrics(); } - if ((av.alignment.getAlignmentAnnotation() == null) - || (av.alignment.getAlignmentAnnotation().length < 1)) + if ((av.getAlignment().getAlignmentAnnotation() == null) + || (av.getAlignment().getAlignmentAnnotation().length < 1)) { g.setColor(Color.white); g.fillRect(0, 0, getWidth(), getHeight()); @@ -865,7 +895,11 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, return; } - renderer.drawComponent(this, av, g, activeRow, startRes, endRes); + lastImageGood = renderer.drawComponent(this, av, g, activeRow, startRes, endRes); + if (!lastImageGood && fadedImage==null) + { + fadedImage=oldFaded; + } } @Override