package haloGUI; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.LinkedList; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.DropMode; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.ListSelectionModel; import javax.swing.TransferHandler; import javax.swing.text.BadLocationException; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.text.StyledDocument; import moduls.frm.FrmPrincipalDesk; public class GFFChecker extends JFrame implements ActionListener{ //Fields //universal private static final long serialVersionUID = 1L; private JPanel jp; private LoadGenomesPanelv2 lgp; private FrmPrincipalDesk f; private TransferHandler lh; private String strTextField = ""; private int SrchCol = 12; private int RmvIndent = 11; //Introductory info private JTextPane Instructions; private Dimension InstructionDimensions = new Dimension(300,150); private JScrollPane InstructionPane; //include list private LinkedList<String> IncludeTypes; private DefaultListModel<String> IncludeListModel; private JList<String> IncludeList; private JScrollPane IncludePane; private JPanel IncludeInternalPanel; private String strIncludeInternalPanel = "Types to Include in Genomic Groupings"; private JTextField IncludeTextField; private JButton IncludeAddButton; private JButton IncludeRemoveButton; //display list private LinkedList<String> DisplayOnlyTypes; private DefaultListModel<String> DisplayOnlyListModel; private JList<String> DisplayOnlyList; private JScrollPane DisplayOnlyPane; private JPanel DisplayOnlyInternalPanel; private String strDisplayOnlyInternalPanel = "Types to Include for Display only"; private JTextField DisplayOnlyTextField; private JButton DisplayOnlyAddButton; private JButton DisplayOnlyRemoveButton; //submit / return private JButton btnSubmit; //private String strbtnSubmit = "Proceed to GFF import with these type-processing settings."; private String strbtnSubmit = "Ok"; //Constructor public GFFChecker(LoadGenomesPanelv2 lgp){ //parent bioinfo this.lgp = lgp; //initializations lh = new ListTransferHandler(); //create GUI object this.getInstructions(); this.getFrame(); this.getPanel(); this.pack(); //make frame visible this.setVisible(true); } //alternative constructor public GFFChecker(FrmPrincipalDesk f){ this.f = f; //initializations lh = new ListTransferHandler(); //create GUI object this.getInstructions(); this.getFrame(); this.getPanel(); this.pack(); //make frame visible this.setVisible(true); } //Build instructional message public void getInstructions(){ // create a JTextPane + add settings Instructions = new JTextPane(); Instructions.setEditable(false); //retrieve document, and add styles StyledDocument doc = Instructions.getStyledDocument(); Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE); Style regular = doc.addStyle("regular", def); StyleConstants.setFontFamily(def, "SansSerif"); Style s = doc.addStyle("bold", regular); StyleConstants.setBold(s, true); //text into document try { doc.insertString(doc.getLength(), "Instructions:\n\n", doc.getStyle("bold")); doc.insertString(doc.getLength(), "The third column of a .GFF file, or the first column of a GenBank file, describes each annotated feature's biological \"type\".", doc.getStyle("regular")); doc.insertString(doc.getLength(), " For example, coding regions", doc.getStyle("regular")); doc.insertString(doc.getLength(), " often have a type designation of \"CDS\" or \"gene\", and transfer RNA often have a type designation of \"tRNA\".\n\n", doc.getStyle("regular")); doc.insertString(doc.getLength(), "This tool allows you to specify how to handle different types of annotated features.\n", doc.getStyle("regular")); doc.insertString(doc.getLength(), "In general, among all possible feature types, you may specify\n",doc.getStyle("Regular")); doc.insertString(doc.getLength(), "(1) The types that should be retained for both genomic grouping computation and display,\n", doc.getStyle("regular")); doc.insertString(doc.getLength(), "(2) The types that should be excluded from genomic grouping computation, but retained for display, and \n", doc.getStyle("regular")); doc.insertString(doc.getLength(), "(3) The types that should be excluded altogether.\n\n", doc.getStyle("regular")); doc.insertString(doc.getLength(), "Types in the list ", doc.getStyle("Regular")); doc.insertString(doc.getLength(), "Types to Include in Genomic Groupings ",doc.getStyle("bold")); doc.insertString(doc.getLength(), "(left) will be retained for both genomic grouping computation and display. Types in the list ", doc.getStyle("Regular")); doc.insertString(doc.getLength(), "Types to Include for Display only ",doc.getStyle("bold")); doc.insertString(doc.getLength(), "(right) will be retained for display only when viewing genomic segments. ",doc.getStyle("Regular")); doc.insertString(doc.getLength(), "All other types will be ignored (excluded altogether).\n\n", doc.getStyle("bold")); doc.insertString(doc.getLength(), "To add types to a list, type in the type in the text field below the list and push the \"Add\" button. \n", doc.getStyle("Regular")); doc.insertString(doc.getLength(), "To remove types from a list, select the type with your mouse, and push the \"Remove\" button. \n", doc.getStyle("Regular")); doc.insertString(doc.getLength(), "To transfer types from one list to another, select the type with your mouse, and drag the type to the other list.\n\n", doc.getStyle("Regular")); doc.insertString(doc.getLength(), "WARNING!\n", doc.getStyle("bold")); doc.insertString(doc.getLength(), "Features in a GFF or GenBank file may not overlap in the genomic coordinates they span. In the case that they do overlap, JContextExplorer will exhibit unpredictable behavior ", doc.getStyle("Regular")); doc.insertString(doc.getLength(), "and likely fail.\n", doc.getStyle("Regular")); doc.insertString(doc.getLength(), "Please ensure that no annotated features overlap prior to loading GFF or GenBank files.", doc.getStyle("bold")); doc.insertString(doc.getLength(), "\n\nFor additional help and examples, please consult the JContextExplorer manual.", doc.getStyle("regular")); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //Create frame public void getFrame(){ this.setSize(700,620); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.setLocationRelativeTo(null); this.setTitle("Feature Type Import Settings"); } //Create panel public void getPanel(){ //initial GridBagLayout parameters jp = new JPanel(); jp.setLayout(new GridBagLayout()); final GridBagConstraints c = new GridBagConstraints(); int gridy = 0; int gridx = 0; //initial GridBagLayout parameters c.anchor = GridBagConstraints.FIRST_LINE_START; c.weightx = 1; /* * Include List */ //Initialize list + list elements IncludeListModel = new DefaultListModel<String>(); if (f != null){ for (String s : f.getGFFIncludeTypes()){ IncludeListModel.addElement(s); } } else { IncludeListModel.addElement("CDS"); IncludeListModel.addElement("tRNA"); IncludeListModel.addElement("rRNA"); } //GUI list settings IncludeList = new JList<String>(IncludeListModel); IncludeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); IncludeList.setDragEnabled(true); IncludeList.setDropMode(DropMode.INSERT); IncludeList.setTransferHandler(lh); setMappings(IncludeList); //Internal pane - initialize IncludeInternalPanel = new JPanel(new BorderLayout()); IncludeInternalPanel.setBorder(BorderFactory.createTitledBorder(strIncludeInternalPanel)); IncludeInternalPanel.setLayout(new GridBagLayout()); final GridBagConstraints c1 = new GridBagConstraints(); //Internal pane - components //scrollpane IncludePane = new JScrollPane(IncludeList); IncludePane.setPreferredSize(new Dimension(300,100)); c1.insets = new Insets(1,1,1,10); c1.anchor = GridBagConstraints.FIRST_LINE_START; c1.weightx = 1; c1.gridx = 0; c1.gridy = 0; c1.gridwidth = 3; IncludeInternalPanel.add(IncludePane, c1); //search bar c1.gridx = 0; c1.gridy = 1; c1.gridwidth = 1; c1.fill = GridBagConstraints.HORIZONTAL; c1.insets = new Insets(1,1,1,1); c1.ipady = 7; IncludeTextField = new JTextField(strTextField); IncludeTextField.setColumns(SrchCol); IncludeTextField.setEditable(true); IncludeTextField.addActionListener(this); IncludeInternalPanel.add(IncludeTextField, c1); //Add button c1.gridx = 1; c1.gridy = 1; c1.gridwidth = 1; c1.ipady = 0; c1.fill = GridBagConstraints.HORIZONTAL; c1.insets = new Insets(1,1,1,1); IncludeAddButton = new JButton("Add"); IncludeAddButton.addActionListener(this); IncludeInternalPanel.add(IncludeAddButton, c1); //Remove button c1.gridx = 2; c1.gridy = 1; c1.gridwidth = 1; c1.ipady = 0; c1.fill = GridBagConstraints.HORIZONTAL; c1.insets = new Insets(1,1,1,RmvIndent); IncludeRemoveButton = new JButton("Remove"); IncludeRemoveButton.addActionListener(this); IncludeInternalPanel.add(IncludeRemoveButton, c1); //internal panel -> frame panel c.gridx = gridx; c.gridy = gridy; c.insets = new Insets(0,0,0,0); jp.add(IncludeInternalPanel,c); //GridBagLayout transitions gridx++; /* * Display List */ //Initialize list + list elements DisplayOnlyListModel = new DefaultListModel<String>(); if (f != null){ for (String s : f.getGFFDisplayTypes()){ DisplayOnlyListModel.addElement(s); } } else { DisplayOnlyListModel.addElement("mobile_element"); DisplayOnlyListModel.addElement("IS_element"); } //GUI list settings DisplayOnlyList = new JList<String>(DisplayOnlyListModel); DisplayOnlyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); DisplayOnlyList.setDragEnabled(true); DisplayOnlyList.setDropMode(DropMode.INSERT); DisplayOnlyList.setTransferHandler(lh); setMappings(DisplayOnlyList); //internal pane - initialize DisplayOnlyInternalPanel = new JPanel(new BorderLayout()); DisplayOnlyInternalPanel.setBorder(BorderFactory.createTitledBorder(strDisplayOnlyInternalPanel)); DisplayOnlyInternalPanel.setLayout(new GridBagLayout()); final GridBagConstraints c2 = new GridBagConstraints(); //Internal pane - components //scrollpane c2.insets = new Insets(1,1,1,10); c2.anchor = GridBagConstraints.FIRST_LINE_START; c2.weightx = 1; c2.gridx = 0; c2.gridy = 0; c2.gridwidth = 3; DisplayOnlyPane = new JScrollPane(DisplayOnlyList); DisplayOnlyPane.setPreferredSize(new Dimension(300,100)); DisplayOnlyInternalPanel.add(DisplayOnlyPane, c2); //search bar c2.gridx = 0; c2.gridy = 1; c2.gridwidth = 1; c2.fill = GridBagConstraints.HORIZONTAL; c2.insets = new Insets(1,1,1,1); c2.ipady = 7; DisplayOnlyTextField = new JTextField(strTextField); DisplayOnlyTextField.setEditable(true); DisplayOnlyTextField.setColumns(SrchCol); DisplayOnlyTextField.addActionListener(this); DisplayOnlyInternalPanel.add(DisplayOnlyTextField, c2); //add button c2.gridx = 1; c2.gridy = 1; c2.gridwidth = 1; c2.ipady = 0; c2.fill = GridBagConstraints.HORIZONTAL; c2.insets = new Insets(1,1,1,1); DisplayOnlyAddButton = new JButton("Add"); DisplayOnlyAddButton.addActionListener(this); DisplayOnlyInternalPanel.add(DisplayOnlyAddButton, c2); //Remove button c1.gridx = 2; c1.gridy = 1; c1.gridwidth = 1; c1.ipady = 0; c1.fill = GridBagConstraints.HORIZONTAL; c1.insets = new Insets(1,1,1,RmvIndent); DisplayOnlyRemoveButton = new JButton("Remove"); DisplayOnlyRemoveButton.addActionListener(this); DisplayOnlyInternalPanel.add(DisplayOnlyRemoveButton, c1); //internal panel -> frame panel c.gridx = gridx; c.gridy = gridy; c.insets = new Insets(0,40,0,0); jp.add(DisplayOnlyInternalPanel,c); //GridBagLayout transitions gridx = 0; gridy++; /* * Instructions / Explanations */ c.gridx = gridx; c.gridy = gridy; c.gridwidth = 2; c.gridheight = 1; c.insets = new Insets(5,5,5,5); c.fill = GridBagConstraints.HORIZONTAL; InstructionPane= new JScrollPane(Instructions); InstructionPane.setPreferredSize(InstructionDimensions); Instructions.setCaretPosition(0); jp.add(InstructionPane, c); gridy++; gridx = 0; /* * Submit/Return */ c.gridx = gridx; c.gridy = gridy; c.gridwidth = 2; c.gridheight = 2; c.fill = GridBagConstraints.HORIZONTAL; c.ipady = 20; c.insets = new Insets(10,100,10,100); btnSubmit = new JButton(strbtnSubmit); btnSubmit.addActionListener(this); btnSubmit.addActionListener(lgp); jp.add(btnSubmit, c); //add panel to frame this.add(jp, BorderLayout.NORTH); } //List-associated mappings private void setMappings(JList list) { ActionMap map = list.getActionMap(); map.put(TransferHandler.getCutAction().getValue(Action.NAME), TransferHandler.getCutAction()); map.put(TransferHandler.getCopyAction().getValue(Action.NAME), TransferHandler.getCopyAction()); map.put(TransferHandler.getPasteAction().getValue(Action.NAME), TransferHandler.getPasteAction()); } //Actions! @Override public void actionPerformed(ActionEvent e) { //Include List //Adding if (e.getSource().equals(IncludeAddButton) || e.getSource().equals(IncludeTextField)){ //ignore empty fields. if (IncludeTextField.getText().contentEquals("")==false){ //check to see if adding to list is appropriate or not boolean AddToList = true; boolean RemoveFromOtherList = false; for (int i = 0; i < IncludeListModel.getSize(); i++){ if (IncludeListModel.get(i).toString().contentEquals(IncludeTextField.getText().trim())){ AddToList = false; } } //add to list, if appropriate if (AddToList){ IncludeListModel.addElement(IncludeTextField.getText().trim()); } //remove from other list, if appropriate. for (int i = 0; i < DisplayOnlyListModel.getSize(); i++){ if (DisplayOnlyListModel.get(i).toString().contentEquals(IncludeTextField.getText().trim())){ DisplayOnlyListModel.remove(i); } } //reset text field. IncludeTextField.setText(""); } } //Removing if (e.getSource().equals(IncludeRemoveButton)){ try { for (int i = 0; i < IncludeListModel.getSize(); i++){ if (IncludeListModel.get(i).toString().contentEquals(IncludeList.getSelectedValue())){ IncludeListModel.remove(i); } } } catch (Exception ex){} } //DisplayOnly List //Adding if (e.getSource().equals(DisplayOnlyAddButton) || e.getSource().equals(DisplayOnlyTextField)){ if (DisplayOnlyTextField.getText().contentEquals("")==false){ //check to see if adding to list is appropriate or not boolean AddToList = true; boolean RemoveFromOtherList = false; for (int i = 0; i < DisplayOnlyListModel.getSize(); i++){ if (DisplayOnlyListModel.get(i).toString().contentEquals(DisplayOnlyTextField.getText().trim())){ AddToList = false; } } //add to list, if appropriate if (AddToList){ DisplayOnlyListModel.addElement(DisplayOnlyTextField.getText().trim()); } //remove from other list, if appropriate. for (int i = 0; i < IncludeListModel.getSize(); i++){ if (IncludeListModel.get(i).toString().contentEquals(DisplayOnlyTextField.getText().trim())){ IncludeListModel.remove(i); } } //reset text field. DisplayOnlyTextField.setText(""); } } //Removing if (e.getSource().equals(DisplayOnlyRemoveButton)){ try { for (int i = 0; i < DisplayOnlyListModel.getSize(); i++){ if (DisplayOnlyListModel.get(i).toString().contentEquals(DisplayOnlyList.getSelectedValue())){ DisplayOnlyListModel.remove(i); } } } catch (Exception ex){} } //Submit / proceed if (e.getSource().equals(btnSubmit)){ //record included + display only types in linked list form. IncludeTypes = new LinkedList<String>(); for (int i = 0; i < IncludeListModel.getSize(); i++){ IncludeTypes.add(IncludeListModel.get(i).toString()); } DisplayOnlyTypes = new LinkedList<String>(); for (int i = 0; i < DisplayOnlyListModel.getSize(); i++){ DisplayOnlyTypes.add(DisplayOnlyListModel.get(i).toString()); } //when lgp exists, remember type settings if (lgp != null) { //write these types to the output structure. lgp.setIncludeTypes(IncludeTypes); lgp.setDisplayOnlyTypes(DisplayOnlyTypes); } //when frm principal desk exists, remember type settings. if (f != null){ //write these types to output structure. f.setGFFIncludeTypes(IncludeTypes); f.setGFFDisplayTypes(DisplayOnlyTypes); } //dispose the window. this.dispose(); } } //---GETTERS + SETTERS----------- public JButton getBtnSubmit() { return btnSubmit; } public void setBtnSubmit(JButton btnSubmit) { this.btnSubmit = btnSubmit; } //transfer handler class class ListTransferHandler extends TransferHandler { private static final long serialVersionUID = 1L; /** * Perform the actual data import. */ public boolean importData(TransferHandler.TransferSupport info) { String data = null; //If we can't handle the import, bail now. if (!canImport(info)) { return false; } JList list = (JList)info.getComponent(); DefaultListModel model = (DefaultListModel)list.getModel(); //Fetch the data -- bail if this fails try { data = (String)info.getTransferable().getTransferData(DataFlavor.stringFlavor); } catch (UnsupportedFlavorException ufe) { System.out.println("importData: unsupported data flavor"); return false; } catch (IOException ioe) { System.out.println("importData: I/O exception"); return false; } //only add objects that are not already in the list. boolean AddToList = true; for (int i = 0 ; i <model.getSize(); i++){ if (model.get(i).toString().contentEquals(data)){ AddToList = false; } } if (AddToList){ if (info.isDrop()) { //This is a drop JList.DropLocation dl = (JList.DropLocation)info.getDropLocation(); int index = dl.getIndex(); if (dl.isInsert()) { model.add(index, data); return true; } else { model.set(index, data); return true; } } else { //This is a paste int index = list.getSelectedIndex(); // if there is a valid selection, // insert data after the selection if (index >= 0) { model.add(list.getSelectedIndex()+1, data); // else append to the end of the list } else { model.addElement(data); } return true; } } else { return false; } } /** * Bundle up the data for export. */ protected Transferable createTransferable(JComponent c) { JList list = (JList)c; int index = list.getSelectedIndex(); String value = (String)list.getSelectedValue(); return new StringSelection(value); } /** * The list handles both copy and move actions. */ public int getSourceActions(JComponent c) { return COPY_OR_MOVE; } /** * When the export is complete, remove the old list entry if the * action was a move. */ protected void exportDone(JComponent c, Transferable data, int action) { if (action != MOVE) { return; } JList list = (JList)c; DefaultListModel model = (DefaultListModel)list.getModel(); int index = list.getSelectedIndex(); model.remove(index); } /** * We only support importing strings. */ public boolean canImport(TransferHandler.TransferSupport support) { // we only import Strings if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) { return false; } return true; } } }