/* * Created on Feb 8, 2007 */ package org.seqcode.projects.seqview.components; import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import org.seqcode.genome.Genome; import org.seqcode.genome.location.Gene; import org.seqcode.genome.location.Region; import org.seqcode.gsebricks.GeneFactoryLoader; import org.seqcode.gsebricks.verbs.*; import org.seqcode.gsebricks.verbs.assignment.*; import java.io.File; import java.io.PrintWriter; public class RegionAnnotationPanel extends JPanel implements RegionList { private static GeneFactoryLoader geneFactoryLoader = new GeneFactoryLoader(); private Genome genome; private RegionToRegionAnnotations annotations; private OverlappingRegionExpander<Region> expander; private Expander<Region,Gene> lastgenerator; private JTextField upField, downField; private DefaultComboBoxModel geneSourceModel; private JComboBox geneSourceCombo; private DefaultListModel eventModel, geneModel; private JList eventList, geneList; private JButton annotateButton, saveLocationsButton, saveGenesButton, sortButton, saveGenesFastaButton, saveEventsFastaButton; private RegionPanel regionPanel; private Collection<Region> eventsToAdd, allEvents; private boolean changedevents; private JMenuBar jmb; private JFrame frame; private TaskRunnable taskRunnable; private LinkedList<Runnable> tasks; private class TaskRunnable implements Runnable { private boolean continueRunning; public TaskRunnable() { continueRunning = true; } public void stop() { continueRunning = false; } public void run() { while(continueRunning) { Runnable nextRunnable = null; synchronized(this) { nextRunnable = tasks.isEmpty() ? null : tasks.removeFirst(); if(nextRunnable == null) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } if(nextRunnable != null) { nextRunnable.run(); } } } private synchronized void waitOnMe() { } } private void addTaskedRunnable(Runnable r) { synchronized(taskRunnable) { tasks.addLast(r); taskRunnable.notifyAll(); } } public RegionAnnotationPanel(RegionPanel rp, Collection<Region> events) { super(); tasks = new LinkedList<Runnable>(); taskRunnable = new TaskRunnable(); Thread t = new Thread(taskRunnable); t.start(); regionPanel = rp; genome = rp.getGenome(); expander = null; allEvents = new ArrayList<Region>(); if (events != null) { allEvents.addAll(events); } eventsToAdd = new ArrayList<Region>(); changedevents = false; setLayout(new BorderLayout()); JPanel upPanel = new JPanel(); upPanel.setLayout(new BorderLayout()); upPanel.add(upField = new JTextField("8000"), BorderLayout.NORTH); upPanel.setBorder(new TitledBorder("Upstream:")); JPanel downPanel = new JPanel(); downPanel.setLayout(new BorderLayout()); downPanel.add(downField = new JTextField("2000"), BorderLayout.NORTH); downPanel.setBorder(new TitledBorder("Downstream:")); geneSourceModel = new DefaultComboBoxModel(); geneSourceCombo = new JComboBox(geneSourceModel); JPanel sourcePanel = new JPanel(); sourcePanel.setLayout(new BorderLayout()); sourcePanel.add(geneSourceCombo, BorderLayout.NORTH); sourcePanel.setBorder(new TitledBorder("Gene Source:")); JPanel paramPanel = new JPanel(); paramPanel.setLayout(new GridLayout(1, 3)); paramPanel.add(upPanel); paramPanel.add(downPanel); paramPanel.add(sourcePanel); add(paramPanel, BorderLayout.NORTH); eventModel = new DefaultListModel(); geneModel = new DefaultListModel(); eventList = new JList(eventModel); geneList = new JList(geneModel); JPanel genePanel = new JPanel(); genePanel.setLayout(new BorderLayout()); genePanel.add(new JScrollPane(geneList), BorderLayout.CENTER); genePanel.setBorder(new TitledBorder("Genes:")); JPanel eventPanel = new JPanel(); eventPanel.setLayout(new BorderLayout()); eventPanel.add(new JScrollPane(eventList), BorderLayout.CENTER); eventPanel.setBorder(new TitledBorder("Binding Events:")); JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPane.add(eventPanel, JSplitPane.LEFT); splitPane.add(genePanel, JSplitPane.RIGHT); add(splitPane, BorderLayout.CENTER); final RegionAnnotationPanel caller = this; jmb = new JMenuBar(); JMenu fileMenu = new JMenu("File"); JMenuItem item = new JMenuItem("Save Locations"); fileMenu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { caller.saveLocations(); } }); item = new JMenuItem("Save Genes"); fileMenu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { caller.saveGenes(); } }); item = new JMenuItem("Save Locations as FASTA"); fileMenu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ArrayList<Region> regions = new ArrayList<Region>(); for (int i = 0; i < eventModel.size(); i++) { regions.add((Region)eventModel.get(i)); } new SaveRegionsAsFasta(regions); } }); item = new JMenuItem("Save Genes as FASTA"); fileMenu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ArrayList<Region> regions = new ArrayList<Region>(); for (int i = 0; i < geneModel.size(); i++) { regions.add((Region)geneModel.get(i)); } new SaveRegionsAsFasta(regions); } }); item = new JMenuItem("Close"); fileMenu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ frame.dispose(); } }); JMenu annotMenu = new JMenu("Annotate"); item = new JMenuItem("Get Genes"); annotMenu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Runnable r = new Runnable() { public void run() { annotate(); } }; addTaskedRunnable(r); } }); JMenu sortMenu = new JMenu("Sorting"); item = new JMenuItem("Sort Genes"); sortMenu.add(item); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { caller.sortGenes(); } }); jmb.add(fileMenu); jmb.add(annotMenu); jmb.add(sortMenu); TreeSet<String> sources = new TreeSet<String>(geneFactoryLoader.getTypes(genome)); String first = null; for(String source : sources) { if(first == null) { first = source; } geneSourceModel.addElement(source); } if(first != null) { geneSourceModel.setSelectedItem(first); } for(Region event : allEvents) { eventModel.addElement(event); } eventList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { int row = eventList.locationToIndex(e.getPoint()); Region region = (Region)eventModel.get(row); if(region != null && regionPanel != null) { Region existing = regionPanel.getRegion(); int halfsize = Math.abs(existing.getEnd() - existing.getStart()) / 2; int center = Math.abs(region.getEnd() + region.getStart()) / 2; regionPanel.setRegion(new Region(region.getGenome(),region.getChrom(),center - halfsize, center + halfsize)); } } } }); geneList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { int row = geneList.locationToIndex(e.getPoint()); Region region = (Region)geneModel.get(row); if(region != null && regionPanel != null) { regionPanel.setRegion(region); } } } }); } public JMenuBar getMenuBar() { return jmb; } public void addRegion(Region r) { allEvents.add(r); changedevents = true; synchronized (eventsToAdd) { eventsToAdd.add(r); } SwingUtilities.invokeLater(new ListModelAdder(eventsToAdd,eventModel)); } public int regionListSize() {return eventModel.size();} public Region regionAt(int i) {return (Region)eventModel.getElementAt(i);} public RegionToRegionAnnotations getAnnotations(JProgressBar pbar) { if (expander == null || changedevents) { expander = new OverlappingRegionExpander<Region>(allEvents); changedevents = false; } RegionToRegionAnnotations result = new RegionToRegionAnnotations(genome, (Expander<Region,Region>)expander, pbar); lastgenerator = result.getGeneGenerator(); return result; } public void annotate() { System.out.println("Annotating: \"annotate()\" called."); clearGenes(); JFrame progressFrame = new JFrame(); JProgressBar bar = new JProgressBar(0,1); bar.setValue(0); bar.setStringPainted(true); Container cnt = (Container)progressFrame.getContentPane(); cnt.setLayout(new GridLayout(2, 1)); cnt.add(new JLabel("Annotating Genes...")); cnt.add(bar); progressFrame.setVisible(true); progressFrame.pack(); RegionToRegionAnnotations annotations = getAnnotations(bar); progressFrame.dispose(); System.err.println("Annotating " + annotations.getNumItems()); ArrayList targets = new ArrayList(); for(int i = 0; i < annotations.getNumItems(); i++) { Region event = annotations.getItem(i); targets.addAll(annotations.getAnnotations(event, "genes")); } SwingUtilities.invokeLater(new ListModelAdder(targets,geneModel)); } public void sortGenes() { Object[] genes = new Object[geneModel.size()]; geneModel.copyInto(genes); Arrays.sort(genes,new GeneorRegionComparator()); clearGenes(); SwingUtilities.invokeLater(new ListModelAdder(genes,geneModel)); } public void saveLocations() { JFileChooser chooser; chooser = new JFileChooser(new File(System.getProperty("user.dir"))); int v = chooser.showSaveDialog(null); if(v == JFileChooser.APPROVE_OPTION) { try { File f = chooser.getSelectedFile(); PrintWriter writer = new PrintWriter(f); for (int i = 0; i < eventModel.getSize(); i++) { writer.println(eventModel.get(i).toString()); } writer.close(); } catch (Exception ex) { ex.printStackTrace(); } } } public void saveGenes() { JFileChooser chooser; chooser = new JFileChooser(new File(System.getProperty("user.dir"))); int v = chooser.showSaveDialog(null); if(v == JFileChooser.APPROVE_OPTION) { try { File f = chooser.getSelectedFile(); PrintWriter writer = new PrintWriter(f); for (int i = 0; i < geneModel.getSize(); i++) { writer.println(geneModel.get(i).toString()); } writer.close(); } catch (Exception ex) { ex.printStackTrace(); } } } public void clearGenes() { geneModel.clear(); } public static class Frame extends JFrame { private RegionAnnotationPanel annotationPanel; public Frame(RegionAnnotationPanel bea) { super("Region Annotations"); bea.frame = this; annotationPanel = bea; setJMenuBar(bea.getMenuBar()); Container c = (Container)getContentPane(); c.setLayout(new BorderLayout()); c.add(annotationPanel, BorderLayout.CENTER); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); pack(); setVisible(true); } } }