Skip to content
Snippets Groups Projects
BamView.java 136 KiB
Newer Older
tcarver's avatar
tcarver committed
    final JMenuItem readGroupsMenu = new JMenuItem("Read Groups ...");
    readGroupsMenu.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent arg0)
      {
tcarver's avatar
tcarver committed
        ReadGroupsFrame f = getReadGroupFrame();
tcarver's avatar
tcarver committed
        f.setVisible(true);
      }
    });
    menu.add(readGroupsMenu);
    
tjc's avatar
tjc committed
    JMenuItem filter = new JMenuItem("Filter Reads ...");
    menu.add(filter);
    filter.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
tjc's avatar
tjc committed
        if(filterFrame == null)
          filterFrame = new SAMRecordFilter(BamView.this);
        else
          filterFrame.setVisible(true);
    JMenuItem maxReadCoverage = new JMenuItem("Read Coverage Threshold ...");
    menu.add(maxReadCoverage);
    maxReadCoverage.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        final TextFieldInt maxRead = new TextFieldInt();
        maxRead.setValue(MAX_COVERAGE);
        int status = JOptionPane.showConfirmDialog(null, maxRead, 
            "Read Coverage Threshold", JOptionPane.OK_CANCEL_OPTION);
        if(status == JOptionPane.OK_OPTION &&
           maxRead.getValue() != MAX_COVERAGE)
        {
          MAX_COVERAGE = maxRead.getValue();
          if(MAX_COVERAGE < 1)
            MAX_COVERAGE = Integer.MAX_VALUE;
          laststart = -1;
          repaint();
        }
      } 
    });
    
tcarver's avatar
tcarver committed
    JMenuItem readList = new JMenuItem("List Reads ...");
tcarver's avatar
tcarver committed
    menu.add(readList);
    readList.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
tcarver's avatar
tcarver committed
        new SAMRecordList(BamView.this);
tcarver's avatar
tcarver committed
      }
tcarver's avatar
tcarver committed
    });
tjc's avatar
tjc committed
    final JMenuItem bamSplitter = new JMenuItem("Clone window");
    bamSplitter.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        openBamView(new Vector<String>(bamList));
tjc's avatar
tjc committed
      } 
    });
    menu.add(new JSeparator());
    menu.add(bamSplitter);

    //
    JMenu coverageMenu = new JMenu("Coverage Options");
    coverageView.init(this, 0.f, 0, 0);
    coverageView.createMenus(coverageMenu);
    viewMenu.add(new JSeparator());
    viewMenu.add(coverageMenu);
tcarver's avatar
tcarver committed
  private ReadGroupsFrame getReadGroupFrame()
tcarver's avatar
tcarver committed
  {
    if(readGrpFrame == null)
tcarver's avatar
tcarver committed
      readGrpFrame = new ReadGroupsFrame(readGroups, BamView.this);
tcarver's avatar
tcarver committed
    return readGrpFrame;
  }
  
tjc's avatar
tjc committed
  private JComponent bamTopPanel(final JFrame frame)
  {
    final JComponent topPanel;
tjc's avatar
tjc committed
    if(frame == null)
tjc's avatar
tjc committed
    {
      topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
      if(feature_display != null)
        this.selection = feature_display.getSelection(); 
tjc's avatar
tjc committed
    }
    else
    { 
      topPanel = new JMenuBar();
      frame.setJMenuBar((JMenuBar)topPanel);
      
      JMenu fileMenu = new JMenu("File");
      topPanel.add(fileMenu);

      JMenuItem readBam = new JMenuItem("Open new BamView ...");
      fileMenu.add(readBam);
      readBam.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          String[] s = { "NEW-BAMVIEW" };
tjc's avatar
tjc committed
          BamView.main(s);
        } 
      });
      
tcarver's avatar
tcarver committed
      
      JMenuItem saveAs = new JMenuItem("Save As Image File (png/jpeg/svg) ...");
      fileMenu.add(saveAs);
      saveAs.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          PrintBamView.print((JPanel)mainPanel.getParent()); 
        }
      });

      
tjc's avatar
tjc committed
      JMenuItem close = new JMenuItem("Close");
      fileMenu.add(close);
      close.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          BamView.this.setVisible(false);
          Component comp = BamView.this;
          
          while( !(comp instanceof JFrame) )
            comp = comp.getParent();
          ((JFrame)comp).dispose();
        } 
      });
      
      JMenuItem exit = new JMenuItem("Exit");
      fileMenu.add(new JSeparator());
      fileMenu.add(exit);
      exit.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          int status = JOptionPane.showConfirmDialog(BamView.this, 
              "Exit BamView?", "Exit", 
              JOptionPane.OK_CANCEL_OPTION);
          if(status != JOptionPane.OK_OPTION)
            return;
          System.exit(0);
        } 
      });
      
      addKeyListener(new KeyAdapter()
      {
        public void keyPressed(final KeyEvent event)
        {
          switch (event.getKeyCode())
          {
            case KeyEvent.VK_UP:
              setZoomLevel((int) (BamView.this.nbasesInView * 1.1));
              break;
            case KeyEvent.VK_DOWN:
              if (showBaseAlignment)
                break;
              setZoomLevel((int) (BamView.this.nbasesInView * .9));
              break;
            default:
              break;
          }
        }
      });
    }
    
    if(seqNames.size() > 1)
    {
      int len = 0;
      for(int i=0; i<seqNames.size(); i++)
        len += seqLengths.get(seqNames.get(i));
      
      if(feature_display != null &&
         len == feature_display.getSequenceLength())
        concatSequences = true;
      else if(bases != null &&
          len == bases.getLength() )
        concatSequences = true;
    }

    // auto hide top panel
tjc's avatar
tjc committed
    final JCheckBox buttonAutoHide = new JCheckBox("Hide", (frame == null));
tjc's avatar
tjc committed
    buttonAutoHide.setToolTipText("Auto-Hide");
    final MouseMotionListener mouseMotionListener = new MouseMotionListener()
    {
      public void mouseDragged(MouseEvent event)
      {
        handleCanvasMouseDrag(event);
      }
      
      public void mouseMoved(MouseEvent e)
      {
        lastMousePoint = e.getPoint();
tcarver's avatar
tcarver committed
        int thisHgt = HEIGHT-2;
tjc's avatar
tjc committed
        if (thisHgt < 5)
          thisHgt = 15;

        int y = (int) (e.getY() - jspView.getViewport().getViewRect().getY());
        if (y < thisHgt)
          topPanel.setVisible(true);
        else
        {
tcarver's avatar
tcarver committed
          if (buttonAutoHide.isSelected() && topPanel.isVisible())
tcarver's avatar
tcarver committed
            topPanel.setVisible(false); 
        
        // KJP - added these to make selecting work properly.
        mainPanel.repaint();
        mainPanel.revalidate();
tjc's avatar
tjc committed
      }
    };
    addMouseMotionListener(mouseMotionListener);

    
    combo = new SequenceComboBox(seqNames){
      private static final long serialVersionUID = 1L;
      public void update(IndexReferenceEvent event)
tjc's avatar
tjc committed
      {
        laststart = -1;
        if(feature_display != null)
          setZoomLevel(feature_display.getMaxVisibleBases());
        else
          setZoomLevel(BamView.this.nbasesInView);
      }
tjc's avatar
tjc committed
    topPanel.add(combo);

    if(feature_display == null)
    {
      final JTextField baseText = new JTextField(8);
      JButton goTo = new JButton("GoTo:");
      goTo.setToolTipText("Go to base position");
      goTo.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          try
          {
            int basePosition = Integer.parseInt(baseText.getText());
            scrollBar.setValue(basePosition);
          }
          catch (NumberFormatException nfe)
          {
            JOptionPane.showMessageDialog(BamView.this,
                "Expecting a base number!", "Number Format",
                JOptionPane.WARNING_MESSAGE);
          }
        }
      });
      topPanel.add(goTo);
      topPanel.add(baseText);

      JButton zoomIn = new JButton("-");
      zoomIn.setToolTipText("Zoom out (up arrow)");
tjc's avatar
tjc committed
      Insets ins = new Insets(1,1,1,1);
      zoomIn.setMargin(ins);
      zoomIn.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          setZoomLevel((int) (BamView.this.nbasesInView * 1.1));
        }
      });
      topPanel.add(zoomIn);

      JButton zoomOut = new JButton("+");
      zoomOut.setToolTipText("Zoom in (down arrow)");
tjc's avatar
tjc committed
      zoomOut.setMargin(ins);
      zoomOut.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          if (showBaseAlignment)
            return;
          setZoomLevel((int) (BamView.this.nbasesInView * .9));
        }
      });
      topPanel.add(zoomOut);
    }
    
    topPanel.add(buttonAutoHide);
tcarver's avatar
tcarver committed
    
    final JSlider slider = new JSlider(13, 52, (int) (readLnHgt*10));
    slider.addChangeListener(new ChangeListener(){
      public void stateChanged(ChangeEvent arg0)
      {
        readLnHgt = (slider.getValue()/10.f);
        repaintBamView();
      }
    });
tcarver's avatar
tcarver committed
    topPanel.add(new JLabel(" Read Height:"));
tcarver's avatar
tcarver committed
    topPanel.add(slider);
    
    if(feature_display != null)
    {
      JButton close = new JButton("Close");
      topPanel.add(close);
      close.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
tcarver's avatar
tcarver committed
          int status = JOptionPane.showConfirmDialog(frame, 
              "Close the BAM panel?", "Close", 
              JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
          if(status == JOptionPane.CANCEL_OPTION)
            return;
          
          final JPanel containerPanel = (JPanel) mainPanel.getParent();
          feature_display.removeDisplayAdjustmentListener(BamView.this);
          feature_display.getSelection().removeSelectionChangeListener(BamView.this);
          containerPanel.remove(mainPanel);
          
          if(containerPanel.getComponentCount() > 0)
            containerPanel.revalidate();
          else
          {
            if(entry_edit != null)
              entry_edit.setNGDivider();
            else
              containerPanel.setVisible(false);
          }
        }
      });
    }
tjc's avatar
tjc committed
    return topPanel;
  }
  
  public void setVisible(boolean visible)
  {
    super.setVisible(visible);
    mainPanel.setVisible(visible);
tjc's avatar
tjc committed
  }
  
tjc's avatar
tjc committed
  private void setViewportMidPoint()
  {
    Point p = jspView.getViewport().getLocation();
    p.y = (getHeight() - jspView.getViewport().getViewRect().height)/2;
    jspView.getViewport().setViewPosition(p);
  }
  
  private void setViewportBtm()
  {
    jspView.getVerticalScrollBar().setValue(
        jspView.getVerticalScrollBar().getMaximum());
  }
  
tjc's avatar
tjc committed
  protected int getBaseAtStartOfView()
tjc's avatar
tjc committed
  {
tjc's avatar
tjc committed
    if(feature_display != null)
      return feature_display.getForwardBaseAtLeftEdge();
    else
      return scrollBar.getValue();
tjc's avatar
tjc committed
  }
  
  /**
   * Set the panel size based on the number of bases visible
   * and repaint.
   * @param nbasesInView
   */
tjc's avatar
tjc committed
  private void setZoomLevel(final int nbasesInView)
  {
tjc's avatar
tjc committed
    int startValue = getBaseAtStartOfView();
tjc's avatar
tjc committed
    this.nbasesInView = nbasesInView;
tjc's avatar
tjc committed
    float pixPerBase = getPixPerBaseByWidth(); 
tjc's avatar
tjc committed

    if(isBaseAlignmentView(pixPerBase))
tjc's avatar
tjc committed
    {
      pixPerBase = ALIGNMENT_PIX_PER_BASE;
      this.nbasesInView = (int)(mainPanel.getWidth()/pixPerBase);
tjc's avatar
tjc committed
      jspView.getVerticalScrollBar().setValue(0);
      
      if(ruler == null)
        ruler = new Ruler();
tjc's avatar
tjc committed
      jspView.setColumnHeaderView(ruler);
      showBaseAlignment = true;
      baseQualityColour.setEnabled(true);
      markInsertions.setEnabled(true);
tjc's avatar
tjc committed
    }
    else if(jspView != null)
    {
      if(!isCoverageView(pixPerBase) && nbasesInView >= MAX_BASES)
      {
        cbLastSelected = getSelectedCheckBoxMenuItem();
        cbCoverageView.setSelected(true);
        coverageView.setPlotByStrand(false);
tcarver's avatar
tcarver committed
      else if(isCoverageView(pixPerBase) && nbasesInView < MAX_BASES && cbLastSelected != null)
      {
        cbLastSelected.setSelected(true);
        cbLastSelected = null;
      }
tcarver's avatar
tcarver committed

tjc's avatar
tjc committed
      jspView.setColumnHeaderView(null);
tcarver's avatar
tcarver committed
      if(isCoverageView(pixPerBase))
        setViewportBtm();
tcarver's avatar
tcarver committed
      else if (isStrandStackView())
tjc's avatar
tjc committed
      showBaseAlignment = false;
      baseQualityColour.setEnabled(false);
      markInsertions.setEnabled(false);
tjc's avatar
tjc committed
    }
tcarver's avatar
tcarver committed

tjc's avatar
tjc committed
    if(scrollBar != null)
tjc's avatar
tjc committed
      scrollBar.setValues(startValue, nbasesInView, 1, 
             getMaxBasesInPanel(getSequenceLength()));
      scrollBar.setUnitIncrement(nbasesInView/20);
      scrollBar.setBlockIncrement(nbasesInView);
tjc's avatar
tjc committed
  }
tjc's avatar
tjc committed

tjc's avatar
tjc committed
  /**
   * Set the start and end base positions to display.
   * @param start
   * @param end
   * @param event
tjc's avatar
tjc committed
   */
  public void setDisplay(int start,
                         int end,
                         DisplayAdjustmentEvent event)
tjc's avatar
tjc committed
  {
    this.startBase = start;
    this.endBase   = end;
tjc's avatar
tjc committed
    this.nbasesInView = end-start+1;
    lastMousePoint = null;
tjc's avatar
tjc committed
    float pixPerBase;
    if(jspView.getViewport().getViewRect().width > 0)
tjc's avatar
tjc committed
      pixPerBase = getPixPerBaseByWidth();
tjc's avatar
tjc committed
    else
    {
      if(feature_display == null)
        pixPerBase = 1000.f/(float)(end-start+1);
      else
        pixPerBase = feature_display.getWidth()/(float)(end-start+1);
    }
tjc's avatar
tjc committed
    Dimension d = new Dimension();
tjc's avatar
tjc committed
    d.setSize(nbasesInView*pixPerBase, maxHeight);
tjc's avatar
tjc committed
    setPreferredSize(d);
tjc's avatar
tjc committed
    if(event == null)
    {
      this.startBase = -1;
      this.endBase   = -1;
    }
tjc's avatar
tjc committed
  /**
   * Return an Artemis entry from a file 
   * @param entryFileName
   * @param entryGroup
   * @return
   * @throws NoSequenceException
   */
  private Entry getEntry(final String entryFileName, final EntryGroup entryGroup) 
                   throws NoSequenceException
  {
    final Document entry_document = DocumentFactory.makeDocument(entryFileName);
    final EntryInformation artemis_entry_information =
      Options.getArtemisEntryInformation();
    
    //System.out.println(entryFileName);
tjc's avatar
tjc committed
    final uk.ac.sanger.artemis.io.Entry new_embl_entry =
      EntryFileDialog.getEntryFromFile(null, entry_document,
                                       artemis_entry_information,
                                       false);

    if(new_embl_entry == null)  // the read failed
      return null;

    Entry entry = null;
    try
    {
      if(entryGroup.getSequenceEntry() != null)
        bases = entryGroup.getSequenceEntry().getBases();
tjc's avatar
tjc committed
      
tjc's avatar
tjc committed
      if(bases == null)
tjc's avatar
tjc committed
      {
tjc's avatar
tjc committed
        entry = new Entry(new_embl_entry);
tjc's avatar
tjc committed
        bases = entry.getBases();
      }
tjc's avatar
tjc committed
      else
        entry = new Entry(bases,new_embl_entry);
      
      entryGroup.add(entry);
    } 
    catch(OutOfRangeException e) 
    {
      new MessageDialog(null, "read failed: one of the features in " +
          entryFileName + " has an out of range " +
                        "location: " + e.getMessage());
    }
    return entry;
  }
  
  private boolean isShowScale()
  {
tjc's avatar
tjc committed
    return (feature_display == null ? true : false);
  }

  public JScrollPane getJspView()
  {
    return jspView;
  }
  
  /**
   *  Handle a mouse drag event on the drawing canvas.
   **/
tjc's avatar
tjc committed
  private void handleCanvasMouseDrag(final MouseEvent event)
    if(event.getButton() == MouseEvent.BUTTON3 || bases == null) 
    // KJP: Removed this as it causes selection issues and
    // doesn't seems strictly necessary.
    // highlightSAMRecord = null;
    
    if(event.getClickCount() > 1)
    {
      getSelection().clear();
      repaint();
      return;  
    }
    
    highlightRange(event, 
        MouseEvent.BUTTON1_DOWN_MASK & MouseEvent.BUTTON2_DOWN_MASK);
  }
  
  /**
   * 
   * @param event
   * @param onmask
   */
  protected void highlightRange(MouseEvent event, int onmask)
tjc's avatar
tjc committed
    int seqLength = getSequenceLength();
tjc's avatar
tjc committed
    float pixPerBase = getPixPerBaseByWidth();
tjc's avatar
tjc committed
    int start = (int) ( ( (event.getPoint().getX())/pixPerBase) + getBaseAtStartOfView() );
    if(start < 1)
      start = 1;
    if(start > seqLength)
      start = seqLength;
    if (dragStart < 0 && (event.getModifiersEx() & onmask) == onmask)
      dragStart = start;
    else if((event.getModifiersEx() & onmask) != onmask)
      dragStart = -1;
    
    MarkerRange drag_range;
    try
      if(dragStart < 0)
        drag_range = new MarkerRange (bases.getForwardStrand(), start, start);
      else
        drag_range = new MarkerRange (bases.getForwardStrand(), dragStart, start);
      getSelection().setMarkerRange(drag_range);
      repaint();
    catch (OutOfRangeException e)
      e.printStackTrace();
  /**
   * Get the colour for the given read given to it by the coverage plot.
   * @param samRecord
   * @return
   */
  private Color getColourByCoverageColour(BamViewRecord samRecord)
    if(bamList.size()>1)
      fileIndex = samRecord.bamIndex;
    return getColourByCoverageColour(fileIndex); 
  }
  
  private Color getColourByCoverageColour(final short fileIndex)
  {
    LineAttributes lines[] = CoveragePanel.getLineAttributes(bamList.size());
    return lines[fileIndex].getLineColour(); 
  }

  protected int getMaxBases()
  {
    return MAX_BASES;
  }
  
  protected void setMaxBases(int max)
  {
    MAX_BASES = max;
  }
  
  private boolean isStackView()
  {
    return cbStackView.isSelected();  
  }
  
  private boolean isPairedStackView()
  {
    return cbPairedStackView.isSelected();
  }
  
  private boolean isStrandStackView()
  {
    return cbStrandStackView.isSelected();
  }
  
  private boolean isCoverageView(float pixPerBase)
  {
    if(isBaseAlignmentView(pixPerBase))
      return false;
tcarver's avatar
tcarver committed
    return cbCoverageView.isSelected() || cbCoverageStrandView.isSelected() || cbCoverageHeatMap.isSelected();
  }
  
  private boolean isIsizeStackView()
  {
    return cbIsizeStackView.isSelected();
  }
  
  private boolean isBaseAlignmentView(float pixPerBase)
  {
    if(pixPerBase*1.08f >= ALIGNMENT_PIX_PER_BASE)
      return true;
    return false;
  }
  
  private JCheckBoxMenuItem getSelectedCheckBoxMenuItem()
  {
    if(isStackView())
      return cbStackView;
    if(isPairedStackView())
      return cbPairedStackView;
    if(isStrandStackView())
      return cbStrandStackView;
    if(isIsizeStackView())
      return cbIsizeStackView;
    if(cbCoverageView.isSelected())
      return cbCoverageView;
tcarver's avatar
tcarver committed
    if(cbCoverageHeatMap.isSelected())
      return cbCoverageHeatMap;
    return cbCoverageStrandView;
  protected Selection getSelection()
  protected List<BamViewRecord> getReadsInView()
tjc's avatar
tjc committed
    return readsInView;
  }
  
tjc's avatar
tjc committed
  protected int getBasesInView()
  {
    return nbasesInView;
  }
  
  protected void setHighlightSAMRecord(BamViewRecord highlightSAMRecord)
tcarver's avatar
tcarver committed
  {
    this.highlightSAMRecord = highlightSAMRecord;
  }
  
  protected BamViewRecord getHighlightSAMRecord()
tcarver's avatar
tcarver committed
  {
    return highlightSAMRecord;
  }
  
tcarver's avatar
tcarver committed
  protected FeatureDisplay getFeatureDisplay()
  {
    return feature_display;
  }
  
  /**
   * @return the combo
   */
  public SequenceComboBox getCombo()
  {
    return combo;
  }
  
  protected Hashtable<String, SAMFileReader>  getSamFileReaderHash()
  {
    return samFileReaderHash;
  }
  
  protected Vector<String> getSeqNames()
  {
    return seqNames;
  }
  
  protected HashMap<String, Integer> getSeqLengths()
  {
    return seqLengths;
  }
  
  protected HashMap<String, Integer> getOffsetLengths()
  {
    return offsetLengths;
  }
  
tjc's avatar
tjc committed
  private String getVersion()
  {
    final ClassLoader cl = this.getClass().getClassLoader();
    try
    {
      String line;
      InputStream in = cl.getResourceAsStream("etc/versions");
      BufferedReader reader = new BufferedReader(new InputStreamReader(in));
      while((line = reader.readLine()) != null)
      {
        if(line.startsWith("BamView"))
          return line.substring( "BamView".length() ).trim();
      }
      reader.close();
      in.close();
    }
    catch (Exception ex)
    {
    }
    return null;
  }
  
tcarver's avatar
tcarver committed
  /**
   * Open another BamView window
   */
  public void openBamView(final List<String> bamsList)
tcarver's avatar
tcarver committed
  {
    BamView bamView = new BamView(bamsList, 
tcarver's avatar
tcarver committed
        null, nbasesInView, entry_edit,
        feature_display, bases, (JPanel) mainPanel.getParent(), null);
    bamView.getJspView().getVerticalScrollBar().setValue(
        bamView.getJspView().getVerticalScrollBar().getMaximum());
    getJspView().getVerticalScrollBar().setValue(
        bamView.getJspView().getVerticalScrollBar().getMaximum());

    int start = getBaseAtStartOfView();
    setDisplay(start, nbasesInView+start, null);
    if(feature_display != null)
    {
      feature_display.addDisplayAdjustmentListener(bamView);
      feature_display.getSelection().addSelectionChangeListener(bamView);
tcarver's avatar
tcarver committed
      if(entry_edit != null)
        entry_edit.getOneLinePerEntryDisplay().addDisplayAdjustmentListener(bamView);
      if(feature_display.getEntryGroup().getSequenceEntry().getEMBLEntry().getSequence() 
          instanceof uk.ac.sanger.artemis.io.IndexFastaStream)
      {
        if(entry_edit != null)
        {
          // add reference sequence selection listeners
          entry_edit.getEntryGroupDisplay().getIndexFastaCombo().addIndexReferenceListener(bamView.getCombo());
          bamView.getCombo().addIndexReferenceListener(entry_edit.getEntryGroupDisplay().getIndexFastaCombo());
tjc's avatar
tjc committed
  /**
   * Artemis event notification
   */
  public void displayAdjustmentValueChanged(final DisplayAdjustmentEvent event)
    if(event.getType() == DisplayAdjustmentEvent.REV_COMP_EVENT &&
       event.isRevCompDisplay())
      JOptionPane.showMessageDialog(this, 
          "Flipping the display is not supported by BamView.", "Warning", 
          JOptionPane.WARNING_MESSAGE);

    if(!asynchronous)
    {
      // if not asynchronous
      displayAdjustmentWork(event);
      return;
    }
    
    SwingWorker worker = new SwingWorker()
tjc's avatar
tjc committed
    {
      public Object construct()
      {
        try
        {
          Thread.sleep(500);
        }
        catch (InterruptedException e)
        {
          e.printStackTrace();
        }
        
        if(event.getStart() != ((FeatureDisplay)event.getSource()).getForwardBaseAtLeftEdge())
        {
          waitingFrame.showWaiting("waiting...", mainPanel);
        displayAdjustmentWork(event);
        waitingFrame.setVisible(false);
        return null;
      }
    };
    worker.start();
  /**
   * Carry out the display agjustment event action.
   * @param event
   */
  private void displayAdjustmentWork(final DisplayAdjustmentEvent event)
  {
    if(event.getType() == DisplayAdjustmentEvent.SCALE_ADJUST_EVENT)
    {
      laststart = -1;
tjc's avatar
tjc committed

      BamView.this.startBase = event.getStart();
      BamView.this.endBase   = event.getEnd();

      int width = feature_display.getMaxVisibleBases();
      setZoomLevel(width);
      repaint();
    }
    else
    {
      setDisplay(event.getStart(), 
        event.getStart()+feature_display.getMaxVisibleBases(), event);
      repaint();
    }
  }
  
tjc's avatar
tjc committed
  public void selectionChanged(SelectionChangeEvent event)
  {
    repaint();
tjc's avatar
tjc committed
  private class Ruler extends JPanel
tjc's avatar
tjc committed
  {
tjc's avatar
tjc committed
    private static final long serialVersionUID = 1L;
    protected int start;
    protected int end;
    protected String refSeq;
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    public Ruler()
    {
      super();
      setPreferredSize(new Dimension(mainPanel.getWidth(), 26));
tjc's avatar
tjc committed
      setBackground(Color.white);
    }
tjc's avatar
tjc committed

tjc's avatar
tjc committed
    public void paintComponent(Graphics g)
    {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D)g;
      drawBaseScale(g2, start, end, 12);
    }
tjc's avatar
tjc committed

    private void drawBaseScale(Graphics2D g2, int start, int end, int ypos)
    {
      int startMark = (((int)(start/10))*10)+1;
      if(end > getSequenceLength())
        end = getSequenceLength();

      for(int i=startMark; i<end; i+=20)
tjc's avatar
tjc committed
      {
tjc's avatar
tjc committed
        int xpos = (i-start)*ALIGNMENT_PIX_PER_BASE;
tjc's avatar
tjc committed
        g2.drawString(Integer.toString(i), xpos, ypos);
tjc's avatar
tjc committed
        
      for(int i=startMark; i<end; i+=10)
      {
        int xpos = (i-start)*ALIGNMENT_PIX_PER_BASE;
tjc's avatar
tjc committed
        xpos+=(ALIGNMENT_PIX_PER_BASE/2);
        g2.drawLine(xpos, ypos+1, xpos, ypos+5);
      }
      
      if(refSeq != null)
      {
        ypos+=15;
        g2.setColor(LIGHT_GREY);
        g2.fillRect(0, ypos-11, getWidth(), 11);

        g2.translate(0, 16);
        drawSelectionRange(g2, ALIGNMENT_PIX_PER_BASE, start, end, Color.yellow);
        g2.translate(0, -16);
        g2.setColor(Color.black);
        g2.drawString(refSeq, 0, ypos-2);
      }
tjc's avatar
tjc committed
    }
tjc's avatar
tjc committed
  }
  
  /**
  * Popup menu listener
  */
  class PopupListener extends MouseAdapter
  {
tcarver's avatar
tcarver committed
	private JMenuItem gotoMateMenuItem;
	private JMenuItem showDetails;
	private JMenu coverageMenu;
	private JMenuItem createGroup;
    public void mouseClicked(MouseEvent e)
    {
      if(e.isPopupTrigger() ||
         e.getButton() == MouseEvent.BUTTON3)
        return;
      
      
      if(e.getClickCount() > 1)
        getSelection().clear(); 
      else if(e.getButton() == MouseEvent.BUTTON1)
tcarver's avatar
tcarver committed
      {
        if(isCoverageView(getPixPerBaseByWidth()))
          coverageView.singleClick(e.isShiftDown(),
              e.getPoint().y-getJspView().getViewport().getViewPosition().y);
        //else
        //{
        	//	mouseHighlightSelectionMade.set(true);
        	//	highlightSAMRecord = null;
        //}
      else
        highlightRange(e, MouseEvent.BUTTON2_DOWN_MASK);
    public void mousePressed(final MouseEvent e)
      highlightSAMRecord = mouseOverSAMRecord;

    	  repaint();
    	  
    	  javax.swing.SwingUtilities.invokeLater(new Runnable() {
    	        public void run() {
    	        		maybeShowPopup(e);
    	        }
    	    });
      
    }

    public void mouseReleased(MouseEvent e)
    {
      maybeShowPopup(e);
    }

    private void maybeShowPopup(MouseEvent e)
    {
      if(e.isPopupTrigger())
tcarver's avatar
tcarver committed
      {       
        //
        // main menu options
tjc's avatar
tjc committed
        if(popup == null)
        {
          popup = new JPopupMenu();
          createMenus(popup);
tjc's avatar
tjc committed
        }
tcarver's avatar
tcarver committed

        //
        // coverage heatmap menu options
        if(coverageMenu != null)
          popup.remove(coverageMenu);
        if(isCoverageView(getPixPerBaseByWidth()) && coverageView.isPlotHeatMap())
        {
          if(coverageMenu == null)
          {
            coverageMenu = new JMenu("Coverage HeatMap");
tcarver's avatar
tcarver committed
            coverageView.createMenus(coverageMenu);
            
tcarver's avatar
tcarver committed
            final JCheckBoxMenuItem coverageGrid = new JCheckBoxMenuItem("Show heatmap grid", false);
tcarver's avatar
tcarver committed
            coverageGrid.addActionListener(new ActionListener()
            {
              public void actionPerformed(ActionEvent e) 
              {
                coverageView.showLabels(coverageGrid.isSelected());
              }
            });
            coverageMenu.add(coverageGrid);

            createGroup = new JMenuItem("Create group from selected BAMs");
            createGroup.addActionListener(new ActionListener()
            {
tcarver's avatar
tcarver committed
              private int n = 1;
tcarver's avatar
tcarver committed
              public void actionPerformed(ActionEvent e) 
              {
tcarver's avatar
tcarver committed
                String groupName = "group_"+n;
                groupsFrame.addGroup(groupName);
                final List<String> selected = coverageView.getSelected();