diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java
index 663f649da395c4abb21f67ef1120f00ed13b4e9a..c83f249463868333c40f6f7f67d58236b74f77e6 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamView.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamView.java
@@ -28,7 +28,6 @@ import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
-import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
@@ -42,8 +41,6 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
@@ -78,7 +75,6 @@ import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
-import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.Border;
@@ -105,7 +101,6 @@ import uk.ac.sanger.artemis.components.EntryFileDialog;
import uk.ac.sanger.artemis.components.FeatureDisplay;
import uk.ac.sanger.artemis.components.MessageDialog;
import uk.ac.sanger.artemis.components.SwingWorker;
-import uk.ac.sanger.artemis.components.Utilities;
import uk.ac.sanger.artemis.editor.MultiLineToolTipUI;
import uk.ac.sanger.artemis.io.EntryInformation;
import uk.ac.sanger.artemis.io.Range;
@@ -151,14 +146,12 @@ public class BamView extends JPanel
private int laststart;
private int lastend;
private int maxUnitIncrement = 8;
- private Cursor cbusy = new Cursor(Cursor.WAIT_CURSOR);
- private Cursor cdone = new Cursor(Cursor.DEFAULT_CURSOR);
private boolean asynchronous = true;
private boolean showBaseAlignment = false;
private JCheckBoxMenuItem checkBoxStackView = new JCheckBoxMenuItem("Stack View");
private JCheckBoxMenuItem baseQualityColour = new JCheckBoxMenuItem("Colour by Base Quality");;
-
+ private JCheckBoxMenuItem markInsertions = new JCheckBoxMenuItem("Mark Insertions");
private AlphaComposite translucent =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f);
@@ -166,10 +159,12 @@ public class BamView extends JPanel
private Color lightGrey = new Color(200, 200, 200);
private Color darkGreen = new Color(0, 150, 0);
private Color darkOrange = new Color(255,140,0);
+ private Color deepPink = new Color(139,10,80);
private Point lastMousePoint = null;
private SAMRecord mouseOverSAMRecord = null;
private SAMRecord highlightSAMRecord = null;
+ private String mouseOverInsertion;
// record of where a mouse drag starts
private int dragStart = -1;
@@ -181,7 +176,7 @@ public class BamView extends JPanel
private JPopupMenu popup;
private PopupMessageFrame popFrame = new PopupMessageFrame();
- private PopupMessageFrame waitingFrame;
+ private PopupMessageFrame waitingFrame = new PopupMessageFrame("waiting...");
public static org.apache.log4j.Logger logger4j =
org.apache.log4j.Logger.getLogger(BamView.class);
@@ -218,13 +213,7 @@ public class BamView extends JPanel
"This requires Java 1.6 or higher.",
"Check Java Version", JOptionPane.WARNING_MESSAGE);
}
-
- // set font size
- //setFont(getFont().deriveFont(12.f));
- //Options.getOptions().getFontUIResource();
- //final javax.swing.plaf.FontUIResource font_ui_resource =
- // new javax.swing.plaf.FontUIResource(getFont());
final javax.swing.plaf.FontUIResource font_ui_resource =
Options.getOptions().getFontUIResource();
@@ -240,7 +229,7 @@ public class BamView extends JPanel
setFont(Options.getOptions().getFont());
FontMetrics fm = getFontMetrics(getFont());
ALIGNMENT_PIX_PER_BASE = fm.charWidth('M');
- BASE_HEIGHT = fm.getHeight();
+ BASE_HEIGHT = fm.getMaxAscent();
selection = new Selection(null);
MultiLineToolTipUI.initialize();
@@ -249,12 +238,17 @@ public class BamView extends JPanel
public String getToolTipText()
{
- return ( mouseOverSAMRecord != null ?
+ String msg = (mouseOverSAMRecord != null ?
mouseOverSAMRecord.getReadName() + "\n" +
mouseOverSAMRecord.getAlignmentStart() + ".." +
mouseOverSAMRecord.getAlignmentEnd() + "\nisize=" +
mouseOverSAMRecord.getInferredInsertSize() + "\nrname=" +
- mouseOverSAMRecord.getReferenceName(): null);
+ mouseOverSAMRecord.getReferenceName() : null);
+
+ if(msg != null && mouseOverInsertion != null)
+ msg = msg + "\nInsertion at:" +mouseOverInsertion;
+
+ return msg;
}
/*
@@ -445,7 +439,7 @@ public class BamView extends JPanel
(memory.getHeapMemoryUsage().getMax()/1000000.f)+" Mb).\n"+
"Zoom in or consider increasing the\nmemory for this application.",
mainPanel.getLocationOnScreen().y,
- 20000);
+ 15000);
break;
}
}
@@ -531,7 +525,9 @@ public class BamView extends JPanel
if(laststart != start ||
lastend != end)
{
- setCursor(cbusy);
+ if(!waitingFrame.isVisible())
+ waitingFrame.showWaiting("loading...", mainPanel);
+
synchronized (this)
{
try
@@ -559,8 +555,6 @@ public class BamView extends JPanel
{
Collections.sort(readsInView, new SAMRecordComparator());
}
-
- setCursor(cdone);
}
catch (OutOfMemoryError ome)
{
@@ -596,7 +590,8 @@ public class BamView extends JPanel
coveragePanel.repaint();
}
}
-
+
+ waitingFrame.setVisible(false);
if(changeToStackView)
{
popFrame.show("Stack View",
@@ -606,7 +601,7 @@ public class BamView extends JPanel
"and the maximum\nmemory limit is "+
(memory.getHeapMemoryUsage().getMax()/1000000.f)+" Mb.",
mainPanel.getLocationOnScreen().y,
- 20000);
+ 15000);
}
}
@@ -679,6 +674,7 @@ public class BamView extends JPanel
else
drawSelectionRange(g2, ALIGNMENT_PIX_PER_BASE, start, end);
+ g2.setStroke(new BasicStroke (2.f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND));
boolean drawn[] = new boolean[readsInView.size()];
for(int i=0; i<readsInView.size(); i++)
@@ -753,38 +749,30 @@ public class BamView extends JPanel
Color col = g2.getColor();
int xpos;
- int len = 0;
+ int len = 0;
+ int refPos = 0;
String readSeq = samRecord.getReadString();
int offset = getSequenceOffset(samRecord.getReferenceName());
-
+
byte[] phredQuality = null;
-
if(baseQualityColour.isSelected())
phredQuality = samRecord.getBaseQualities();
+ Hashtable<Integer, String> insertions = null;
List<AlignmentBlock> blocks = samRecord.getAlignmentBlocks();
for(int i=0; i<blocks.size(); i++)
{
AlignmentBlock block = blocks.get(i);
+ int blockStart = block.getReadStart();
len += block.getLength();
for(int j=0; j<block.getLength(); j++)
{
- int readPos = block.getReadStart()-1+j;
+ int readPos = blockStart-1+j;
xpos = block.getReferenceStart() - 1 + j + offset;
- int refPos = xpos - refSeqStart + 1;
+ refPos = xpos - refSeqStart + 1;
if(phredQuality != null)
- {
- byte baseQuality = phredQuality[readPos];
- if (baseQuality < 10)
- g2.setColor(Color.blue);
- else if (baseQuality < 20)
- g2.setColor(darkGreen);
- else if (baseQuality < 30)
- g2.setColor(darkOrange);
- else
- g2.setColor(Color.black);
- }
+ setColourByBaseQuality(g2, phredQuality[readPos]);
if(isSNPs && refSeq != null && refPos > 0 && refPos < refSeq.length())
{
@@ -793,18 +781,43 @@ public class BamView extends JPanel
else
g2.setColor(col);
}
-
+
g2.drawString(readSeq.substring(readPos, readPos+1),
refPos*ALIGNMENT_PIX_PER_BASE, ypos);
}
+
+ // look for insertions
+ if(markInsertions.isSelected() && i < blocks.size()-1)
+ {
+ int blockEnd = blockStart+block.getLength();
+ int nextBlockStart = blocks.get(i+1).getReadStart();
+ int insertSize = nextBlockStart - blockEnd;
+ if(insertSize > 0)
+ {
+ if(insertions == null)
+ insertions = new Hashtable<Integer, String>();
+
+ g2.setColor(deepPink);
+
+ int xscreen = refPos*ALIGNMENT_PIX_PER_BASE;
+ insertions.put(xscreen,
+ (samRecord.getAlignmentStart()+len-2)+" "+
+ readSeq.substring(blockEnd-1, nextBlockStart-1));
+ g2.drawLine(xscreen, ypos, xscreen, ypos-BASE_HEIGHT);
+
+ // mark on reference sequence as well
+ if(bases != null)
+ g2.drawLine(xscreen, 11, xscreen, 11-BASE_HEIGHT);
+ g2.setColor(col);
+ }
+ }
}
-
-
+
// highlight
if(highlightSAMRecord != null &&
highlightSAMRecord.getReadName().equals(samRecord.getReadName()))
{
- int refPos = blocks.get(0).getReferenceStart()+offset-refSeqStart;
+ refPos = blocks.get(0).getReferenceStart()+offset-refSeqStart;
int xstart = refPos*ALIGNMENT_PIX_PER_BASE;
int width = len*ALIGNMENT_PIX_PER_BASE;
g2.setColor(Color.red);
@@ -813,7 +826,7 @@ public class BamView extends JPanel
if(lastMousePoint != null)
{
- int refPos = blocks.get(0).getReferenceStart()+offset-refSeqStart;
+ refPos = blocks.get(0).getReferenceStart()+offset-refSeqStart;
int xstart = refPos*ALIGNMENT_PIX_PER_BASE;
int xend = (refPos+len)*ALIGNMENT_PIX_PER_BASE;
@@ -821,11 +834,31 @@ public class BamView extends JPanel
if(lastMousePoint.getX() > xstart &&
lastMousePoint.getX() < xend)
{
- mouseOverSAMRecord = samRecord;
+ mouseOverSAMRecord = samRecord;
+
+ if(insertions != null)
+ mouseOverInsertion = insertions.get((int)lastMousePoint.getX());
}
}
}
+ /**
+ * Colour bases on their mapping quality.
+ * @param g2
+ * @param baseQuality
+ */
+ private void setColourByBaseQuality(Graphics2D g2, byte baseQuality)
+ {
+ if (baseQuality < 10)
+ g2.setColor(Color.blue);
+ else if (baseQuality < 20)
+ g2.setColor(darkGreen);
+ else if (baseQuality < 30)
+ g2.setColor(darkOrange);
+ else
+ g2.setColor(Color.black);
+ }
+
/**
* Draw zoomed-out view.
* @param g2
@@ -1733,11 +1766,6 @@ public class BamView extends JPanel
addMouseListener(new PopupListener());
setFocusable(true);
requestFocusInWindow();
- addFocusListener(new FocusListener()
- {
- public void focusGained(FocusEvent fe){}
- public void focusLost(FocusEvent fe){}
- });
}
@@ -1750,6 +1778,8 @@ public class BamView extends JPanel
final JCheckBoxMenuItem checkIsizeStackView = new JCheckBoxMenuItem("Inferred Size View", true);
checkBoxStackView.setFont(checkIsizeStackView.getFont());
baseQualityColour.setFont(checkIsizeStackView.getFont());
+ markInsertions.setFont(checkIsizeStackView.getFont());
+
group.add(checkBoxStackView);
group.add(checkBoxPairedStackView);
group.add(checkBoxStrandStackView);
@@ -1882,6 +1912,15 @@ public class BamView extends JPanel
}
});
showMenu.add(baseQualityColour);
+
+ markInsertions.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ repaint();
+ }
+ });
+ showMenu.add(markInsertions);
showMenu.add(new JSeparator());
JCheckBoxMenuItem checkBoxCoverage = new JCheckBoxMenuItem("Coverage");
@@ -1983,6 +2022,7 @@ public class BamView extends JPanel
jspView.setColumnHeaderView(ruler);
showBaseAlignment = true;
baseQualityColour.setEnabled(true);
+ markInsertions.setEnabled(true);
}
else if(jspView != null)
{
@@ -1993,6 +2033,7 @@ public class BamView extends JPanel
jspView.getVerticalScrollBar().getMaximum());
showBaseAlignment = false;
baseQualityColour.setEnabled(false);
+ markInsertions.setEnabled(false);
}
if(scrollBar != null)
@@ -2038,12 +2079,14 @@ public class BamView extends JPanel
jspView.setColumnHeaderView(ruler);
showBaseAlignment = true;
baseQualityColour.setEnabled(true);
+ markInsertions.setEnabled(true);
}
else if(jspView != null)
{
jspView.setColumnHeaderView(null);
showBaseAlignment = false;
baseQualityColour.setEnabled(false);
+ markInsertions.setEnabled(false);
}
Dimension d = new Dimension();
@@ -2233,15 +2276,12 @@ public class BamView extends JPanel
if(event.getStart() != ((FeatureDisplay)event.getSource()).getForwardBaseAtLeftEdge())
{
- if(waitingFrame == null)
- waitingFrame = new PopupMessageFrame("waiting...");
- waitingFrame.showWaiting();
+ waitingFrame.showWaiting("waiting...", mainPanel);
return null;
}
displayAdjustmentWork(event);
- if(waitingFrame != null)
- waitingFrame.setVisible(false);
+ waitingFrame.setVisible(false);
return null;
}
};
@@ -2325,6 +2365,10 @@ public class BamView extends JPanel
JMenuItem gotoMateMenuItem;
public void mouseClicked(MouseEvent e)
{
+ if(e.isPopupTrigger() ||
+ e.getButton() == MouseEvent.BUTTON3)
+ return;
+
BamView.this.requestFocus();
if(e.getClickCount() > 1)
@@ -2400,80 +2444,6 @@ public class BamView extends JPanel
SAMRecord sam2;
}
- class PopupMessageFrame extends JFrame
- {
- private static final long serialVersionUID = 1L;
- private JTextArea textArea = new JTextArea();
- PopupMessageFrame()
- {
- super();
- getRootPane().putClientProperty("Window.alpha", new Float(0.8f));
- textArea.setWrapStyleWord(true);
- textArea.setEditable(false);
- setUndecorated(true);
- getContentPane().add(textArea);
- }
-
- PopupMessageFrame(String msg)
- {
- this();
- textArea.setFont(textArea.getFont().deriveFont(14.f));
- textArea.setText(msg);
- setTitle(msg);
- pack();
- }
-
- protected void showWaiting()
- {
- Point p = mainPanel.getLocationOnScreen();
- p.x += (mainPanel.getWidth() - PopupMessageFrame.this.getWidth())/2;
- p.y += mainPanel.getHeight()/2;
- setLocation(p);
- setVisible(true);
- requestFocus();
- }
-
- protected void show(String title, String msg, int ypos, long aliveTime)
- {
- setTitle(title);
- textArea.setText(msg);
- pack();
- //PopupMessageFrame.this.setLocationRelativeTo(BamView.this);
- Utilities.centreJustifyFrame(this, Math.abs(ypos));
- setVisible(true);
- requestFocus();
-
- HideFrameThread thread = new HideFrameThread(this, aliveTime);
- thread.start();
- }
- }
-
- class HideFrameThread extends Thread
- {
- private long aliveTime;
- private JFrame f;
-
- public HideFrameThread(JFrame f, long aliveTime)
- {
- this.f = f;
- this.aliveTime = aliveTime;
- }
-
- public void run()
- {
- try
- {
- Thread.sleep(aliveTime);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- f.setVisible(false);
- }
- }
-
-
public static void main(String[] args)
{
String bam = args[0];
diff --git a/uk/ac/sanger/artemis/components/alignment/PopupMessageFrame.java b/uk/ac/sanger/artemis/components/alignment/PopupMessageFrame.java
new file mode 100644
index 0000000000000000000000000000000000000000..36725762b6fc4cfb2c42f1525d64ff8980ba9758
--- /dev/null
+++ b/uk/ac/sanger/artemis/components/alignment/PopupMessageFrame.java
@@ -0,0 +1,109 @@
+/* PopupMessageFrame
+ *
+ * created: 2009
+ *
+ * This file is part of Artemis
+ *
+ * Copyright(C) 2009 Genome Research Limited
+ *
+ * This program 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 2
+ * of the License, or(at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+package uk.ac.sanger.artemis.components.alignment;
+
+import java.awt.Point;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+
+import uk.ac.sanger.artemis.components.SwingWorker;
+import uk.ac.sanger.artemis.components.Utilities;
+
+/**
+ * Create undecorated popup frames.
+ */
+class PopupMessageFrame extends JFrame
+{
+ private static final long serialVersionUID = 1L;
+ private JTextArea textArea = new JTextArea();
+
+ PopupMessageFrame()
+ {
+ super();
+ getRootPane().putClientProperty("Window.alpha", new Float(0.8f));
+ textArea.setWrapStyleWord(true);
+ textArea.setEditable(false);
+ setUndecorated(true);
+ getContentPane().add(textArea);
+ }
+
+ PopupMessageFrame(String msg)
+ {
+ this();
+ textArea.setFont(textArea.getFont().deriveFont(14.f));
+ textArea.setText(msg);
+ setTitle(msg);
+ pack();
+ }
+
+ protected void showWaiting(final String msg, final JPanel mainPanel)
+ {
+ textArea.setText(msg);
+ pack();
+ Point p = mainPanel.getLocationOnScreen();
+ p.x += (mainPanel.getWidth() - PopupMessageFrame.this.getWidth()) / 2;
+ p.y += mainPanel.getHeight() / 2;
+ setLocation(p);
+ SwingWorker worker = new SwingWorker()
+ {
+ public Object construct()
+ {
+ setVisible(true);
+ return null;
+ }
+ };
+ worker.start();
+ }
+
+ protected void show(final String title, final String msg, final int ypos,
+ final long aliveTime)
+ {
+ SwingWorker worker = new SwingWorker()
+ {
+ public Object construct()
+ {
+ setTitle(title);
+ textArea.setText(msg);
+ pack();
+ Utilities.centreJustifyFrame(PopupMessageFrame.this, Math.abs(ypos));
+ setVisible(true);
+ requestFocus();
+
+ try
+ {
+ Thread.sleep(aliveTime);
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ setVisible(false);
+ return null;
+ }
+ };
+ worker.start();
+ }
+}