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