Skip to content
Snippets Groups Projects
BamView.java 93.6 KiB
Newer Older
  • Learn to ignore specific revisions
  •       }
        };
        addMouseMotionListener(mouseMotionListener);
    
        combo = new JComboBox(seqNames);
        combo.setEditable(false);
    
        combo.setMaximumRowCount(20);
        
    
        combo.addItemListener(new ItemListener()
        {
          public void itemStateChanged(ItemEvent e)
          {
            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)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          final JTextField baseText = new JTextField(8);
    
          JButton goTo = new JButton("GoTo:");
    
    tjc's avatar
    tjc committed
          goTo.setToolTipText("Go to base position");
    
          goTo.addActionListener(new ActionListener()
    
    tjc's avatar
    tjc committed
          {
    
            public void actionPerformed(ActionEvent e)
    
    tjc's avatar
    tjc committed
            {
    
              try
              {
                int basePosition = Integer.parseInt(baseText.getText());
    
    tjc's avatar
    tjc committed
                scrollBar.setValue(basePosition);
    
              }
              catch (NumberFormatException nfe)
              {
    
                JOptionPane.showMessageDialog(BamView.this,
    
                    "Expecting a base number!", "Number Format",
                    JOptionPane.WARNING_MESSAGE);
              }
    
    tjc's avatar
    tjc committed
            }
    
    tjc's avatar
    tjc committed
          topPanel.add(goTo);
          topPanel.add(baseText);
    
          JButton zoomIn = new JButton("-");
          Insets ins = new Insets(1,1,1,1);
    
          zoomIn.setMargin(ins);
    
          zoomIn.addActionListener(new ActionListener()
    
    tjc's avatar
    tjc committed
          {
    
            public void actionPerformed(ActionEvent e)
            {
    
              setZoomLevel((int) (BamView.this.nbasesInView * 1.1));
    
    tjc's avatar
    tjc committed
          topPanel.add(zoomIn);
    
          JButton zoomOut = new JButton("+");
          zoomOut.setMargin(ins);
    
          zoomOut.addActionListener(new ActionListener()
    
    tjc's avatar
    tjc committed
          {
    
            public void actionPerformed(ActionEvent e)
            {
              if (showBaseAlignment)
                return;
    
              setZoomLevel((int) (BamView.this.nbasesInView * .9));
    
    tjc's avatar
    tjc committed
          topPanel.add(zoomOut);
    
    tjc's avatar
    tjc committed
        topPanel.add(buttonAutoHide);
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        mainPanel.setPreferredSize(new Dimension(900, 400));
    
    tjc's avatar
    tjc committed
        
        jspView = new JScrollPane(this, 
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
    
    tjc's avatar
    tjc committed
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    
        setDisplay(1, nbasesInView, null);
        mainPanel.setLayout(new BorderLayout());
    
    tjc's avatar
    tjc committed
        if(topPanel instanceof JPanel)
          mainPanel.add(topPanel, BorderLayout.NORTH);
    
        mainPanel.add(jspView, BorderLayout.CENTER);
    
    tjc's avatar
    tjc committed
        JPanel bottomPanel = new JPanel(new BorderLayout());
        coveragePanel = new CoveragePanel(this);
        bottomPanel.add(coveragePanel, BorderLayout.CENTER);
    
    
    tjc's avatar
    tjc committed
        //
        snpPanel = new SnpPanel(this, bases);
        bottomPanel.add(snpPanel, BorderLayout.NORTH);
        
    
    tjc's avatar
    tjc committed
        if(feature_display == null)
        {
          scrollBar = new JScrollBar(JScrollBar.HORIZONTAL, 1, nbasesInView, 1,
              getMaxBasesInPanel(getSequenceLength()));
    
          scrollBar.setUnitIncrement(nbasesInView/20);
    
    tjc's avatar
    tjc committed
          scrollBar.addAdjustmentListener(new AdjustmentListener()
          {
            public void adjustmentValueChanged(AdjustmentEvent e)
            {
              repaint();
    
    tjc's avatar
    tjc committed
              if(coveragePanel != null)
                coveragePanel.repaint();
              if(snpPanel != null)
                snpPanel.repaint();
    
    tjc's avatar
    tjc committed
            }
          });
          bottomPanel.add(scrollBar, BorderLayout.SOUTH);
        }
    
        mainPanel.add(bottomPanel, BorderLayout.SOUTH);
    
        coveragePanel.setPreferredSize(new Dimension(900, 100));
        coveragePanel.setVisible(false);
    
    tjc's avatar
    tjc committed
        snpPanel.setPreferredSize(new Dimension(900, 100));
        snpPanel.setVisible(false);
    
    
    tjc's avatar
    tjc committed
        jspView.getVerticalScrollBar().setValue(
            jspView.getVerticalScrollBar().getMaximum());
    
    tjc's avatar
    tjc committed
        jspView.getVerticalScrollBar().setUnitIncrement(maxUnitIncrement);
        
    
    tjc's avatar
    tjc committed
        if(feature_display == null)
    
    tjc's avatar
    tjc committed
        {
    
          addKeyListener(new KeyAdapter()
    
    tjc's avatar
    tjc committed
          {
    
            public void keyPressed(final KeyEvent event)
    
    tjc's avatar
    tjc committed
            {
    
              switch (event.getKeyCode())
              {
    
    tjc's avatar
    tjc committed
              case KeyEvent.VK_UP:
    
                setZoomLevel((int) (BamView.this.nbasesInView * 1.1));
    
    tjc's avatar
    tjc committed
                break;
              case KeyEvent.VK_DOWN:
    
                if (showBaseAlignment)
                  break;
    
                setZoomLevel((int) (BamView.this.nbasesInView * .9));
    
    tjc's avatar
    tjc committed
                break;
              default:
                break;
    
    tjc's avatar
    tjc committed
            }
    
        addMouseListener(new PopupListener());
    
    tjc's avatar
    tjc committed
        setFocusable(true);
        requestFocusInWindow();
    
      
      private void addToViewMenu(final int thisBamIndex)
      {
        File f = new File(bamList.get(thisBamIndex));
        final JCheckBoxMenuItem cbBam = new JCheckBoxMenuItem(
                                         f.getName(), true);
        bamFilesMenu.add(cbBam);
        cbBam.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            if(cbBam.isSelected())
              hideBamList.remove(new Integer(thisBamIndex));
            else
              hideBamList.add(new Integer(thisBamIndex));
            laststart = -1;
            repaint();
          } 
        });
      }
    
    tjc's avatar
    tjc committed
    
    
      private void createMenus(JComponent menu)
    
      {
        final JMenuItem addBam = new JMenuItem("Add Bam ...");
        menu.add(addBam);
        addBam.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
    
            FileSelectionDialog bamFileSelection = new FileSelectionDialog(
                null, false, "BamView", "BAM");
    
            List<String> bamFiles = bamFileSelection.getFiles(".*\\.bam$");
    
            int count = bamList.size();
           
    
            bamList.addAll(bamFileSelection.getFiles(".*\\.bam$"));
    
            
            for(int i=0; i<bamFiles.size(); i++)
              addToViewMenu(i+count);
    
    tjc's avatar
    tjc committed
            laststart = -1; 
    
            repaint();
          } 
        });
        
        bamFilesMenu.setFont(addBam.getFont());
        menu.add(bamFilesMenu);
        for(int i=0; i<bamList.size(); i++)
          addToViewMenu(i);
        
        menu.add(new JSeparator());
        
    
        JMenu viewMenu = new JMenu("Views");
    
    tjc's avatar
    tjc committed
        cbStackView.setFont(viewMenu.getFont());
        cbIsizeStackView.setFont(viewMenu.getFont());
        cbPairedStackView.setFont(viewMenu.getFont());
        cbStrandStackView.setFont(viewMenu.getFont());
        cbCoverageView.setFont(viewMenu.getFont());
        
        baseQualityColour.setFont(viewMenu.getFont());
        colourByCoverageColour.setFont(viewMenu.getFont());
        markInsertions.setFont(viewMenu.getFont());
    
        
        cbIsizeStackView.addActionListener(new ActionListener()
    
    tjc's avatar
    tjc committed
        {
          public void actionPerformed(ActionEvent e)
          {
            laststart = -1;
    
            if(isIsizeStackView())
    
              logMenuItem.setEnabled(true);
    
    tjc's avatar
    tjc committed
            repaint();
          }
        });
    
        viewMenu.add(cbIsizeStackView);
    
        cbStackView.addActionListener(new ActionListener()
    
    tjc's avatar
    tjc committed
        {
          public void actionPerformed(ActionEvent e)
          {
            laststart = -1;
    
            if(isStackView())
    
              logMenuItem.setEnabled(false);
    
    tjc's avatar
    tjc committed
            repaint();
          }
        });
    
        viewMenu.add(cbStackView);
    
        cbPairedStackView.addActionListener(new ActionListener()
    
        {
          public void actionPerformed(ActionEvent e)
          {
            laststart = -1;
    
            if(cbPairedStackView.isSelected())
    
              logMenuItem.setEnabled(false);
    
        viewMenu.add(cbPairedStackView);
    
        cbStrandStackView.addActionListener(new ActionListener()
    
    tjc's avatar
    tjc committed
        {
          public void actionPerformed(ActionEvent e)
          {
            laststart = -1;
    
            if(isStrandStackView())
    
    tjc's avatar
    tjc committed
            {
              setViewportMidPoint();
    
              logMenuItem.setEnabled(false);
    
    tjc's avatar
    tjc committed
            }
            repaint();
          }
        });
    
        viewMenu.add(cbStrandStackView);
        
        cbCoverageView.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            laststart = -1;
            repaint();
          }
        });
        viewMenu.add(cbCoverageView);
        
    
        menu.add(viewMenu);
    
    tjc's avatar
    tjc committed
        final JCheckBoxMenuItem checkBoxSNPs = new JCheckBoxMenuItem("SNP marks");
    
        // 
        JMenu colourMenu = new JMenu("Colour By");
        colourMenu.add(colourByCoverageColour);
        
        baseQualityColour.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            if(baseQualityColour.isSelected())
            {
              checkBoxSNPs.setSelected(false);
              isSNPs = false;
            }
            repaint();
          }
        });
        colourMenu.add(baseQualityColour);
        menu.add(colourMenu);
        
        //
    
        JMenu showMenu = new JMenu("Show");
    
        JCheckBoxMenuItem checkBoxOrientation = new JCheckBoxMenuItem("Orientation");
        checkBoxOrientation.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            isOrientation = !isOrientation;
            repaint();
          }
        });
        showMenu.add(checkBoxOrientation);
        
    
        JCheckBoxMenuItem checkBoxSingle = new JCheckBoxMenuItem("Single Reads");
        checkBoxSingle.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            repaint();
            isSingle = !isSingle;
          }
        });
        showMenu.add(checkBoxSingle);
    
        checkBoxSNPs.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            if (isSNPs && bases == null)
            {
              JOptionPane.showMessageDialog(null,
                  "No reference sequence supplied to identify SNPs.", "SNPs",
                  JOptionPane.INFORMATION_MESSAGE);
            }
            isSNPs = !isSNPs;
            
            if(isSNPs)
              baseQualityColour.setSelected(false);
            repaint();
          }
        });
        showMenu.add(checkBoxSNPs);
    
        
        markInsertions.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            repaint();
          }
        });
        showMenu.add(markInsertions);
    
    tjc's avatar
    tjc committed
        menu.add(showMenu);
    
    tjc's avatar
    tjc committed
        //
        JMenu graphMenu = new JMenu("Graph");
    
        JCheckBoxMenuItem checkBoxCoverage = new JCheckBoxMenuItem("Coverage");
        checkBoxCoverage.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            isCoverage = !isCoverage;
            coveragePanel.setVisible(isCoverage);
    
    tjc's avatar
    tjc committed
            
            if(isCoverage && !cbCoverageView.isSelected())
              laststart = -1;
    
            repaint();
          }
        });
    
    tjc's avatar
    tjc committed
        graphMenu.add(checkBoxCoverage);
        
        JCheckBoxMenuItem checkBoxSNP = new JCheckBoxMenuItem("SNP");
        checkBoxSNP.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            isSNPplot = !isSNPplot;
            snpPanel.setVisible(isSNPplot);
    
            laststart = -1;
    
    tjc's avatar
    tjc committed
            repaint();
          }
        });
        graphMenu.add(checkBoxSNP);
        menu.add(graphMenu);
        
    
        if(feature_display != null)
    
          final JCheckBoxMenuItem checkBoxSync =
            new JCheckBoxMenuItem("Asynchronous", asynchronous);
          checkBoxSync.addActionListener(new ActionListener()
    
            public void actionPerformed(ActionEvent e)
            {
              asynchronous = checkBoxSync.isSelected();
            }
          });
    
          menu.add(checkBoxSync);
    
        menu.add(new JSeparator());
    
        JMenu maxHeightMenu = new JMenu("BamView Height");
    
        menu.add(maxHeightMenu);
    
        final String hgts[] =
           {"500", "800", "1000", "1500", "2500", "5000", "50000"};
    
        
        ButtonGroup bgroup = new ButtonGroup();
        for(int i=0; i<hgts.length; i++)
        {
          final String hgt = hgts[i];
          final JCheckBoxMenuItem maxHeightMenuItem = new JCheckBoxMenuItem(hgt);
          bgroup.add(maxHeightMenuItem);
          maxHeightMenuItem.setSelected(hgts[i].equals(Integer.toString(maxHeight)));
          maxHeightMenu.add(maxHeightMenuItem);
          maxHeightMenuItem.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent e)
            {
              if(maxHeightMenuItem.isSelected())
                maxHeight = Integer.parseInt(hgt);
              int start = getBaseAtStartOfView();
              setDisplay(start, nbasesInView+start, null);
            }
          });
        }
    
        menu.add(new JSeparator());
    
    tjc's avatar
    tjc committed
        logMenuItem.setFont(menu.getFont());
    
        menu.add(logMenuItem);
        logMenuItem.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            logScale = logMenuItem.isSelected();
            repaint();
          }
        });
        
    
        JMenuItem filter = new JMenuItem("Filter by Flag...");
        menu.add(filter);
        filter.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            new SAMRecordFilter(BamView.this);
          } 
        });
    
    
        //
        JMenu coverageMenu = new JMenu("Coverage Options");
        coverageView.init(this, 0.f, 0, 0);
        coverageView.createMenus(coverageMenu, BamView.this);
        viewMenu.add(new JSeparator());
        viewMenu.add(coverageMenu);
    
      }
      
      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);
      }
      
    
    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(!cbCoverageView.isSelected() && nbasesInView >= MAX_BASES)
          {
            cbLastSelected = getSelectedCheckBoxMenuItem();
            cbCoverageView.setSelected(true);
          }
          else if(cbCoverageView.isSelected() && nbasesInView < MAX_BASES && cbLastSelected != null)
          {
            cbLastSelected.setSelected(true);
            cbLastSelected = null;
          }
          
    
    tjc's avatar
    tjc committed
          jspView.setColumnHeaderView(null);
    
    tjc's avatar
    tjc committed
          
    
          if(!isStrandStackView())
    
    tjc's avatar
    tjc committed
            jspView.getVerticalScrollBar().setValue(
                jspView.getVerticalScrollBar().getMaximum());
    
    tjc's avatar
    tjc committed
          showBaseAlignment = false;
    
          baseQualityColour.setEnabled(false);
    
          markInsertions.setEnabled(false);
    
    tjc's avatar
    tjc 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()
      {
        return showScale;
      }
    
      public void setShowScale(boolean showScale)
      {
        this.showScale = showScale;
      }
      
      public JScrollPane getJspView()
      {
        return jspView;
      }
      
      public void setBases(Bases bases)
      {
        this.bases = bases;
      }
      
      /**
       * Remove JScrollPane border
       */
      public void removeBorder()
      {
        Border empty = new EmptyBorder(0,0,0,0);
        jspView.setBorder(empty);
      }
      
      /**
       *  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) 
    
        if(event.getClickCount() > 1)
        {
          getSelection().clear();
          repaint();
          return;  
        }
        
    
        highlightRange(event, 
            MouseEvent.BUTTON1_DOWN_MASK & MouseEvent.BUTTON2_DOWN_MASK);
      }
      
      /**
       * 
       * @param event
       * @param onmask
       */
      private 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(SAMRecord samRecord)
      {
        LineAttributes lines[] = CoveragePanel.getLineAttributes(bamList.size());
        int fileIndex = 0;
        if(bamList.size()>1)
          fileIndex = (Integer) samRecord.getAttribute("FL");
        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;
        return cbCoverageView.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;
        return cbCoverageView;
      }
    
      private Selection getSelection()
      {
        return selection;
      }
      
    
    tjc's avatar
    tjc committed
      protected List<SAMRecord> getReadsInView()
    
    tjc's avatar
    tjc committed
        return readsInView;
      }
      
    
      protected Hashtable<String, int[]> getCoveragePlotData()
      {
        return coverageView.getPlotData();
      }
      
    
    tjc's avatar
    tjc committed
      protected int getBasesInView()
      {
        return nbasesInView;
      }
      
    
    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;
      }
      
    
    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();
    
          if(coveragePanel != null && coveragePanel.isVisible()) 
          {
            coveragePanel.setStartAndEnd(BamView.this.startBase, BamView.this.endBase);
            coveragePanel.setPixPerBase(getPixPerBaseByWidth());
    
    tjc's avatar
    tjc committed
            coveragePanel.repaint();
    
    tjc's avatar
    tjc committed
          if(snpPanel != null && snpPanel.isVisible())
    
          {
            snpPanel.setStartAndEnd(BamView.this.startBase, BamView.this.endBase);
            snpPanel.setPixPerBase(getPixPerBaseByWidth());
    
    tjc's avatar
    tjc committed
            snpPanel.repaint();
    
        }
        else
        {
          setDisplay(event.getStart(), 
            event.getStart()+feature_display.getMaxVisibleBases(), event);
          repaint();
    
    tjc's avatar
    tjc committed
          if(coveragePanel != null && coveragePanel.isVisible())
            coveragePanel.repaint();
          if(snpPanel != null && snpPanel.isVisible())
            snpPanel.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;
    
    tjc's avatar
    tjc committed
        int start;
        int end;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        public Ruler()
        {
          super();
    
          setPreferredSize(new Dimension(mainPanel.getWidth(), 15));
    
    tjc's avatar
    tjc committed
          setBackground(Color.white);
          setFont(getFont().deriveFont(11.f));
        }
    
    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();
          
    
    tjc's avatar
    tjc committed
          for(int i=startMark; i<end; i+=10)
          {
    
    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);
            
            xpos+=(ALIGNMENT_PIX_PER_BASE/2);
            g2.drawLine(xpos, ypos+1, xpos, ypos+5);
          }
        }
    
    tjc's avatar
    tjc committed
      }
      
    
      /**
      * Popup menu listener
      */
      class PopupListener extends MouseAdapter
      {
    
        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)
            highlightSAMRecord = mouseOverSAMRecord;
    
          else
            highlightRange(e, MouseEvent.BUTTON2_DOWN_MASK);
    
        }
        
        public void mousePressed(MouseEvent e)
        {
          maybeShowPopup(e);
        }
    
        public void mouseReleased(MouseEvent e)
        {
    
          maybeShowPopup(e);
        }
    
        private void maybeShowPopup(MouseEvent e)
        {
          if(e.isPopupTrigger())
    
    tjc's avatar
    tjc committed
          {
            if(popup == null)
            {
              popup = new JPopupMenu();
    
              createMenus(popup);
    
    tjc's avatar
    tjc committed
            }
    
            
            if(gotoMateMenuItem != null)
              popup.remove(gotoMateMenuItem);
    
    
            if(showDetails != null)
              popup.remove(showDetails);