package com.github.lindenb.jvarkit.tools.batchpicts; import htsjdk.samtools.util.CloserUtil; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.prefs.Preferences; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import com.github.lindenb.jvarkit.io.IOUtils; import com.github.lindenb.jvarkit.io.NullOuputStream; import com.github.lindenb.jvarkit.util.htsjdk.HtsjdkVersion; import com.github.lindenb.jvarkit.util.igv.IgvSocket; import com.github.lindenb.jvarkit.util.jcommander.Launcher; import com.github.lindenb.jvarkit.util.jcommander.Program; import com.github.lindenb.jvarkit.util.log.Logger; /* BEGIN_DOC ## Motivation Takes IGV pictures in batch. Save as HTML+png images or OpenOffice/ODP. ## Screenshot ![screenshot](http://i.imgur.com/pasROkt.jpg) END_DOC */ @SuppressWarnings("serial") @Program(name="batchigvpictures", description="Takes IGV pictures in batch. Save as HTML+png image", keywords={"gui","igv","visualization"} ) class BatchIGVPicturesFrame extends JFrame { private static final String PREF_EXTEND="snp.extend"; private static final String PREF_IGV_PORT="igv.port"; private static final String PREF_IGV_HOST="igv.host"; private static final String PREF_SAVE_AS_FILE="save.as.file"; private static final String PREF_IMG_WIDTH="img.width"; private static final String PREF_LOAD_VCF_FILE="load.vcf.file"; private static final String PREF_IGV_SLEEP="igv.sleep"; private static final String PREF_FORMAT="out.fmt"; private static final int FORMAT_HTML=0; private static final int FORMAT_PPT=1; String about=""; private Preferences preferences; private AbstractSlave currentSlave=null; private JTextArea snpArea; private SpinnerNumberModel spinnerExtendSize; private SpinnerNumberModel spinnerImageWidth; private SpinnerNumberModel spinnerIgvWait; private JTextField tfIgvHost; private SpinnerNumberModel spinnerIgvPort; private JLabel progressLbl=null; private JComboBox<String> cboxFormat; private static class Mutation implements Comparable<Mutation> { String chrom; int position; @Override public int compareTo(Mutation o) { int i=chrom.compareTo(o.chrom); if(i!=0) return i; return position-o.position; } @Override public boolean equals(Object obj) { if(this==obj) return true; return compareTo(Mutation.class.cast(obj))==0; } @Override public int hashCode() { return chrom.hashCode()*31+position; } @Override public String toString() { return chrom+":"+position; } } private abstract class AbstractSlave extends Thread { String pathOut; int igvPort; String igvHost; int extend; int imageWidth; int waitMiliSecs; Set<Mutation> mutations=new TreeSet<Mutation>(); protected void log(final String labelStr) { try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { progressLbl.setText(labelStr); } }); } catch (Exception e) { } } protected IgvSocket createIgvSocket() { IgvSocket igvSocket=new IgvSocket(); igvSocket.setHost(this.igvHost); igvSocket.setPort(this.igvPort); return igvSocket; } protected BufferedImage scale(File pngFile) throws IOException { BufferedImage src=ImageIO.read(pngFile); if(src==null) { throw new IOException("Cannot read Image "+pngFile.getName()); } BufferedImage dest=new BufferedImage( this.imageWidth, (int)((this.imageWidth/(double)src.getWidth())*src.getHeight()), src.getType() ); Graphics2D g=(Graphics2D)dest.getGraphics(); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.drawImage(src, 0, 0, dest.getWidth(), dest.getHeight(), null); g.dispose(); return dest; } } private class HtmlSlave extends AbstractSlave { @Override public void run() { File baseFile=new File(pathOut); File resultFileOut=new File(pathOut+".html"); File pngFile=null; PrintWriter out =null; BufferedReader in =null; XMLStreamWriter w=null; FileOutputStream fout=null; IgvSocket igvSocket=null; PrintWriter igvLog=null; try { XMLOutputFactory xof=XMLOutputFactory.newFactory(); igvLog=new PrintWriter(new NullOuputStream()); fout=new FileOutputStream(resultFileOut); w=xof.createXMLStreamWriter(fout, "UTF-8"); w.writeStartElement("html"); w.writeStartElement("body"); pngFile=File.createTempFile("igv_", ".png"); igvSocket=createIgvSocket(); out=igvSocket.getWriter(); in=igvSocket.getReader(); out.println("snapshotDirectory "+pngFile.getParentFile()); igvLog.println(in.readLine()); out.println("setSleepInterval "+(waitMiliSecs+1)); igvLog.println(in.readLine()); int index=0; for(Mutation m:this.mutations) { if(this!=BatchIGVPicturesFrame.this.currentSlave) break; log("Drawing "+(++index)+"/"+this.mutations.size()+" "+m); int chromStart= Math.max(1,m.position - extend); int chromEnd = m.position + extend; out.println("goto "+m.chrom+":"+chromStart+"-"+chromEnd); out.flush(); igvLog.println(in.readLine()); out.println("snapshot "+pngFile.getName()); out.flush(); igvLog.println(in.readLine()); BufferedImage dest=scale(pngFile); String imgName=baseFile.getName()+"_"+m.chrom+"_"+m.position+".png"; w.writeStartElement("h3"); w.writeCharacters(m.toString()); w.writeEndElement(); w.writeEmptyElement("img"); w.writeAttribute("src",imgName); w.writeAttribute("alt",m.toString()); w.writeAttribute("width",String.valueOf(dest.getWidth())); w.writeAttribute("height",String.valueOf(dest.getHeight())); File destScaledImage=new File(baseFile.getParentFile(),imgName); ImageIO.write(dest, "png",destScaledImage); dest=null; log("Sleep "+waitMiliSecs+" millisecs..."); Thread.sleep(waitMiliSecs); } log("Done."); w.writeEmptyElement("hr"); w.writeStartElement("div"); w.writeCharacters(about); w.writeEndElement();//div w.writeEndElement();//body w.writeEndElement();//html w.flush(); fout.flush(); } catch (Exception e) { e.printStackTrace(); log("Error "+e.getMessage()); } finally { CloserUtil.close(igvSocket); CloserUtil.close(out); CloserUtil.close(in); CloserUtil.close(w); CloserUtil.close(fout); CloserUtil.close(igvLog); pngFile.delete(); } } } /** save image as OpenOffice Presentation */ private class PPTSlave extends AbstractSlave { private class PictAndMut { Mutation mut; String file; Dimension dim; } private InputStream openODPResource(String filename) throws IOException { filename="META-INF/opendocument/odp/"+filename;//no head '/' Enumeration<URL> resources = getClass().getClassLoader() .getResources(filename); while (resources.hasMoreElements()) { URL url=resources.nextElement(); InputStream in=url.openStream(); if(in!=null) return in; } throw new IOException("Cannot open resource:"+filename); } private void copyODPResource( ZipOutputStream zout, String filename, String outname) throws IOException { ZipEntry zentry=new ZipEntry(outname); zout.putNextEntry(zentry); InputStream is=openODPResource(filename); IOUtils.copyTo(is, zout); zout.flush(); is.close(); zout.closeEntry(); } private void copyODPResource( ZipOutputStream zout, String filename) throws IOException { copyODPResource(zout,filename,filename); } private String odpns(String localname) { return "urn:oasis:names:tc:opendocument:xmlns:"+localname+":1.0"; } @Override public void run() { File resultFileOut=new File(pathOut+".odp"); File pngFile=null; PrintWriter igvout =null; BufferedReader igvin =null; FileOutputStream fout=null; ZipOutputStream zout=null; IgvSocket igvSocket=null; PrintWriter igvLog=null; List<PictAndMut> pictures=new ArrayList<PictAndMut>(this.mutations.size()); try { igvLog=new PrintWriter(new NullOuputStream()); fout=new FileOutputStream(resultFileOut); zout=new ZipOutputStream(fout); pngFile=File.createTempFile("igv_", ".png"); igvSocket=createIgvSocket(); igvout=igvSocket.getWriter(); igvin=igvSocket.getReader(); igvout.println("snapshotDirectory "+pngFile.getParentFile()); igvLog.println(igvin.readLine()); igvout.println("setSleepInterval "+(waitMiliSecs+1)); igvLog.println(igvin.readLine()); copyODPResource(zout,"mimetype"); copyODPResource(zout,"meta.xml"); copyODPResource(zout,"settings.xml"); int index=0; for(Mutation m:this.mutations) { if(this!=BatchIGVPicturesFrame.this.currentSlave) break; log("Drawing "+(++index)+"/"+this.mutations.size()+" "+m); int chromStart= Math.max(1,m.position - extend); int chromEnd = m.position + extend; igvout.println("goto "+m.chrom+":"+chromStart+"-"+chromEnd); igvout.flush(); igvLog.println(igvin.readLine()); igvout.println("snapshot "+pngFile.getName()); igvout.flush(); igvLog.println(igvin.readLine()); BufferedImage dest=scale(pngFile); String entryName="Pictures/"+m.chrom+"_"+m.position+".png"; PictAndMut pam=new PictAndMut(); pam.dim=new Dimension(dest.getWidth(), dest.getHeight()); pam.mut=m; pam.file=entryName; pictures.add(pam); ZipEntry zentry=new ZipEntry(entryName); zout.putNextEntry(zentry); ImageIO.write(dest, "png",zout); zout.closeEntry(); dest=null; dest=null; log("Sleep "+waitMiliSecs+" millisecs..."); Thread.sleep(waitMiliSecs); } CloserUtil.close(igvout);igvout=null; CloserUtil.close(igvin);igvin=null; CloserUtil.close(igvSocket);igvSocket=null; { /* content.xml */ ZipEntry zentry=new ZipEntry("content.xml"); zout.putNextEntry(zentry); InputStream is=openODPResource("content.xml"); XMLOutputFactory xof=XMLOutputFactory.newFactory(); XMLInputFactory xif=XMLInputFactory.newFactory(); XMLEventReader xi=xif.createXMLEventReader(is); XMLEventWriter xw=xof.createXMLEventWriter(zout); while(xi.hasNext()) { XMLEvent evt=xi.nextEvent(); xw.add(evt); if(evt.isStartElement()) { StartElement SE=evt.asStartElement(); QName qName=SE.getName(); if(qName.getLocalPart().equals("presentation") && qName.getNamespaceURI().equals(odpns("office"))) { XMLEventFactory xef=XMLEventFactory.newFactory(); ArrayList<Attribute> attributes; ArrayList<Namespace> namespaces; for(PictAndMut pam:pictures) { final String XLINK="http://www.w3.org/1999/xlink"; attributes=new ArrayList<Attribute>(); namespaces=new ArrayList<Namespace>(); attributes.add(xef.createAttribute("draw",odpns("drawing"),"master-page-name","")); evt=xef.createStartElement("draw",odpns("drawing"),"page",attributes.iterator(),namespaces.iterator()); xw.add(evt); attributes=new ArrayList<Attribute>(); namespaces=new ArrayList<Namespace>(); attributes.add(xef.createAttribute("presentation",odpns("presentation"),"style-name","")); double width_cm=20.0; double height_cm= (width_cm/pam.dim.width)*pam.dim.getHeight(); attributes.add(xef.createAttribute("svg",odpns("svg-compatible"),"width",""+width_cm+"cm")); attributes.add(xef.createAttribute("svg",odpns("svg-compatible"),"height",""+height_cm+"cm")); attributes.add(xef.createAttribute("svg",odpns("svg-compatible"),"x","0cm")); attributes.add(xef.createAttribute("svg",odpns("svg-compatible"),"y","0cm")); attributes.add(xef.createAttribute("presentation",odpns("presentation"),"class","title")); evt=xef.createStartElement("draw",odpns("drawing"),"frame",attributes.iterator(),namespaces.iterator()); xw.add(evt); attributes=new ArrayList<Attribute>(); namespaces=new ArrayList<Namespace>(); attributes.add(xef.createAttribute("xlink",XLINK,"type","simple")); attributes.add(xef.createAttribute("xlink",XLINK,"show","embed")); attributes.add(xef.createAttribute("xlink",XLINK,"actuate","onLoad")); attributes.add(xef.createAttribute("xlink",XLINK,"href",pam.file)); evt=xef.createStartElement("draw",odpns("drawing"),"image",attributes.iterator(),namespaces.iterator()); xw.add(evt); attributes=new ArrayList<Attribute>(); namespaces=new ArrayList<Namespace>(); evt=xef.createStartElement("text",odpns("text"),"p",attributes.iterator(),namespaces.iterator()); xw.add(evt); xw.add(xef.createCharacters(pam.mut.toString())); evt=xef.createEndElement("text",odpns("text"),"p"); xw.add(evt); evt=xef.createEndElement("draw",odpns("drawing"),"image"); xw.add(evt); evt=xef.createEndElement("draw",odpns("drawing"),"frame"); xw.add(evt); evt=xef.createEndElement("draw",odpns("drawing"),"page"); xw.add(evt); } } } } xw.flush(); xi.close(); is.close(); zout.closeEntry(); } copyODPResource(zout,"thumbnail.png","Thumbnails/thumbnail.png"); copyODPResource(zout,"styles.xml"); //copyODPResource(zout,"manifest.xml","META-INF/manifest.xml"); { /* content.xml */ ZipEntry zentry=new ZipEntry("META-INF/manifest.xml"); zout.putNextEntry(zentry); PrintWriter pw=new PrintWriter(zout); pw.println( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+ "<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\" manifest:version=\"1.2\">\n"+ " <manifest:file-entry manifest:full-path=\"/\" manifest:version=\"1.2\" manifest:media-type=\"application/vnd.oasis.opendocument.presentation\"/>\n"+ " <manifest:file-entry manifest:full-path=\"meta.xml\" manifest:media-type=\"text/xml\"/>\n"); for(PictAndMut pam:pictures) { pw.println(" <manifest:file-entry manifest:full-path=\""+ pam.file+ "\" manifest:media-type=\"image/png\"/>\n"); } pw.print( " <manifest:file-entry manifest:full-path=\"settings.xml\" manifest:media-type=\"text/xml\"/>\n"+ " <manifest:file-entry manifest:full-path=\"content.xml\" manifest:media-type=\"text/xml\"/>\n"+ " <manifest:file-entry manifest:full-path=\"Thumbnails/thumbnail.png\" manifest:media-type=\"image/png\"/>\n"+ " <manifest:file-entry manifest:full-path=\"Configurations2/accelerator/current.xml\" manifest:media-type=\"\"/>\n"+ " <manifest:file-entry manifest:full-path=\"Configurations2/\" manifest:media-type=\"application/vnd.sun.xml.ui.configuration\"/>\n"+ " <manifest:file-entry manifest:full-path=\"styles.xml\" manifest:media-type=\"text/xml\"/>\n"+ "</manifest:manifest>"); pw.flush(); /* InputStream is=openODPResource("manifest.xml"); XMLOutputFactory xof=XMLOutputFactory.newFactory(); XMLInputFactory xif=XMLInputFactory.newFactory(); XMLEventReader xi=xif.createXMLEventReader(is); XMLEventWriter xw=xof.createXMLEventWriter(zout); boolean seen=false; while(xi.hasNext()) { XMLEvent evt=xi.nextEvent(); xw.add(evt); if(!seen && evt.isStartElement()) { StartElement SE=evt.asStartElement(); QName qName=SE.getName(); if(qName.getLocalPart().equals("file-entry") && qName.getNamespaceURI().equals(odpns("manifest"))) { seen=true; XMLEventFactory xef=XMLEventFactory.newFactory(); ArrayList<Attribute> attributes; ArrayList<Namespace> namespaces; for(PictAndMut pam:pictures) { attributes=new ArrayList<Attribute>(); namespaces=new ArrayList<Namespace>(); attributes.add(xef.createAttribute("manifest",odpns("manifest"),"full-path",pam.file)); attributes.add(xef.createAttribute("manifest",odpns("manifest"),"media-type","image/png")); evt=xef.createStartElement("manifest",odpns("manifest"),"file-entry",attributes.iterator(),namespaces.iterator()); xw.add(evt); evt=xef.createEndElement("manifest",odpns("manifest"),"file-entry"); xw.add(evt); } } } } xw.flush(); xi.close(); is.close(); */ zout.closeEntry(); } log("Done."); zout.flush(); zout.finish(); } catch (Exception e) { e.printStackTrace(); log("Error "+e.getMessage()); } finally { CloserUtil.close(igvSocket); CloserUtil.close(igvout); CloserUtil.close(igvin); CloserUtil.close(zout); CloserUtil.close(fout); CloserUtil.close(igvLog); pngFile.delete(); } } } BatchIGVPicturesFrame() { setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); try { this.preferences=Preferences.userNodeForPackage(BatchIGVPictures.class); } catch (Exception e) { } addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { doMenuClose(); } }); JMenuBar menubar=new JMenuBar(); setJMenuBar(menubar); JMenu menu=new JMenu("File"); menubar.add(menu); menu.add(new AbstractAction("Quit") { @Override public void actionPerformed(ActionEvent e) { doMenuClose(); } }); menu=new JMenu("Help"); menubar.add(menu); menu.add(new AbstractAction("About") { @Override public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(BatchIGVPicturesFrame.this, about); } }); JPanel contentPane=new JPanel(new BorderLayout(5, 5)); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); JPanel top0=new JPanel(new GridLayout(0,1,5,5)); contentPane.add(top0,BorderLayout.NORTH); JPanel top=new JPanel(new FlowLayout(FlowLayout.LEADING)); top0.add(top); /* extend */ JLabel lbl=new JLabel("Position Extend:",JLabel.RIGHT); top.add(lbl); JSpinner spin=new JSpinner(this.spinnerExtendSize=new SpinnerNumberModel( preferences.getInt(PREF_EXTEND, 10), 1, 100, 1)); lbl.setLabelFor(spin); top.add(spin); this.spinnerExtendSize.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { preferences.putInt(PREF_EXTEND,SpinnerNumberModel.class.cast(e.getSource()).getNumber().intValue()); } }); /* image width */ lbl=new JLabel("Image Width:",JLabel.RIGHT); top.add(lbl); spin=new JSpinner(this.spinnerImageWidth=new SpinnerNumberModel( preferences.getInt(PREF_IMG_WIDTH, 640), 1, 2000, 1)); lbl.setLabelFor(spin); top.add(spin); this.spinnerImageWidth.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { preferences.putInt(PREF_IMG_WIDTH,SpinnerNumberModel.class.cast(e.getSource()).getNumber().intValue()); } }); /* image width */ lbl=new JLabel("Wait ms:",JLabel.RIGHT); top.add(lbl); spin=new JSpinner(this.spinnerIgvWait=new SpinnerNumberModel( preferences.getInt(PREF_IGV_SLEEP, 100), 1, 10000, 1)); lbl.setLabelFor(spin); top.add(spin); this.spinnerIgvWait.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { preferences.putInt(PREF_IMG_WIDTH,SpinnerNumberModel.class.cast(e.getSource()).getNumber().intValue()); } }); /* IGV Host */ lbl=new JLabel("IGV Host:",JLabel.RIGHT); top.add(lbl); this.tfIgvHost = new JTextField( preferences.get(PREF_IGV_HOST,IgvSocket.DEFAULT_HOST),8); top.add(this.tfIgvHost); this.tfIgvHost.getDocument().addDocumentListener(new DocumentListener() { @Override public void removeUpdate(DocumentEvent e) { changedUpdate(e); } @Override public void insertUpdate(DocumentEvent e) { changedUpdate(e); } @Override public void changedUpdate(DocumentEvent e) { String s; try { s = e.getDocument().getText(0, e.getDocument().getLength()).trim(); preferences.put(PREF_IGV_HOST,s); } catch (BadLocationException e1) { e1.printStackTrace(); } } }); /* IGV port */ lbl=new JLabel("IGV PORT:",JLabel.RIGHT); top.add(lbl); spin=new JSpinner(this.spinnerIgvPort=new SpinnerNumberModel( preferences.getInt(PREF_IGV_PORT, IgvSocket.DEFAULT_PORT), 1, 1000000, 1)); lbl.setLabelFor(spin); top.add(spin); this.spinnerIgvPort.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { preferences.putInt(PREF_IGV_PORT,SpinnerNumberModel.class.cast(e.getSource()).getNumber().intValue()); } }); top=new JPanel(new FlowLayout(FlowLayout.LEADING)); top0.add(top); /* FORMAT */ lbl=new JLabel("Format:",JLabel.RIGHT); top.add(lbl); this.cboxFormat =new JComboBox<String>(new String[]{"HTML","PPT/ODP"}); this.cboxFormat.setSelectedIndex(preferences.getInt(PREF_FORMAT, FORMAT_HTML)); lbl.setLabelFor(this.cboxFormat); top.add(this.cboxFormat); this.cboxFormat.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { preferences.putInt(PREF_FORMAT,Math.max(cboxFormat.getSelectedIndex(),0)); } }); /* paint */ JButton but=new JButton(new AbstractAction("Load Mutation File") { @Override public void actionPerformed(ActionEvent e) { loadVCF(); } }); top.add(but); but=new JButton(new AbstractAction("Stop") { @Override public void actionPerformed(ActionEvent e) { stopPaint(); } }); but.setFont(new Font("Dialog",Font.BOLD,18)); but.setBackground(Color.RED); but.setForeground(Color.WHITE); top.add(but); but=new JButton(new AbstractAction("Draw") { @Override public void actionPerformed(ActionEvent e) { doMenuPaint(); } }); but.setFont(new Font("Dialog",Font.BOLD,18)); but.setBackground(Color.GREEN); but.setForeground(Color.WHITE); top.add(but); JPanel pane2=new JPanel(new BorderLayout(5,5)); contentPane.add(pane2,BorderLayout.CENTER); pane2.add(new JScrollPane(this.snpArea=new JTextArea(10,80)),BorderLayout.CENTER); pane2.setBorder(new TitledBorder("SNP: CHROM(tab)POSITION")); /* this.snpArea.setText( "chr6\t85356177\n"+ "chr6\t85356228\n"+ "chr6\t85356328\n" ); */ this.progressLbl=new JLabel(""); contentPane.add(this.progressLbl,BorderLayout.SOUTH); } private void stopPaint() { if(this.currentSlave!=null) { try { this.currentSlave.interrupt(); } catch (Exception e) { } } this.currentSlave=null; this.progressLbl.setText(""); } private void doMenuClose() { stopPaint(); try { this.preferences.flush(); } catch(Exception err) { } this.setVisible(false); this.dispose(); } private void loadVCF() { String prevFile=this.preferences.get(PREF_LOAD_VCF_FILE, null); File selFile=prevFile==null?null:new File(prevFile); JFileChooser fc=new JFileChooser(); if(selFile!=null) { fc.setSelectedFile(selFile); } if(fc.showOpenDialog(this)!=JFileChooser.APPROVE_OPTION) { return ; } BufferedReader r=null; try { r=IOUtils.openFileForBufferedReading(fc.getSelectedFile()); Set<Mutation> mutations=this.loadMutations(r); StringWriter sw=new StringWriter(); for(Mutation m:mutations) { sw.write(m.chrom+"\t"+m.position+"\n"); } this.snpArea.setText(sw.toString()); this.snpArea.setCaretPosition(0); this.preferences.put(PREF_LOAD_VCF_FILE, fc.getSelectedFile().getPath()); } catch(Exception err) { JOptionPane.showMessageDialog(this, "Cannot pars data in "+fc.getSelectedFile()+" "+err.getMessage()); } finally { CloserUtil.close(r); } } private Set<Mutation> loadMutations(Reader reader) throws IOException { Set<Mutation> mutations=new TreeSet<Mutation>(); BufferedReader in=new BufferedReader(reader); String line; while(((line=in.readLine()))!=null) { if(line.isEmpty() || line.startsWith("#")) continue; String tokens[]=line.split("[\t]",3); if(tokens.length<2) throw new IOException("Bad line "+line); Mutation m=new Mutation(); m.chrom=tokens[0].trim(); if(!m.chrom.matches("[A-Z0-9a-z_\\.]+")) { throw new IOException("Bad chrom in "+line); } try { m.position=Integer.parseInt(tokens[1].replace(",", "").replace(".", "")); } catch (Exception e) { throw new IOException("Bad Position in in "+line); } if(m.position<0) throw new IOException("Bad Position in in "+line); mutations.add(m); } return mutations; } private void doMenuPaint() { stopPaint(); int fotmat=Math.max(this.cboxFormat.getSelectedIndex(),0); this.currentSlave=null; if(fotmat==FORMAT_HTML) { this.currentSlave=new HtmlSlave(); } else { this.currentSlave=new PPTSlave(); } this.currentSlave.igvHost= this.tfIgvHost.getText().trim(); this.currentSlave.igvPort= this.spinnerIgvPort.getNumber().intValue(); this.currentSlave.extend= this.spinnerExtendSize.getNumber().intValue(); this.currentSlave.imageWidth=this.spinnerImageWidth.getNumber().intValue(); this.currentSlave.waitMiliSecs=this.spinnerIgvWait.getNumber().intValue(); try { this.currentSlave.mutations=loadMutations(new StringReader(this.snpArea.getText())); } catch (Exception e) { JOptionPane.showMessageDialog(this,"Cannot parse SNPs area:"+e.getMessage()); stopPaint(); return; } if(this.currentSlave.mutations.isEmpty()) { stopPaint(); return; } File file=null; String fileStr=this.preferences.get(PREF_SAVE_AS_FILE, null); if(fileStr!=null) { file=new File(fileStr); } JFileChooser chooser=new JFileChooser(file!=null?file.getParentFile():null); if(file!=null ) { chooser.setSelectedFile(file); } if(chooser.showSaveDialog(this)!=JFileChooser.APPROVE_OPTION) { return; } File selectedFile=chooser.getSelectedFile(); this.currentSlave.pathOut=selectedFile.getPath(); this.preferences.put(PREF_SAVE_AS_FILE, selectedFile.getPath()); if(fotmat==FORMAT_HTML) { if(this.currentSlave.pathOut.endsWith(".html")) { this.currentSlave.pathOut=this.currentSlave.pathOut.substring(0,this.currentSlave.pathOut.length()-5); } else if(this.currentSlave.pathOut.endsWith(".htm")) { this.currentSlave.pathOut=this.currentSlave.pathOut.substring(0,this.currentSlave.pathOut.length()-4); } selectedFile=new File(this.currentSlave.pathOut+".html"); } else if(fotmat==FORMAT_PPT) { if(this.currentSlave.pathOut.endsWith(".odp")) { this.currentSlave.pathOut=this.currentSlave.pathOut.substring(0,this.currentSlave.pathOut.length()-4); } selectedFile=new File(this.currentSlave.pathOut+".odp"); } else { throw new IllegalStateException(); } if(selectedFile!=null && selectedFile.exists() && JOptionPane.showConfirmDialog(this, selectedFile.toString()+" already exists. Overwrite ?", "Overwrite", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null)!=JOptionPane.OK_OPTION ) { stopPaint(); return; } this.currentSlave.start(); } } public class BatchIGVPictures extends Launcher { private static final Logger LOG=Logger.build(BatchIGVPictures.class).make(); @Override public int doWork(final List<String> args) { final BatchIGVPicturesFrame app=new BatchIGVPicturesFrame(); app.about=" Author: Pierre Lindenbaum "+ " Version:"+getVersion()+ " Htsjdk.version:"+HtsjdkVersion.getVersion()+ " Date:"+getCompileDate() ; try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { Dimension win=Toolkit.getDefaultToolkit().getScreenSize(); app.setTitle(getProgramName()); app.pack(); Dimension ps=app.getPreferredSize(); app.setLocation( (win.width-ps.width)/2, (win.height-ps.height)/2 ); app.setVisible(true); } }); return RETURN_OK; } catch(Exception err) { LOG.error(err); return -1; } finally { } } public static void main(String[] args) { new BatchIGVPictures().instanceMain(args); } }