From 65ea2d45f6812649eac1efbf0d9ac9fdb492b485 Mon Sep 17 00:00:00 2001
From: tjc <tjc@ee4ac58c-ac51-4696-9907-e4b3aa274f04>
Date: Fri, 15 Aug 2008 15:24:46 +0000
Subject: [PATCH] draw linear plots fixed and printing single page image files

git-svn-id: svn+ssh://svn.internal.sanger.ac.uk/repos/svn/pathsoft/artemis/trunk@8565 ee4ac58c-ac51-4696-9907-e4b3aa274f04
---
 uk/ac/sanger/artemis/circular/Block.java      | 102 ++++++++---
 uk/ac/sanger/artemis/circular/DNADraw.java    | 166 +++++++++++++++---
 .../artemis/circular/LineAttribute.java       |  16 +-
 .../artemis/circular/PrintDNAImage.java       |  59 +++++--
 4 files changed, 269 insertions(+), 74 deletions(-)

diff --git a/uk/ac/sanger/artemis/circular/Block.java b/uk/ac/sanger/artemis/circular/Block.java
index 83035a63d..8e3e31e3f 100644
--- a/uk/ac/sanger/artemis/circular/Block.java
+++ b/uk/ac/sanger/artemis/circular/Block.java
@@ -28,6 +28,7 @@ import java.awt.*;
 import java.awt.datatransfer.*;
 import java.awt.event.*;
 import java.io.IOException;
+import java.util.Vector;
 
 import javax.swing.event.*;
 
@@ -38,7 +39,7 @@ public class Block implements Transferable
   private double angStart;
   private double angEnd;
 
-  private Rectangle rect = new Rectangle();
+  private Vector rect;
   private boolean drawLabel = false;
   final public static DataFlavor BLOCK =
          new DataFlavor(Block.class, "Block");
@@ -217,7 +218,7 @@ public class Block implements Transferable
     {
       public void actionPerformed(ActionEvent e)
       {
-        dialog.show();
+        dialog.setVisible(true);
       }
     });
     bacross = Box.createHorizontalBox();
@@ -350,7 +351,7 @@ public class Block implements Transferable
     f.setVisible(true);
   }
 
-  protected void drawLinear(Graphics2D g2)
+  protected void drawLinear(final Graphics2D g2)
   {
     RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
         RenderingHints.VALUE_ANTIALIAS_ON); 
@@ -361,31 +362,34 @@ public class Block implements Transferable
     String markerLabel = getLabel();
     int bstart = getBstart();
     int bend   = getBend();
+    
    
-    float strokeSize2 = getStrokeSize()/2.f;
-
     FontMetrics fm = g2.getFontMetrics();
-    //double hgt = fm.getAscent();
     g2.setColor(getColour());
 
-    double ddiameter   = current_dna.getDiameter();
-    double heightPanel = current_dna.getHeight();
-    Point location = current_dna.getLocationPoint();
-    int ymid  = (int)(heightPanel/2.);
+    //int shift = (int)getTrack().getPosition();
 
-    int shift = (int)getTrack().getPosition();
-    if(shift > 1 && shift < (int)heightPanel)
-      ymid  = shift;
+    int basesPerLine    = current_dna.getBasesPerLine();
+    int lineNumberStart = Math.round((float)(bstart-1)/((float)basesPerLine) + 0.5f)-1;
+    int lineNumberEnd   = Math.round((float)(bend-1)/((float)basesPerLine) + 0.5f)-1;
+    float singleBaseWidth = current_dna.getSingleBaseWidth();
+     
+    int border2 = current_dna.getBorder2();
+    
+    int ypos = (int) ( (lineNumberStart*current_dna.getLineHeight()) - (strokeSize/2.f) -
+                        ((1-track.getPosition())*current_dna.getLineHeight())  +
+                        border2+current_dna.getLineHeight());
 
-    int start = current_dna.getStart();
-    int end   = current_dna.getEnd();
-    g2.setStroke(new BasicStroke(strokeSize));
+    int xstart = (int) ((bstart-(lineNumberStart*basesPerLine))*singleBaseWidth)+border2;
+    int xend   = (int) ((bend-(lineNumberEnd*basesPerLine))*singleBaseWidth)+border2;
+    
+    BasicStroke basicstroke = new BasicStroke(
+        strokeSize,
+        BasicStroke.CAP_BUTT, 
+        BasicStroke.JOIN_MITER);
+    g2.setStroke(basicstroke);
 
-    int xend   = (((int)ddiameter-location.x)*(bend-start)/
-                   (end-start))+location.x-(int)strokeSize2;
-    int xstart = (((int)ddiameter-location.x)*(bstart-start)/
-                   (end-start))+location.x+(int)strokeSize2;
-    if(arrowHead)
+    /*if(arrowHead)
     {
       xend-=strokeSize2;
       int[] xPoints = {xend,xend,xend+(int)strokeSize};
@@ -402,15 +406,52 @@ public class Block implements Transferable
       g2.fillPolygon(xPoints,yPoints,3);
       g2.drawLine(xstart,ymid,xend,ymid);
     }
-    else
-      g2.drawLine(xstart,ymid,xend,ymid);
+    else*/
+    
+    if(rect == null)
+      rect = new Vector();
 
+    Rectangle r;
+    
+    if(lineNumberEnd > lineNumberStart)
+    {
+      g2.drawLine(xstart,ypos,current_dna.getWidth()-border2,ypos);
+      r = new Rectangle();
+      r.setLocation(xstart,ypos);
+      r.setSize(current_dna.getWidth()-border2-xstart,(int)strokeSize);
+      rect.add(r);
+      
+      for(int i=lineNumberStart+1; i<lineNumberEnd; i++)
+      {
+        ypos = (int) ( (i*current_dna.getLineHeight()) - (strokeSize/2.f) -
+            ((1-track.getPosition())*current_dna.getLineHeight())  +
+            border2+current_dna.getLineHeight());
+        g2.drawLine(border2,ypos,current_dna.getWidth()-border2,ypos);
+        
+        r = new Rectangle();
+        r.setLocation(border2,ypos);
+        r.setSize(current_dna.getWidth()-border2-border2,(int)strokeSize);
+        rect.add(r);
+      }
+      
+      ypos = (int) ( (lineNumberEnd*current_dna.getLineHeight()) - (strokeSize/2.f) -
+          ((1-track.getPosition())*current_dna.getLineHeight())  +
+          border2+current_dna.getLineHeight());
+      xstart = border2;
+    }
+    
+    g2.drawLine(xstart,ypos,xend,ypos);
+
+    r = new Rectangle();
+    r.setLocation(xstart,ypos);
+    r.setSize(xend-xstart,(int)strokeSize);
+    rect.add(r);
+    
+    
     if(drawLabel)
     {
-      rect.setLocation(xstart,ymid-(int)strokeSize2);
-      rect.setSize(xend-xstart,(int)strokeSize);
       int xmid = xstart+(int)(((xend-xstart)/2.)-(fm.stringWidth(markerLabel)/2.));
-      g2.drawString(markerLabel,xmid,ymid-strokeSize);
+      g2.drawString(markerLabel,xmid,ypos-strokeSize);
     } 
   }
 
@@ -718,7 +759,14 @@ public class Block implements Transferable
       }
     }
     else
-      return rect.contains(x,y);
+    {
+      for(int i=0; i<rect.size(); i++)
+      {
+        Rectangle r = (Rectangle)rect.get(i);
+        if(r.contains(x,y))
+          return true;
+      }
+    }
     
     return false;
   }
diff --git a/uk/ac/sanger/artemis/circular/DNADraw.java b/uk/ac/sanger/artemis/circular/DNADraw.java
index 9cb79185d..27ababfa0 100644
--- a/uk/ac/sanger/artemis/circular/DNADraw.java
+++ b/uk/ac/sanger/artemis/circular/DNADraw.java
@@ -60,7 +60,6 @@ import java.awt.dnd.DropTargetDropEvent;
 import java.awt.dnd.DropTargetEvent;
 import java.awt.dnd.DropTargetListener;
 import java.io.IOException;
-import java.net.URL;
 
 import javax.swing.JButton;
 import javax.swing.JCheckBoxMenuItem;
@@ -129,7 +128,14 @@ public class DNADraw extends ScrollPanel
   protected static int THETA = -90;
   private TrackViewer viewer;
   private AffineTransform original;
-
+  
+  // linear plot variables
+  private int numberOfLines;
+  private int basesPerLine = 10000;
+  private float lineHeight = 100.f;
+  private float singleBaseWidth;
+  private int border2;
+  
   public DNADraw()
   {
     super(new BorderLayout()); 
@@ -335,8 +341,7 @@ public class DNADraw extends ScrollPanel
   protected void paintComponent(Graphics g)
   {
     super.paintComponent(g);
-    Graphics2D g2 = (Graphics2D)g;
-    
+    Graphics2D g2 = (Graphics2D)g;  
 
     if(isCircular())
       drawCircularPanel(g2,true);
@@ -366,7 +371,7 @@ public class DNADraw extends ScrollPanel
     double hgt = fm.getAscent();
     g2.setColor(Color.black);
     double widDash = 4;
-
+    
     int lineSize = 5;
     try
     {
@@ -378,18 +383,33 @@ public class DNADraw extends ScrollPanel
     }
     g2.setStroke(new BasicStroke((float)lineSize));
 
-    double widthPanel  = getWidth();
-    double ddiameter  = widthPanel-border.getWidth();
-    int diameter = (int)ddiameter;
-    int ymid = getHeight()/2;
+    border2 = border.width/2;
 
     g2.setStroke(new BasicStroke((float)lineSize));
-    g2.drawLine(location.x,ymid,
-                diameter,ymid);   
-
-    int start = getStart();
-    int end   = getEnd();
-
+    
+    int lastBase  = getEnd();
+    numberOfLines = Math.round( (lastBase/basesPerLine) + 0.5f);
+    
+    int height = (int) ((numberOfLines * lineHeight)+border.height);
+    Dimension size = new Dimension(getWidth(),height);
+    setPreferredSize(size);
+    setSize(size);
+    
+    singleBaseWidth = (float)(getWidth()-border.width)/(float)basesPerLine;
+    
+    for(int i=0; i<numberOfLines; i++)
+    {
+      int ypos = (int) (border2+lineHeight+(lineHeight*i));
+      
+      if(i<numberOfLines-1)
+        g2.drawLine(border2,ypos,getWidth()-border2,ypos);
+      else
+      {
+        int lastLineWidth = (int) ((lastBase-(i*basesPerLine))*singleBaseWidth)+border2;
+        g2.drawLine(border2,ypos,lastLineWidth,ypos);
+      }
+    }
+    
     g2.setColor(Color.black);
     g2.setStroke(new BasicStroke(1.f));
 
@@ -400,25 +420,37 @@ public class DNADraw extends ScrollPanel
     while(enumTk.hasMoreElements())
     {
       int tick = ((Integer)enumTk.nextElement()).intValue();
-      int x = ((diameter-location.x)*(tick-start)/(end-start))+location.x;
-      int y = ymid+(int)((lineSize+widDash)/2);
-      g2.drawLine(x,ymid,x,y);
+      int lineNumber = Math.round((float)(tick-1)/((float)basesPerLine) + 0.5f)-1;
+      
+      int ypos = (int) (border2+lineHeight+(lineHeight*lineNumber));
+      int xpos = (int) ((tick-(lineNumber*basesPerLine))*singleBaseWidth)+border2;
+      int y = ypos+(int)((lineSize+widDash)/2);
+      
+      g2.drawLine(xpos,ypos,xpos,y);
     }
 
     enumTk = majorTicks.elements();
     while(enumTk.hasMoreElements())
     {
       int tick = ((Integer)enumTk.nextElement()).intValue();
-      int x = ((diameter-location.x)*(tick-start)/(end-start))+location.x;
-      int y = ymid+(lineSize/2)+(int)widDash;
-      g2.drawLine(x,ymid,x,y);
+      int lineNumber = Math.round((float)(tick-1)/((float)basesPerLine) + 0.5f)-1;
+      
+      if(lineNumber < 0)
+        lineNumber = 0;
+      
+      int ypos = (int) (border2+lineHeight+(lineHeight*lineNumber));
+      int xpos = (int) ((tick-(lineNumber*basesPerLine))*singleBaseWidth)+border2;
+      int y = ypos+(int)((lineSize+widDash)/2);
+      
+      g2.drawLine(xpos,ypos,xpos,y);
+      
       String label = Integer.toString(tick);
-      x-=(fm.stringWidth(label)/2);
+      xpos-=(fm.stringWidth(label)/2);
       y+=hgt;
-      g2.drawString(label,x,y);
+      g2.drawString(label,xpos,y);
     }
 
-    if(restrictionEnzyme != null)
+    /*if(restrictionEnzyme != null)
     {
       enumTk = restrictionEnzyme.elements();
       while(enumTk.hasMoreElements())
@@ -434,7 +466,7 @@ public class DNADraw extends ScrollPanel
         y-=hgt;
         g2.drawString(reLabel,x,y);
       }
-    }
+    }*/
 
     // draw features
     Vector markers = getGeneticMarker();
@@ -946,6 +978,14 @@ public class DNADraw extends ScrollPanel
   public void setLineAttributes(Hashtable lineAttr)
   {
     this.lineAttr = lineAttr;
+    
+    if(isCircular())
+    {
+      setSize(panelSize);
+      setPreferredSize(panelSize);
+    }
+    revalidate();
+    repaint();
   }
 
 
@@ -1037,7 +1077,7 @@ public class DNADraw extends ScrollPanel
       public void actionPerformed(ActionEvent e)
       {
         PrintDNAImage pdnai = new PrintDNAImage(current_dna);
-        pdnai.print();
+        pdnai.printAsSinglePage();
       }
     });
     printMenu.add(printImage);
@@ -1384,7 +1424,19 @@ public class DNADraw extends ScrollPanel
         repaint();
       }
     });
-    optionMenu.add(labelTick);
+    optionMenu.add(labelTick);  
+
+    final JCheckBoxMenuItem asCircular = new JCheckBoxMenuItem("Circular Plot", isCircular());
+    asCircular.addItemListener(new ItemListener()
+    {
+
+      public void itemStateChanged(ItemEvent e)
+      {
+        lineAttr.put("circular",new Boolean(asCircular.isSelected()));
+        setLineAttributes(lineAttr);
+      }
+    });
+    optionMenu.add(asCircular);
 
 // help manu
     JMenu helpMenu = new JMenu("Help");
@@ -1676,6 +1728,66 @@ public class DNADraw extends ScrollPanel
     //dna.add(dna.new BlockPanel(dna));
     f.setVisible(true);
   }
+
+
+  public int getBasesPerLine()
+  {
+    return basesPerLine;
+  }
+
+
+  public void setBasesPerLine(int basesPerLine)
+  {
+    this.basesPerLine = basesPerLine;
+  }
+
+
+  public int getNumberOfLines()
+  {
+    return numberOfLines;
+  }
+
+
+  public void setNumberOfLines(int numberOfLines)
+  {
+    this.numberOfLines = numberOfLines;
+  }
+
+
+  public float getLineHeight()
+  {
+    return lineHeight;
+  }
+
+
+  public void setLineHeight(float lineHeight)
+  {
+    this.lineHeight = lineHeight;
+  }
+
+
+  public float getSingleBaseWidth()
+  {
+    return singleBaseWidth;
+  }
+
+
+  public void setSingleBaseWidth(float singleBaseWidth)
+  {
+    this.singleBaseWidth = singleBaseWidth;
+  }
+
+
+  public int getBorder2()
+  {
+    return border2;
+  }
+
+
+  public void setBorder2(int border2)
+  {
+    this.border2 = border2;
+  }
   
   /*class BlockPanel extends JPanel
   {
diff --git a/uk/ac/sanger/artemis/circular/LineAttribute.java b/uk/ac/sanger/artemis/circular/LineAttribute.java
index 44e13845c..ae0e3b0c6 100644
--- a/uk/ac/sanger/artemis/circular/LineAttribute.java
+++ b/uk/ac/sanger/artemis/circular/LineAttribute.java
@@ -22,12 +22,14 @@
 package uk.ac.sanger.artemis.circular;
 
 import javax.swing.Box;
+import javax.swing.ButtonGroup;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
 import javax.swing.JPanel;
+import javax.swing.JRadioButton;
 import javax.swing.JSlider;
 import javax.swing.KeyStroke;
 import javax.swing.event.*;
@@ -37,6 +39,7 @@ import java.util.Hashtable;
 
 public class LineAttribute extends JPanel
 {
+  private static final long serialVersionUID = 1L;
   private Hashtable lineAttr = new Hashtable();
   private TextFieldInt start;
   private TextFieldInt end;
@@ -52,7 +55,7 @@ public class LineAttribute extends JPanel
     Box bacross = Box.createHorizontalBox();
 
     // circular or linear dna
-    /*ButtonGroup group = new ButtonGroup();
+    ButtonGroup group = new ButtonGroup();
     final JRadioButton jcirc = new JRadioButton("Circular");
     jcirc.addActionListener(new ActionListener()
     {
@@ -75,15 +78,16 @@ public class LineAttribute extends JPanel
       }
     });
     group.add(jline);
-    jcirc.setSelected(true);*/
-    lineAttr.put("circular",new Boolean(true));
-    /*bacross.add(jcirc); 
+    jcirc.setSelected( draw.isCircular() );
+    jline.setSelected( !draw.isCircular() );
+    lineAttr.put("circular",new Boolean(draw.isCircular()));
+    bacross.add(jcirc); 
     bacross.add(jline);
     bacross.add(Box.createHorizontalGlue());
     bdown.add(bacross);
 
     // start position
-    bdown.add(Box.createVerticalStrut(4));*/
+    bdown.add(Box.createVerticalStrut(4));
     bacross = Box.createHorizontalBox();
     start = new TextFieldInt();
     start.addActionListener(new ActionListener()
@@ -101,7 +105,7 @@ public class LineAttribute extends JPanel
     if(draw != null)
       start.setValue(draw.getStart());
     else
-      start.setValue(0);
+      start.setValue(1);
 
     start.setPreferredSize(d);
     start.setMaximumSize(d);
diff --git a/uk/ac/sanger/artemis/circular/PrintDNAImage.java b/uk/ac/sanger/artemis/circular/PrintDNAImage.java
index 8498e4410..a3683a7c3 100644
--- a/uk/ac/sanger/artemis/circular/PrintDNAImage.java
+++ b/uk/ac/sanger/artemis/circular/PrintDNAImage.java
@@ -27,6 +27,7 @@ import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.print.PageFormat;
+import java.awt.print.Paper;
 import java.awt.print.PrinterJob;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -35,7 +36,6 @@ import java.awt.image.BufferedImage;
 import java.awt.image.RenderedImage;
 import java.io.File;
 import java.io.IOException;
-import java.util.Hashtable;
 import javax.swing.BorderFactory;
 import javax.swing.Box;
 import javax.swing.JComboBox;
@@ -66,20 +66,15 @@ import javax.swing.border.Border;
 */
 public class PrintDNAImage extends ScrollPanel
 {
+  private static final long serialVersionUID = 1L;
+
   /** page format */
   private PageFormat format = null;
-  /** page number to print    */
-  private int pageIndex = 0;
+
   /** alignment sequence panel */
   private DNADraw dna;
-  /** prefix of file           */
-//private String filePrefix;
   /** status field for print preview */
   private JTextField statusField = new JTextField("");
-  /** number of residues per line    */
-  private int nResPerLine = 0;
-  /** line attributes */
-  private Hashtable lineAttr;
   /** type (jpeg/png) */
   private String type;
 
@@ -93,7 +88,6 @@ public class PrintDNAImage extends ScrollPanel
     super();
     this.dna = dna;
 
-    lineAttr = dna.getLineAttributes();
     setBackground(Color.white);
   }
 
@@ -118,7 +112,7 @@ public class PrintDNAImage extends ScrollPanel
   * Print to a jpeg or png file
   *
   */
-  public void print()
+/*  public void print()
   {
     if(format == null)
       getFormatDialog();
@@ -138,7 +132,7 @@ public class PrintDNAImage extends ScrollPanel
       JOptionPane.showMessageDialog(this,
             "This option requires Java 1.4 or higher.");
     }
-  }
+  }*/
 
 
   /**
@@ -236,7 +230,7 @@ public class PrintDNAImage extends ScrollPanel
     {
       public void actionPerformed(ActionEvent e)
       {
-        print();
+        printAsSinglePage();
       }
     });
     printMenu.add(printImage);
@@ -271,7 +265,7 @@ public class PrintDNAImage extends ScrollPanel
     String cwd = System.getProperty("user.dir");
     JFileChooser fc = new JFileChooser(cwd);
     File fselect = new File(cwd+System.getProperty("file.separator")+
-                            "dna_image.jpeg"); 
+                            "dna.jpg"); 
     fc.setSelectedFile(fselect);
 
 // file name prefix
@@ -287,6 +281,8 @@ public class PrintDNAImage extends ScrollPanel
     Box bacross = Box.createHorizontalBox();
     JComboBox formatSelect = 
        new JComboBox(javax.imageio.ImageIO.getWriterFormatNames());
+    formatSelect.setSelectedItem("jpg");
+    
     Dimension d = formatSelect.getPreferredSize();
     formatSelect.setMaximumSize(d);
     bacross.add(Box.createHorizontalGlue());
@@ -324,7 +320,42 @@ public class PrintDNAImage extends ScrollPanel
       System.out.println("Java 1.4+ is required");
     }
   }
+  
+  
+  
+
+  /**
+  * Print to one jpeg or png file
+  */
+  public void printAsSinglePage()
+  {
+    //PrinterJob printerJob = PrinterJob.getPrinterJob();
+    format = new PageFormat();
+
+    File file = showOptions();
+    
+    Dimension d = dna.getSize();
+    double imageWidth  = d.getWidth();
+    double imageHeight = d.getHeight();
+    Paper paper  = format.getPaper();
+
+    paper.setSize(imageWidth,imageHeight);
+
+    paper.setImageableArea(0,0,
+                           imageWidth,imageHeight+imageHeight);
+    format.setPaper(paper);
 
+    try
+    {
+      RenderedImage rendImage = createDNAImage(0);
+      writeImageToFile(rendImage,file,type);
+    }
+    catch(NoClassDefFoundError ex)
+    {
+      JOptionPane.showMessageDialog(this,
+            "This option requires Java 1.4 or higher.");
+    }
+  }
 
 }
 
-- 
GitLab