import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenColumns;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.util.Platform;
import java.awt.Color;
+import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.regex.Pattern;
+import java.util.Iterator;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
public class AnnotationLabels extends JPanel
implements MouseListener, MouseMotionListener, ActionListener
{
- // width in pixels within which height adjuster arrows are shown and active
+ private static final String HTML_END_TAG = "</html>";
+
+ private static final String HTML_START_TAG = "<html>";
+
+ /**
+ * width in pixels within which height adjuster arrows are shown and active
+ */
private static final int HEIGHT_ADJUSTER_WIDTH = 50;
- private static final Pattern LEFT_ANGLE_BRACKET_PATTERN = Pattern
- .compile("<");
+ /**
+ * height in pixels for allowing height adjuster to be active
+ */
+ private static int HEIGHT_ADJUSTER_HEIGHT = 10;
private static final Font font = new Font("Arial", Font.PLAIN, 11);
private static final String COPYCONS_SEQ = MessageManager
.getString("label.copy_consensus_sequence");
- private static Image adjusterImage;
-
- private static int adjusterImageHeight;
-
private final boolean debugRedraw = false;
private AlignmentPanel ap;
av = ap.av;
ToolTipManager.sharedInstance().registerComponent(this);
- if (adjusterImage == null)
- {
- loadAdjusterImage();
- }
-
addMouseListener(this);
addMouseMotionListener(this);
addMouseWheelListener(ap.getAnnotationPanel());
}
/**
- * Loads the gif for the panel height adjustment
- */
- protected void loadAdjusterImage()
- {
- java.net.URL url = getClass().getResource("/images/idwidth.gif");
- Image temp = null;
-
- if (url != null)
- {
- temp = Toolkit.getDefaultToolkit().createImage(url);
- }
-
- try
- {
- MediaTracker mt = new MediaTracker(this);
- mt.addImage(temp, 0);
- mt.waitForID(0);
- } catch (Exception ex)
- {
- }
-
- BufferedImage bi = new BufferedImage(temp.getHeight(this),
- temp.getWidth(this), BufferedImage.TYPE_INT_RGB);
- Graphics2D g = (Graphics2D) bi.getGraphics();
- g.rotate(Math.toRadians(90));
- g.drawImage(temp, 0, -bi.getWidth(this), this);
- adjusterImage = bi;
- adjusterImageHeight = bi.getHeight();
- }
-
- /**
* DOCUMENT ME!
*
* @param y
}
else if (evt.getActionCommand().equals(OUTPUT_TEXT))
{
- new AnnotationExporter().exportAnnotations(ap,
- new AlignmentAnnotation[]
- { aa[selectedRow] });
+ new AnnotationExporter(ap).exportAnnotation(aa[selectedRow]);
}
else if (evt.getActionCommand().equals(COPYCONS_SEQ))
{
AlignmentAnnotation aa = ap.av.getAlignment()
.getAlignmentAnnotation()[selectedRow];
- StringBuffer desc = new StringBuffer();
- if (aa.description != null
- && !aa.description.equals("New description"))
- {
- // TODO: we could refactor and merge this code with the code in
- // jalview.gui.SeqPanel.mouseMoved(..) that formats sequence feature
- // tooltips
- desc.append(aa.getDescription(true).trim());
- // check to see if the description is an html fragment.
- if (desc.length() < 6 || (desc.substring(0, 6).toLowerCase()
- .indexOf("<html>") < 0))
- {
- // clean the description ready for embedding in html
- desc = new StringBuffer(LEFT_ANGLE_BRACKET_PATTERN.matcher(desc)
- .replaceAll("<"));
- desc.insert(0, "<html>");
- }
- else
- {
- // remove terminating html if any
- int i = desc.substring(desc.length() - 7).toLowerCase()
- .lastIndexOf("</html>");
- if (i > -1)
- {
- desc.setLength(desc.length() - 7 + i);
- }
- }
- if (aa.hasScore())
- {
- desc.append("<br/>");
- }
- // if (aa.hasProperties())
- // {
- // desc.append("<table>");
- // for (String prop : aa.getProperties())
- // {
- // desc.append("<tr><td>" + prop + "</td><td>"
- // + aa.getProperty(prop) + "</td><tr>");
- // }
- // desc.append("</table>");
- // }
- }
- else
+ String desc = getTooltip(aa);
+ this.setToolTipText(desc);
+ }
+ }
+
+ /**
+ * Answers a tooltip, formatted as html, containing the annotation description
+ * (prefixed by associated sequence id if applicable), and the annotation
+ * (non-positional) score if it has one. Answers null if neither description
+ * nor score is found.
+ *
+ * @param aa
+ * @return
+ */
+ static String getTooltip(AlignmentAnnotation aa)
+ {
+ if (aa == null)
+ {
+ return null;
+ }
+ StringBuilder tooltip = new StringBuilder();
+ if (aa.description != null && !aa.description.equals("New description"))
+ {
+ // TODO: we could refactor and merge this code with the code in
+ // jalview.gui.SeqPanel.mouseMoved(..) that formats sequence feature
+ // tooltips
+ String desc = aa.getDescription(true).trim();
+ if (!desc.toLowerCase().startsWith(HTML_START_TAG))
{
- // begin the tooltip's html fragment
- desc.append("<html>");
- if (aa.hasScore())
- {
- // TODO: limit precision of score to avoid noise from imprecise
- // doubles
- // (64.7 becomes 64.7+/some tiny value).
- desc.append(" Score: " + aa.score);
- }
+ tooltip.append(HTML_START_TAG);
+ desc = desc.replace("<", "<");
}
- if (desc.length() > 6)
+ else if (desc.toLowerCase().endsWith(HTML_END_TAG))
{
- desc.append("</html>");
- this.setToolTipText(desc.toString());
+ desc = desc.substring(0, desc.length() - HTML_END_TAG.length());
}
- else
+ tooltip.append(desc);
+ }
+ else
+ {
+ // begin the tooltip's html fragment
+ tooltip.append(HTML_START_TAG);
+ }
+ if (aa.hasScore())
+ {
+ if (tooltip.length() > HTML_START_TAG.length())
{
- this.setToolTipText(null);
+ tooltip.append("<br/>");
}
+ // TODO: limit precision of score to avoid noise from imprecise
+ // doubles
+ // (64.7 becomes 64.7+/some tiny value).
+ tooltip.append(" Score: ").append(String.valueOf(aa.score));
+ }
+
+ if (tooltip.length() > HTML_START_TAG.length())
+ {
+ return tooltip.append(HTML_END_TAG).toString();
}
+
+ /*
+ * nothing in the tooltip (except "<html>")
+ */
+ return null;
}
/**
protected void showOrHideAdjuster(MouseEvent evt)
{
boolean was = resizePanel;
- resizePanel = evt.getY() < adjusterImageHeight && evt.getX() < HEIGHT_ADJUSTER_WIDTH;
+ resizePanel = evt.getY() < HEIGHT_ADJUSTER_HEIGHT && evt.getX() < HEIGHT_ADJUSTER_WIDTH;
+
if (resizePanel != was)
{
+ setCursor(Cursor.getPredefinedCursor(
+ resizePanel ? Cursor.S_RESIZE_CURSOR
+ : Cursor.DEFAULT_CURSOR));
repaint();
}
}
Alignment ds = new Alignment(dseqs);
if (av.hasHiddenColumns())
{
- omitHidden = av.getAlignment().getHiddenColumns()
- .getVisibleSequenceStrings(0, sq.getLength(), seqs);
+ Iterator<int[]> it = av.getAlignment().getHiddenColumns()
+ .getVisContigsIterator(0, sq.getLength(), false);
+ omitHidden = new String[] { sq.getSequenceStringFromIterator(it) };
}
int[] alignmentStartEnd = new int[] { 0, ds.getWidth() - 1 };
Toolkit.getDefaultToolkit().getSystemClipboard()
.setContents(new StringSelection(output), Desktop.instance);
- ArrayList<int[]> hiddenColumns = null;
+ HiddenColumns hiddenColumns = null;
if (av.hasHiddenColumns())
{
- hiddenColumns = av.getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy();
+ hiddenColumns = new HiddenColumns(
+ av.getAlignment().getHiddenColumns());
}
Desktop.jalviewClipboard = new Object[] { seqs, ds, // what is the dataset
}
}
- if (resizePanel)
- {
- g.drawImage(adjusterImage, 2, 0 - getScrollOffset(), this);
- }
- else if (dragEvent != null && aa != null)
+ if (!resizePanel && dragEvent != null && aa != null)
{
g.setColor(Color.lightGray);
g.drawString(aa[selectedRow].label, dragEvent.getX(),