package moduls.frm.children; import genomeObjects.AnnotatedGenome; import genomeObjects.ContextSet; import genomeObjects.ContextSetDescription; import genomeObjects.GenomicElement; import genomeObjects.MotifGroup; import genomeObjects.MotifGroupDescription; import genomeObjects.SequenceMotif; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Dialog.ModalityType; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.LinkedHashMap; import java.util.LinkedList; import javax.swing.ButtonGroup; import javax.swing.ButtonModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.SwingWorker; import org.biojava3.core.sequence.*; import moduls.frm.FrmPrincipalDesk; import moduls.frm.children.manageContextSetsv2.btnLoadCS; public class ManageMotifs extends JDialog implements ActionListener, PropertyChangeListener{ //Fields //Management private FrmPrincipalDesk f; private String[] SequenceMotifsAsArray; private LinkedList<String> SequenceMotifsAsList; private ButtonGroup MSType; private LinkedHashMap<ButtonModel, LinkedList<Component>> RadioButtonComponents = new LinkedHashMap<ButtonModel, LinkedList<Component>>(); private boolean AcceptableName = true; private boolean MotifFilesLoaded = false; private MotifGroupDescription ToAdd; //File import private File ReferenceDirectory = null; private File[] MotifFiles; private boolean isFile = false; private File SingleFile = null; //GUI //general use private JPanel jp; private JProgressBar progressBar; //insets private Insets IndentInsets = new Insets(1,20,1,1); private Insets NewSectionInsets = new Insets(10,1,1,1); //Associate motifs with genomic elements private LinkedList<Component> FindAssociationGroup; private JCheckBox chkAssociate; private String strAssociate = "Associate imported motifs with genomic elements"; private JRadioButton radNextDownstream, radWithinRange; private ButtonGroup GrpAssociateMotifs; private String strNextDownstream = "Associate motif with the next downstream genomic element"; private String strWithinRange = "Associate motif with all genomic elements located within range"; private LinkedList<Component> DownstreamGroup; private LinkedList<Component> DownstreamGroupNext; private JTextField LblUpstream, LblDownstream, TxtUpstream, TxtDownstream; private JCheckBox chkStrandMatching, chkStrandMatchingDownStream; private String strchkStrandMatching = "Require same strand"; private String strLblUpstream = "Upstream of start:"; private String strLblDownstream = "Downstream of stop:"; private String strTxtUpstream = "50"; private String strTxtDownstream = "none"; private JRadioButton radAllInternal, radRangeInternal; private String strAllInternal = "Include all internal motifs"; private String strRangeInternal = "Include internal motifs within range"; private ButtonGroup grpInternalMotifs; private LinkedList<Component> ConditionalInternalGroup; private JTextField IntLblDownstream, IntLblUpstream, IntTxtDownstream, IntTxtUpstream; private String strIntLblDownstream = "Downstream of start:"; private String strIntTxtDownstream = "50"; private String strIntTxtUpstream = "none"; private String strIntLblUpstream = "Upstream of stop:"; //(1) MSFimo private LinkedList<Component> MSFimo_group; private JRadioButton MSFimo; private String strMSFimo = "Load sequence motif(s) from a set of FIMO output files"; private JButton btnMSFimo; private String strbtnFimo = "Load"; //(2) MSCustom private LinkedList<Component> MSCustom_group; private JRadioButton MSCustom; private String strMSCustom = "Load sequence motif(s) from a set of tab-delimited files"; private JButton btnMSCustom, btnMSCustomInfo; private String strbtnMSCustom = "Load"; private String strbtnMSCustomInfo = "???"; //Add Motifs private JLabel Add; private JButton btnAddMS; private String strAddMS = "Add"; private JTextField MSName, MSNameLabel; private String strMSNameLabel = "Enter Name: "; private JTextField LoadedFileName; //Remove Motifs private JTextField MotifSequenceHeader; private JButton btnRemoveMotif; private JLabel Remove; private String strRemoveMotif = "Remove"; private JComboBox<String> SequenceMotifsMenu; //okay button - close panel private JButton btnOK; private String strbtnOK = "OK"; //DATA //associate motifs private int NumTxtDownstream = -1; private int NumTxtUpstream = -1; private int NumIntTxtUpstream = -1; private int NumIntTxtDownstream = -1; //Constructor public ManageMotifs(FrmPrincipalDesk f){ super(); this.f = f ; this.ReferenceDirectory = f.getFileChooserSource(); //Initialize Sequence Motifs array + list SequenceMotifsAsArray = this.f.getPanMotifOptions().getMenuLoadedMotifs(); SequenceMotifsAsList = new LinkedList<String>(); for (int i = 0; i <SequenceMotifsAsArray.length; i++){ SequenceMotifsAsList.add(SequenceMotifsAsArray[i]); } this.setSize(830,600); this.setTitle("Manage Sequence Motifs"); this.setModalityType(ModalityType.DOCUMENT_MODAL); this.setModal(true); //add panel components //attempt - add nested panel structure for inherent organization this.getPanel(); this.DisableComponents(); this.setContentPane(jp); //this.pack(); //to pack or not to pack? //turn off all checkbox options for (Component c : this.FindAssociationGroup){ c.setEnabled(false); } for (Component c : DownstreamGroup){ c.setEnabled(false); } this.setLocationRelativeTo(null); this.setVisible(true); } //SwingWorkers //load from fimo file class btnLoadFiles extends SwingWorker<Void,Void>{ private int OrganismsMapped; private int SearchBubbleRange = 10000; //Start looking for motifs only at 10K private boolean isFimo; private boolean isDir; //constructor public btnLoadFiles(boolean isFimo, boolean isFile){ this.isFimo = isFimo; this.isDir = !isFile; } //Fields @Override protected Void doInBackground() throws Exception { //wait cursor f.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); LoadedFileName.setVisible(false); //prepare parameters for association (if appropriate) determineAssociationRanges(); if (isDir){ importFromDir(); } else { importFromSingleFile(); } return null; } //import from a directory protected void importFromDir(){ //re-initialize loading MotifFilesLoaded = false; //initialize motif group description ToAdd = new MotifGroupDescription(); ToAdd.setName(MSName.getText()); LinkedList<String> SpeciesNames = new LinkedList<String>(); //Initialize progress bar type things MSName.setEditable(false); progressBar.setValue(0); progressBar.setVisible(true); int OrganismsCompleted = 0; this.OrganismsMapped = 0; int ComputeProgress = 0; int TotalFilesForProcess = MotifFiles.length; // retrieve all files for (File fi : MotifFiles) { //increment counter OrganismsCompleted++; //check if file or directory String FimoFile = null; String SpeciesName = null; if (fi.isDirectory()){ FimoFile = fi.getAbsolutePath() + "/fimo.txt"; SpeciesName = fi.getName(); } else { FimoFile = fi.getAbsolutePath(); SpeciesName = fi.getName().replaceFirst("[.][^.]+$", ""); } //map this to an organism boolean FoundOrganism = false; for (String s : f.getOS().getSpeciesNames()){ if (s.equals(SpeciesName)){ FoundOrganism = true; break; } } //if there is an organism to map to, proceed. if (FoundOrganism){ //try to read in information from this fimo file + map to organism try { BufferedReader br = new BufferedReader(new FileReader(FimoFile)); String Line = null; //define a new motif group MotifGroup MG = new MotifGroup(); MG.setName(MSName.getText()); MG.setFileName(fi.getAbsolutePath()); //add all sequences while ((Line = br.readLine()) != null){ //ignore commented lines if (!Line.startsWith("#")){ //determine imported line String ImportedLine[] = Line.split("\t"); //build sequence motif SequenceMotif SM = new SequenceMotif(); if (isFimo){ SM.setSource("FIMO"); SM.setMotifName(MSName.getText()); SM.setContig(ImportedLine[1]); SM.setStart(Integer.parseInt(ImportedLine[2])); SM.setStop(Integer.parseInt(ImportedLine[3])); SM.setScore(Double.parseDouble(ImportedLine[4])); SM.setPvalue(Double.parseDouble(ImportedLine[5])); SM.setQvalue(Double.parseDouble(ImportedLine[6])); SM.setSequence(ImportedLine[7].toUpperCase()); } else { SM.setSource("Custom"); SM.setMotifName(MSName.getText()); SM.setContig(ImportedLine[0]); SM.setStart(Integer.parseInt(ImportedLine[1])); SM.setStop(Integer.parseInt(ImportedLine[2])); //optional: sequence if (ImportedLine.length > 3){ SM.setSequence(ImportedLine[3]); //optional: annotation if (ImportedLine.length > 4){ SM.setNotes(ImportedLine[4]); } } } //set strand based on order of elements. if (SM.getStart() < SM.getStop()){ SM.setStrand(Strand.POSITIVE); } else { SM.setStrand(Strand.NEGATIVE); //in the case of a negative strand, flip positive and negative coordinates. int TempStart = SM.getStart(); SM.setStart(SM.getStop()); SM.setStop(TempStart); //also, adjust the string to reverse complement, if appropriate. if (isFimo){ DNASequence d = new DNASequence(SM.getSequence()); SM.setSequence(d.getReverseComplement().getSequenceAsString().toUpperCase()); } } //add to list MG.getMotifInstances().add(SM); //Add associations addAssociation(SpeciesName, SM); } } //add this motif grouping to the species list. f.getOS().getSpecies().get(SpeciesName).getMotifs().add(MG); //increment counter OrganismsMapped++; SpeciesNames.add(SpeciesName); } catch (Exception ex) { //ex.printStackTrace(); JOptionPane.showMessageDialog(null, "One or more fields incorrectly formatted, or the input file is not correctly formatted.", "Format Error",JOptionPane.ERROR_MESSAGE); //System.out.println("Unable to map file: " + FimoFile + " to an organism in the genomic working set."); } } //update progress bar ComputeProgress = (int) Math.round(100*((double)OrganismsCompleted/(double)TotalFilesForProcess)); this.setProgress(ComputeProgress); } //Update final info ToAdd.setSpecies(SpeciesNames); if (isFimo){ ToAdd.setSource("FIMO"); } else { ToAdd.setSource("Custom"); } } //import from a single file protected void importFromSingleFile(){ //Initialize progress bar type things MSName.setEditable(false); progressBar.setValue(0); progressBar.setVisible(true); int LinesCompleted = 0; this.OrganismsMapped = 0; int ComputeProgress = 0; //re-initialize loading MotifFilesLoaded = false; //initialize motif group description ToAdd = new MotifGroupDescription(); ToAdd.setName(MSName.getText()); LinkedList<String> SpeciesNames = new LinkedList<String>(); try { //new input file stream BufferedReader br = new BufferedReader(new FileReader(SingleFile)); //get total number of lines in file String Line = null; int LineCounter = 0; while ((Line = br.readLine()) != null){ LineCounter++; } br.close(); //new input file stream to parse file BufferedReader br2 = new BufferedReader(new FileReader(SingleFile)); Line = null; while ((Line = br2.readLine()) != null){ LinesCompleted++; String[] L = Line.split("\t"); //retrieve species AnnotatedGenome AG = f.getOS().getSpecies().get(L[0]); if (AG != null){ //find an original boolean AlreadyThere = false; MotifGroup MG = null; for (MotifGroup MGt : AG.getMotifs()){ if (MGt.getName().equals(MSName.getText())){ MG = MGt; AlreadyThere = true; } } //remove the original if (AlreadyThere){ AG.getMotifs().remove(MG); } //if no current MotifGroup exists, initialize a new one if (MG == null){ MG = new MotifGroup(); MG.setName(MSName.getText()); MG.setFileName(SingleFile.getAbsolutePath()); } //build sequence motif SequenceMotif SM = new SequenceMotif(); SM.setContig(L[1]); SM.setStart(Integer.parseInt(L[2])); SM.setStop(Integer.parseInt(L[3])); SM.setMotifName(MSName.getText()); SM.setNotes(L[4]); SM.setSource("Custom"); //strandedness if (SM.getStart() > SM.getStop()){ SM.setStrand(Strand.NEGATIVE); } else { SM.setStrand(Strand.POSITIVE); } //add associations this.addAssociation(L[0], SM); //add sequence motif to list MG.getMotifInstances().add(SM); //add this motif grouping to the species list. AG.getMotifs().add(MG); //increment counter OrganismsMapped++; SpeciesNames.add(L[0]); //update progress bar ComputeProgress = (int) Math.round(100*((double)LinesCompleted/(double)LineCounter)); this.setProgress(ComputeProgress); } } } catch (Exception ex){ ex.printStackTrace(); JOptionPane.showMessageDialog(null, "One or more fields incorrectly formatted, or the input file is not correctly formatted.", "Format Error",JOptionPane.ERROR_MESSAGE); this.setProgress(0); } //Update final info ToAdd.setSpecies(SpeciesNames); if (isFimo){ ToAdd.setSource("FIMO"); } else { ToAdd.setSource("Custom"); } } //Determine nucleotide proximity for localization protected void determineAssociationRanges(){ //non-integer parses as -1 //upstream of gene (external) try { NumTxtUpstream = Integer.parseInt(TxtUpstream.getText()); } catch (Exception ex){} //downstream of gene (external) try { NumTxtDownstream = Integer.parseInt(TxtDownstream.getText()); } catch (Exception ex) {} //downstream of gene - internal try { NumIntTxtDownstream = Integer.parseInt(IntTxtDownstream.getText()); } catch (Exception ex) {} //upstream of gene - internal try { NumIntTxtUpstream = Integer.parseInt(IntTxtUpstream.getText()); } catch (Exception ex) {} } //Associate a particular motif with one or more genomic elements protected void addAssociation(String SpeciesName, SequenceMotif SM){ //option: associate with an annotated genome if (chkAssociate.isSelected()){ AnnotatedGenome AG = f.getOS().getSpecies().get(SpeciesName); int DistE_SM; GenomicElement TempE = null; //Center of motif double value = 0.5 * ( (double) SM.getStart() + (double) SM.getStop() ); long Center = Math.round(value); for (GenomicElement E : AG.getElements()){ if (radNextDownstream.isSelected()){ if (E.getContig().contentEquals(SM.getContig())){ // same contig //same strand check if (chkStrandMatchingDownStream.isSelected()){ if (E.getStrand().equals(SM.getStrand())){ //same strand if (SM.getStrand().equals(Strand.POSITIVE)){ //case: internal motif if (E.getStart() < SM.getStart() && E.getStop() > SM.getStop()){ E.addAMotif(SM); break; //case: partially overlapping } else if (SM.getStart() < E.getStart() && SM.getStop() > E.getStart()){ E.addAMotif(SM); break; //case: distance from source } else { DistE_SM = E.getStart() - SM.getStop(); if (DistE_SM > 0){ E.addAMotif(SM); break; } } } else { //case: internal motif if (E.getStart() < SM.getStart() && E.getStop() > SM.getStop()){ E.addAMotif(SM); break; //case: partially overlapping } else if (SM.getStart() < E.getStop() && SM.getStop() > E.getStop()){ E.addAMotif(SM); break; //case: distance from source } else { DistE_SM = E.getStart() - SM.getStop(); if (DistE_SM > 0){ if (TempE != null){ TempE.addAMotif(SM); TempE = null; break; } } else { //store value, in case it is needed. TempE = E; } } } } } else { //case: internal motif if (E.getStart() < SM.getStart() && E.getStop() > SM.getStop()){ E.addAMotif(SM); break; //case: partially overlapping } else if (SM.getStart() < E.getStart() && SM.getStop() > E.getStart()){ E.addAMotif(SM); break; //case: distance from source } else { DistE_SM = E.getStart() - SM.getStop(); if (DistE_SM > 0){ E.addAMotif(SM); break; } } } } //just search for nearby } else if (radWithinRange.isSelected()) { if (E.getContig().contentEquals(SM.getContig())){ // same contig //Center of motif double valueofE = 0.5 * ( (double) E.getStart() + (double) E.getStop() ); long CenterofE = Math.round(valueofE); //Once passed through the search bubble, stop searching - E will only get larger. if (CenterofE - Center > SearchBubbleRange){ break; } //don't even consider the motif if it's out of the search bubble range if (Math.abs(Center - CenterofE) < SearchBubbleRange){ //don't look if a strand-agreement condition is violated, when appropriate. if ((chkStrandMatching.isSelected() && SM.getStrand().equals(E.getStrand())) || chkStrandMatching.isSelected() == false){ //positive stranded case if (E.getStrand().equals(Strand.POSITIVE)){ //upstream case if (NumTxtUpstream >= 0){ if (E.getStart() - Center <= NumTxtUpstream && E.getStart() - Center >= 0){ E.addAMotif(SM); } } //downstream case if (NumTxtDownstream >= 0){ if (Center - E.getStop() <= NumTxtDownstream && Center - E.getStop() >= 0){ E.addAMotif(SM); } } //internal motif case if (radAllInternal.isSelected()){ if (E.getStop() > Center && Center > E.getStart()){ E.addAMotif(SM); } } else { if (NumIntTxtDownstream >= 0){ if (Center - E.getStart() <= NumIntTxtDownstream && Center - E.getStart() >= 0){ E.addAMotif(SM); } } if (NumIntTxtUpstream >= 0){ if (E.getStop() - Center <= NumIntTxtUpstream && E.getStop() - Center >= 0){ E.addAMotif(SM); } } } } else { //upstream case if (NumTxtUpstream >= 0){ if (Center - E.getStop() <= NumTxtUpstream && Center - E.getStop() >= 0){ E.addAMotif(SM); } } //downstream case if (NumTxtDownstream >= 0){ if (E.getStart() - Center <= NumTxtDownstream && E.getStart() - Center >= 0){ E.addAMotif(SM); } } //internal motif case if (radAllInternal.isSelected()){ if (E.getStop() > Center && Center > E.getStart()){ E.addAMotif(SM); } } else { if (NumIntTxtDownstream >= 0){ if (E.getStop() - Center <= NumIntTxtDownstream && E.getStop() - Center >= 0){ E.addAMotif(SM); } } if (NumIntTxtUpstream >= 0){ if (Center - E.getStart() <= NumIntTxtUpstream && Center - E.getStart() >= 0){ E.addAMotif(SM); } } } } } } } } } } } //conclude all processes protected void done(){ //add this list to the set, for update. //SequenceMotifsAsList.add(MSName.getText()); MotifFilesLoaded = true; progressBar.setVisible(false); if (isDir){ LoadedFileName.setText("Sequence motif \"" + MSName.getText() + "\" successfully mapped to " + this.OrganismsMapped + " organisms."); } else { LoadedFileName.setText("Sequence motif \"" + MSName.getText() + "\" successfully mapped " + this.OrganismsMapped + " times."); } LoadedFileName.setVisible(true); btnAddMS.setEnabled(true); MSName.setEditable(true); //wait cursor f.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } //Panel private void getPanel(){ //initial GridBagLayout parameters jp = new JPanel(); jp.setLayout(new GridBagLayout()); final GridBagConstraints c = new GridBagConstraints(); int gridy = 0; //initial GridBagLayout parameters c.anchor = GridBagConstraints.FIRST_LINE_START; c.weightx = 1; /* * ADD MOTIFS */ //Add Motifs Heading c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.insets = new Insets(3,3,3,3); c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 6; Add = new JLabel(" ADD A SEQUENCE MOTIF"); Add.setBackground(Color.GRAY); Add.setOpaque(true); jp.add(Add,c); gridy++; //Name Label c.ipady = 7; c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.insets = new Insets(3,3,3,0); c.fill = GridBagConstraints.HORIZONTAL; MSNameLabel = new JTextField(strMSNameLabel); MSNameLabel.setEditable(false); jp.add(MSNameLabel,c); //the name itself text field c.ipady = 7; c.gridx = 1; c.gridy = gridy; c.gridwidth = 5; c.gridheight = 1; c.insets = new Insets(3,2,3,3); c.fill = GridBagConstraints.HORIZONTAL; MSName = new JTextField(""); MSName.setEditable(true); MSName.addActionListener(this); //CSName.setColumns(200); jp.add(MSName, c); gridy++; //create radio buttons //search type button group definition MSFimo = new JRadioButton(strMSFimo); MSCustom = new JRadioButton(strMSCustom); //define button group MSType = new ButtonGroup(); MSType.add(MSFimo); MSType.add(MSCustom); /* * ASSOCIATION OPTION */ //radio button designations FindAssociationGroup = new LinkedList<Component>(); DownstreamGroupNext = new LinkedList<Component>(); DownstreamGroup = new LinkedList<Component>(); radNextDownstream = new JRadioButton(strNextDownstream); radWithinRange = new JRadioButton (strWithinRange); GrpAssociateMotifs = new ButtonGroup(); GrpAssociateMotifs.add(radNextDownstream); GrpAssociateMotifs.add(radWithinRange); c.ipady = 0; //check box c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 6; c.fill = GridBagConstraints.NONE; c.insets = NewSectionInsets; chkAssociate = new JCheckBox(strAssociate); chkAssociate.setSelected(false); chkAssociate.addActionListener(this); jp.add(chkAssociate, c); gridy++; //next upstream radio button c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 6; c.fill = GridBagConstraints.NONE; c.insets = this.IndentInsets; radNextDownstream.setSelected(true); radNextDownstream.addActionListener(this); FindAssociationGroup.add(radNextDownstream); jp.add(radNextDownstream, c); gridy++; //Strand matching for downstream c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = IndentInsets; chkStrandMatchingDownStream = new JCheckBox(strchkStrandMatching); chkStrandMatchingDownStream.setSelected(false); DownstreamGroupNext.add(chkStrandMatchingDownStream); FindAssociationGroup.add(chkStrandMatchingDownStream); jp.add(chkStrandMatchingDownStream, c); gridy++; //within range radio button c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 6; c.fill = GridBagConstraints.NONE; c.insets = IndentInsets; radWithinRange.addActionListener(this); FindAssociationGroup.add(radWithinRange); jp.add(radWithinRange, c); gridy++; //Require strand matching c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = IndentInsets; chkStrandMatching = new JCheckBox(strchkStrandMatching); chkStrandMatching.setEnabled(true); this.FindAssociationGroup.add(chkStrandMatching); this.DownstreamGroup.add(chkStrandMatching); jp.add(chkStrandMatching, c); //options c.gridx = 1; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = IndentInsets; LblUpstream = new JTextField(strLblUpstream); LblUpstream.setEditable(false); LblUpstream.setHorizontalAlignment(JTextField.RIGHT); LblUpstream.setBorder(null); this.FindAssociationGroup.add(LblUpstream); this.DownstreamGroup.add(LblUpstream); jp.add(LblUpstream, c); c.gridx = 2; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(1,1,1,1); TxtUpstream = new JTextField(strTxtUpstream); TxtUpstream.setEditable(true); this.FindAssociationGroup.add(TxtUpstream); this.DownstreamGroup.add(TxtUpstream); jp.add(TxtUpstream, c); c.gridx = 3; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(1,1,1,1); LblDownstream = new JTextField(strLblDownstream); LblDownstream.setEditable(false); LblDownstream.setBorder(null); LblDownstream.setHorizontalAlignment(JTextField.RIGHT); this.FindAssociationGroup.add(LblDownstream); this.DownstreamGroup.add(LblDownstream); jp.add(LblDownstream, c); c.gridx = 4; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(1,1,1,1); TxtDownstream = new JTextField(strTxtDownstream); TxtDownstream.setEditable(true); this.FindAssociationGroup.add(TxtDownstream); this.DownstreamGroup.add(TxtDownstream); jp.add(TxtDownstream, c); gridy++; //Create button group radAllInternal = new JRadioButton(strAllInternal); radRangeInternal = new JRadioButton(strRangeInternal); grpInternalMotifs = new ButtonGroup(); grpInternalMotifs.add(radAllInternal); grpInternalMotifs.add(radRangeInternal); //add radio buttons c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = IndentInsets; radAllInternal.setSelected(true); radAllInternal.addActionListener(this); this.FindAssociationGroup.add(radAllInternal); this.DownstreamGroup.add(radAllInternal); jp.add(radAllInternal, c); c.gridx = 1; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 3; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(1,1,1,1); radRangeInternal.addActionListener(this); this.FindAssociationGroup.add(radRangeInternal); this.DownstreamGroup.add(radRangeInternal); jp.add(radRangeInternal, c); gridy++; ConditionalInternalGroup = new LinkedList<Component>(); //internal options c.gridx = 1; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = IndentInsets; IntLblDownstream = new JTextField(strIntLblDownstream); IntLblDownstream.setEditable(false); IntLblDownstream.setHorizontalAlignment(JTextField.RIGHT); IntLblDownstream.setBorder(null); this.FindAssociationGroup.add(IntLblDownstream); this.DownstreamGroup.add(IntLblDownstream); ConditionalInternalGroup.add(IntLblDownstream); jp.add(IntLblDownstream, c); c.gridx = 2; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(1,1,1,1); IntTxtDownstream = new JTextField(strIntTxtDownstream); IntTxtDownstream.setEditable(true); this.FindAssociationGroup.add(IntTxtDownstream); this.DownstreamGroup.add(IntTxtDownstream); ConditionalInternalGroup.add(IntTxtDownstream); jp.add(IntTxtDownstream, c); c.gridx = 3; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(1,1,1,1); IntLblUpstream = new JTextField(strIntLblUpstream); IntLblUpstream.setEditable(false); IntLblUpstream.setBorder(null); IntLblUpstream.setHorizontalAlignment(JTextField.RIGHT); this.FindAssociationGroup.add(IntLblUpstream); this.DownstreamGroup.add(IntLblUpstream); ConditionalInternalGroup.add(IntLblUpstream); jp.add(IntLblUpstream, c); c.gridx = 4; c.gridy = gridy; c.gridheight = 1; c.gridwidth = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(1,1,1,1); IntTxtUpstream = new JTextField(strIntTxtUpstream); IntTxtUpstream.setEditable(true); this.FindAssociationGroup.add(IntTxtUpstream); this.DownstreamGroup.add(IntTxtUpstream); ConditionalInternalGroup.add(IntTxtUpstream); jp.add(IntTxtUpstream, c); gridy++; //(1) MSFIMO c.ipady = 7; //grouping MSFimo_group = new LinkedList<Component>(); //add radio button c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 6; c.insets = new Insets(10,1,1,1); jp.add(MSFimo, c); MSFimo.addActionListener(this); gridy++; // load motif sequences from fimo files c.ipadx = 0; c.insets = new Insets(1,20,1,1); c.gridx = 0; c.gridy = gridy; c.gridwidth = 1; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; c.gridy = gridy; btnMSFimo = new JButton(strbtnFimo); btnMSFimo.addActionListener(this); jp.add(btnMSFimo, c); MSFimo_group.add(btnMSFimo); gridy++; //add this mapping to hash map. RadioButtonComponents.put(MSFimo.getModel(), MSFimo_group); //(2) MSCustom //grouping MSCustom_group = new LinkedList<Component>(); //add radio button c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 1; c.insets = new Insets(10,1,1,1); jp.add(MSCustom, c); MSCustom.addActionListener(this); c.gridx = 1; c.gridy = gridy; c.gridheight = 1; c.fill = GridBagConstraints.NONE; c.gridwidth = 1; c.insets = new Insets(1,1,1,1); btnMSCustomInfo = new JButton(strbtnMSCustomInfo); btnMSCustomInfo.addActionListener(this); btnMSCustomInfo.setHorizontalAlignment(SwingConstants.LEFT); //jp.add(btnMSCustomInfo, c); MSCustom_group.add(btnMSCustomInfo); gridy++; // load motif sequences from custom files c.ipadx = 0; c.insets = new Insets(1,20,1,1); c.gridx = 0; c.gridy = gridy; c.gridwidth = 1; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; c.gridy = gridy; btnMSCustom = new JButton(strbtnMSCustom); btnMSCustom.addActionListener(this); jp.add(btnMSCustom, c); MSCustom_group.add(btnMSCustom); gridy++; //add this mapping to hash map. RadioButtonComponents.put(MSCustom.getModel(), MSCustom_group); // progress bar c.insets = new Insets(10,1,1,1); c.ipady = 0; c.gridy = gridy; c.gridx = 0; c.gridwidth = 4; c.ipady = 12; c.fill = GridBagConstraints.HORIZONTAL; progressBar = new JProgressBar(0, 100); progressBar.setStringPainted(false); progressBar.setBorderPainted(false); progressBar.setValue(0); progressBar.setForeground(Color.BLUE); progressBar.setVisible(false); jp.add(progressBar, c); // Loaded File Name c.insets = new Insets(10,1,1,1); c.ipady = 5; c.gridx = 0; c.gridy = gridy; c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 4; LoadedFileName = new JTextField(); LoadedFileName.setText(""); // No file loaded LoadedFileName.addActionListener(this); LoadedFileName.setEditable(false); jp.add(LoadedFileName, c); //add context set c.gridx = 4; c.gridy = gridy; c.gridwidth = 2; c.gridheight = 1; c.ipady = 0; c.insets = new Insets(10,1,1,1); c.fill = GridBagConstraints.HORIZONTAL; btnAddMS = new JButton(strAddMS); btnAddMS.addActionListener(this); btnAddMS.setEnabled(false); jp.add(btnAddMS, c); gridy++; /* * REMOVE MOTIFS */ //Remove Motifs Heading c.gridx = 0; c.gridy = gridy; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 6; c.insets = new Insets(3,3,3,3); Remove = new JLabel(" REMOVE A SEQUENCE MOTIF"); Remove.setBackground(Color.GRAY); Remove.setOpaque(true); jp.add(Remove,c); gridy++; // Sequence Motif Text label c.ipady = 5; c.gridx = 0; c.gridy = gridy; c.gridwidth = 1; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; //c.fill = GridBagConstraints.NONE; c.insets = new Insets(1,1,1,1); MotifSequenceHeader = new JTextField(); MotifSequenceHeader.setText("Sequence Motif:"); // context set currently loaded MotifSequenceHeader.addActionListener(this); MotifSequenceHeader.setEditable(false); jp.add(MotifSequenceHeader, c); // drop-down menu for Context Sets c.ipady = 0; c.gridx = 1; c.gridy = gridy; c.gridwidth = 3; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; SequenceMotifsMenu = new JComboBox<String>(SequenceMotifsAsArray); SequenceMotifsMenu.addActionListener(this); SequenceMotifsMenu.setEnabled(true); jp.add(SequenceMotifsMenu, c); //remove button c.gridx = 4; c.gridy = gridy; c.gridwidth = 2; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; btnRemoveMotif = new JButton(strRemoveMotif); btnRemoveMotif.addActionListener(this); btnRemoveMotif.setEnabled(true); jp.add(btnRemoveMotif, c); gridy++; gridy++; //submit button c.gridx = 1; c.gridy = gridy; c.gridwidth = 3; c.gridheight = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(10,1,1,1); btnOK = new JButton(strbtnOK); btnOK.addActionListener(this); jp.add(btnOK, c); //Finally, add to panel. this.getContentPane().add(jp, BorderLayout.NORTH); } //disable all components private void DisableComponents(){ for (LinkedList<Component> LLC : RadioButtonComponents.values()){ for (Component c : LLC){ c.setEnabled(false); } } } //enable all components within a single button group public void EnableComponents(ButtonModel selectedGroup){ //enable appropriate components for (ButtonModel bm : RadioButtonComponents.keySet()){ LinkedList<Component> LL = RadioButtonComponents.get(bm); if (bm.equals(selectedGroup)){ for (Component c : LL){ c.setEnabled(true); } } else { for (Component c : LL){ c.setEnabled(false); } } } } //retrieve either directory or data file private void getMotifFiles(){ //initialize output JFileChooser GetMotifFiles = new JFileChooser(); GetMotifFiles.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); GetMotifFiles.setDialogTitle("Select directory containing FIMO output or custom motif files (or directories)"); if (f.getFileChooserSource() != null){ GetMotifFiles.setCurrentDirectory(f.getFileChooserSource()); } else { GetMotifFiles.setCurrentDirectory(new File(".")); } GetMotifFiles.showOpenDialog(GetMotifFiles); //retrieve directory containing fimo files File ParentDirectory = GetMotifFiles.getSelectedFile(); this.ReferenceDirectory = GetMotifFiles.getCurrentDirectory(); //check if file could be received if (ParentDirectory != null){ //update current directory f.setFileChooserSource(GetMotifFiles.getCurrentDirectory()); if (ParentDirectory.isDirectory()){ //retrieve directory this.MotifFiles = ParentDirectory.listFiles(); this.isFile = false; } else { //retrieve single file this.isFile = true; SingleFile = ParentDirectory; } } else { //no files are currently loaded. this.MotifFiles = null; this.isFile = false; } } public String[] convertSequenceMotifs(LinkedList<ContextSetDescription> ListOfContextSets){ //initialize output array String[] ArrayOfContextSets = new String[ListOfContextSets.size()]; //iterate through array for (int i = 0; i < ListOfContextSets.size(); i++){ ArrayOfContextSets[i] = ListOfContextSets.get(i).getName(); } return ArrayOfContextSets; } @Override public void actionPerformed(ActionEvent evt) { //check boxes: enable + disable appropriate components EnableComponents(MSType.getSelection()); //update appropriate message box UpdateMessageBox(); //Load motifs from FIMO files if (evt.getSource().equals(btnMSFimo)){ //check if name is acceptable CheckName(); if (AcceptableName == true){ //retrieve directory getMotifFiles(); //create a new swing worker btnLoadFiles LF = new btnLoadFiles(true, isFile); LF.addPropertyChangeListener(this); LF.execute(); } } if (evt.getSource().equals(btnMSCustom)){ //check if name is acceptable CheckName(); if (AcceptableName == true){ //retrieve directory getMotifFiles(); //create a new swing worker btnLoadFiles LF = new btnLoadFiles(false, isFile); LF.addPropertyChangeListener(this); LF.execute(); } } if (evt.getSource().equals(this.MSFimo) || evt.getSource().equals(this.MSCustom)){ this.btnAddMS.setEnabled(true); } //active/deactivate components depending on checkbox if (evt.getSource().equals(this.chkAssociate)){ for (Component c : FindAssociationGroup){ if (!this.chkAssociate.isSelected()){ c.setEnabled(false); } else { if (DownstreamGroup.contains(c)){ if (radWithinRange.isSelected()){ if (radAllInternal.isSelected()){ if (!this.ConditionalInternalGroup.contains(c)){ c.setEnabled(true); } } else { c.setEnabled(true); } } } else { c.setEnabled(true); } } } } if (evt.getSource().equals(radNextDownstream)){ for (Component c : DownstreamGroup){ c.setEnabled(false); } for (Component c : DownstreamGroupNext){ c.setEnabled(true); } } if (evt.getSource().equals(radWithinRange)){ for (Component c : DownstreamGroup){ if (radAllInternal.isSelected()){ if (!this.ConditionalInternalGroup.contains(c)){ c.setEnabled(true); } } else { c.setEnabled(true); } } for (Component c : DownstreamGroupNext){ c.setEnabled(false); } } if (evt.getSource().equals(radRangeInternal)){ for (Component c : this.ConditionalInternalGroup){ c.setEnabled(true); } } if (evt.getSource().equals(this.radAllInternal)){ for (Component c : this.ConditionalInternalGroup){ c.setEnabled(false); } } if (evt.getSource().equals(btnAddMS)){ CheckName(); if (AcceptableName == true){ //check cases that are not working if (!MotifFilesLoaded && MSType.isSelected(MSFimo.getModel())) { JOptionPane.showMessageDialog(null, "Select the load button to load fimo-output motif files", "Fimo files not loaded", JOptionPane.ERROR_MESSAGE); } else if (!MotifFilesLoaded && MSType.isSelected(MSCustom.getModel())){ JOptionPane.showMessageDialog(null, "Select the load button to load custom-determined motif files", "Custom files not loaded", JOptionPane.ERROR_MESSAGE); } else { //add description to the OS f.getOS().getMGDescriptions().add(ToAdd); SequenceMotifsAsList.add(ToAdd.getName()); //SequenceMotifsAsArray.add(ToAdd.getName()); //rebuild appropriately SequenceMotifsMenu.removeAllItems(); for (String s : SequenceMotifsAsList){ if (!s.equals("<none>")){ SequenceMotifsMenu.addItem(s); } } //update OS f.getOS().setMotifNames(SequenceMotifsAsList); if (f.getOS().getMotifNames().contains("<none>")){ f.getOS().getMotifNames().remove("<none>"); } //pre-processed sets are reset MotifFilesLoaded = false; LoadedFileName.setText("Motif sequence \"" + ToAdd.getName() + "\" successfully added to the genomic working set!"); } } } //REMOVE BUTTON if (evt.getSource().equals(btnRemoveMotif)){ //set wait cursor this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); Object Item = SequenceMotifsMenu.getSelectedItem(); //update motifs //OS level for (int i = 0; i < f.getOS().getMGDescriptions().size(); i++){ if (f.getOS().getMGDescriptions().get(i).getName().equals(SequenceMotifsMenu.getSelectedItem())){ //remove from all annotated genomes if necessary for (AnnotatedGenome AG : f.getOS().getSpecies().values()){ for (MotifGroup MG : AG.getMotifs()){ if (MG.getName().equals(f.getOS().getCSDs().get(i).getName())){ AG.getGroupings().remove(MG); } } for (GenomicElement E : AG.getElements()){ E.removeAMotifByName(f.getOS().getMGDescriptions().get(i).getName()); } } //remove the organism set-wide context set description f.getOS().getMGDescriptions().remove(i); } } //remove from list SequenceMotifsAsList.remove(Item); //remove from JComboBoxes //add/remove menu SequenceMotifsMenu.removeItem(Item); //add a new tag, if there are none if (SequenceMotifsMenu.getItemCount() == 0){ SequenceMotifsMenu.addItem("<none>"); } //remove from parent frame f.getPanMotifOptions().getMenuOfMotifs().removeItem(Item); //set default cursor this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } //close panel, after updating list. if (evt.getSource().equals(btnOK)){ //set the main frame menu to the existing menu. //remove all items, then add all items back. this.f.getPanMotifOptions().getMenuOfMotifs().removeAllItems(); LinkedList<String> MotifNames = new LinkedList<String>(); for (int i = 0; i < f.getOS().getMGDescriptions().size(); i++){ this.f.getPanMotifOptions().getMenuOfMotifs().addItem(f.getOS().getMGDescriptions().get(i).getName()); MotifNames.add(f.getOS().getMGDescriptions().get(i).getName()); } //if no motifs, reflect this. if (this.f.getPanMotifOptions().getMenuLoadedMotifs().length == 0){ this.f.getPanMotifOptions().getMenuOfMotifs().addItem("<none>"); } //update loaded motifs list in main frame this.f.getPanMotifOptions().setLoadedMotifs(MotifNames); //close this window. this.dispose(); } //information about formatting. if (evt.getSource().equals(this.btnMSCustomInfo)){ //new InfoFrame(); } } //update message box public void UpdateMessageBox(){ } //check if name is acceptable public void CheckName(){ //set name as acceptable. this.AcceptableName = true; //name is unacceptable if non-unique for (String s : SequenceMotifsAsList){ if (s.equals(MSName.getText())){ AcceptableName = false; } } //name is also unacceptable if field is empty if (MSName.getText().equals("")){ AcceptableName = false; } //show error message if appropriate if (AcceptableName == false){ JOptionPane.showMessageDialog(null, "Please give the context set a unique name.", "Name Missing or non-unique",JOptionPane.ERROR_MESSAGE); } } //update progress bar @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName() == "progress") { int progress = (Integer) evt.getNewValue(); progressBar.setValue(progress); } } }