5a185f8099e7cb335f4bec75c0f750176b2ab58f
[jalview.git] / src / jalview / jbgui / GStructureChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21
22 package jalview.jbgui;
23
24 import jalview.datamodel.SequenceI;
25 import jalview.fts.api.FTSDataColumnI;
26 import jalview.fts.core.FTSDataColumnPreferences;
27 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
28 import jalview.fts.service.pdb.PDBFTSRestClient;
29 import jalview.gui.AlignmentPanel;
30 import jalview.gui.Desktop;
31 import jalview.gui.JvSummaryTable;
32 import jalview.gui.JvSwingUtils;
33 import jalview.util.MessageManager;
34
35 import java.awt.BorderLayout;
36 import java.awt.CardLayout;
37 import java.awt.Component;
38 import java.awt.Dimension;
39 import java.awt.FlowLayout;
40 import java.awt.GridLayout;
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ItemEvent;
43 import java.awt.event.ItemListener;
44 import java.awt.event.KeyAdapter;
45 import java.awt.event.KeyEvent;
46 import java.awt.event.MouseAdapter;
47 import java.awt.event.MouseEvent;
48 import java.util.Arrays;
49 import java.util.HashMap;
50 import java.util.Map;
51
52 import javax.swing.ImageIcon;
53 import javax.swing.JButton;
54 import javax.swing.JCheckBox;
55 import javax.swing.JComboBox;
56 import javax.swing.JFrame;
57 import javax.swing.JInternalFrame;
58 import javax.swing.JLabel;
59 import javax.swing.JList;
60 import javax.swing.JPanel;
61 import javax.swing.JScrollPane;
62 import javax.swing.JSeparator;
63 import javax.swing.JTabbedPane;
64 import javax.swing.JTable;
65 import javax.swing.JTextField;
66 import javax.swing.ListCellRenderer;
67 import javax.swing.event.ChangeEvent;
68 import javax.swing.event.ChangeListener;
69 import javax.swing.event.DocumentEvent;
70 import javax.swing.event.DocumentListener;
71 import javax.swing.event.InternalFrameEvent;
72
73 @SuppressWarnings("serial")
74 /**
75  * GUI layout for structure chooser 
76  * @author tcnofoegbu
77  *
78  */
79 public abstract class GStructureChooser extends JPanel implements
80         ItemListener
81 {
82   protected JPanel statusPanel = new JPanel();
83
84   public JLabel statusBar = new JLabel();
85
86   private JPanel pnl_actionsAndStatus = new JPanel(new BorderLayout());
87
88   protected String frameTitle = MessageManager
89           .getString("label.structure_chooser");
90
91   protected JInternalFrame mainFrame = new JInternalFrame(frameTitle);
92
93   protected JComboBox<FilterOption> cmb_filterOption = new JComboBox<FilterOption>();
94
95   protected AlignmentPanel ap;
96
97   protected StringBuilder errorWarning = new StringBuilder();
98
99   protected JLabel lbl_result = new JLabel(
100           MessageManager.getString("label.select"));
101
102   protected JButton btn_view = new JButton();
103
104   protected JButton btn_cancel = new JButton();
105
106   protected JButton btn_pdbFromFile = new JButton();
107
108   protected JButton btn_runPhyre2Prediction = new JButton();
109
110   protected JTextField txt_search = new JTextField(14);
111
112   private JPanel pnl_actions = new JPanel();
113
114   private JPanel pnl_main = new JPanel();
115
116   private JPanel pnl_idInput = new JPanel(new FlowLayout());
117
118   private JPanel pnl_fileChooser = new JPanel(new FlowLayout());
119
120   private JPanel pnl_phyre2Prediction = new JPanel(new FlowLayout());
121
122   private JPanel pnl_phyre2PredictionBL = new JPanel(new BorderLayout());
123
124   private JPanel pnl_idInputBL = new JPanel(new BorderLayout());
125
126   private JPanel pnl_fileChooserBL = new JPanel(new BorderLayout());
127
128   private JPanel pnl_locPDB = new JPanel(new BorderLayout());
129
130   protected JPanel pnl_switchableViews = new JPanel(new CardLayout());
131
132   protected CardLayout layout_switchableViews = (CardLayout) (pnl_switchableViews
133           .getLayout());
134
135   private BorderLayout mainLayout = new BorderLayout();
136
137   protected JCheckBox chk_rememberSettings = new JCheckBox(
138           MessageManager.getString("label.dont_ask_me_again"));
139
140   protected JCheckBox chk_invertFilter = new JCheckBox(
141           MessageManager.getString("label.invert"));
142
143   protected ImageIcon loadingImage = new ImageIcon(getClass().getResource(
144           "/images/loading.gif"));
145
146   protected ImageIcon goodImage = new ImageIcon(getClass().getResource(
147           "/images/good.png"));
148
149   protected ImageIcon errorImage = new ImageIcon(getClass().getResource(
150           "/images/error.png"));
151
152   protected ImageIcon warningImage = new ImageIcon(getClass().getResource(
153           "/images/warning.gif"));
154
155   protected JLabel lbl_warning = new JLabel(warningImage);
156
157   protected JLabel lbl_loading = new JLabel(loadingImage);
158
159   protected JLabel lbl_pdbManualFetchStatus = new JLabel(errorImage);
160
161   protected JLabel lbl_fromFileStatus = new JLabel(errorImage);
162
163   protected AssciateSeqPanel phyre2InputAssSeqPanel = new AssciateSeqPanel();
164
165   protected AssciateSeqPanel idInputAssSeqPanel = new AssciateSeqPanel();
166
167   protected AssciateSeqPanel fileChooserAssSeqPanel = new AssciateSeqPanel();
168
169   protected static final String VIEWS_FILTER = "VIEWS_FILTER";
170
171   protected static final String VIEWS_FROM_FILE = "VIEWS_FROM_FILE";
172
173   protected static final String VIEWS_ENTER_ID = "VIEWS_ENTER_ID";
174
175   protected static final String VIEWS_LOCAL_PDB = "VIEWS_LOCAL_PDB";
176
177   protected static final String VIEWS_PHYRE2_PREDICTION = "VIEWS_PHYRE2_PREDICTION";
178
179   protected JTable tbl_local_pdb = new JTable();
180
181   protected JScrollPane scrl_localPDB = new JScrollPane(tbl_local_pdb);
182
183   protected JTabbedPane pnl_filter = new JTabbedPane();
184
185   protected FTSDataColumnPreferences pdbDocFieldPrefs = new FTSDataColumnPreferences(
186           PreferenceSource.STRUCTURE_CHOOSER,
187           PDBFTSRestClient.getInstance());
188
189   protected FTSDataColumnI[] previousWantedFields;
190
191   protected static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
192
193   private JTable tbl_summary = new JvSummaryTable(tempUserPrefs);
194
195
196   protected JScrollPane scrl_foundStructures = new JScrollPane(tbl_summary);
197
198   JPanel phyreResultPanel = new JPanel(new BorderLayout());
199   
200   protected static Map<String, Integer> tempPrefsForPhyre = new HashMap<String, Integer>();
201
202   private JTable tbl_phyre2_summary = new JvSummaryTable(tempPrefsForPhyre);
203
204   protected JScrollPane scrl_phyre2Summary = new JScrollPane(
205           tbl_phyre2_summary);
206
207   public GStructureChooser()
208   {
209     try
210     {
211       jbInit();
212       mainFrame.setVisible(false);
213       mainFrame.invalidate();
214       mainFrame.pack();
215     } catch (Exception e)
216     {
217       e.printStackTrace();
218     }
219   }
220
221   /**
222    * Initializes the GUI default properties
223    * 
224    * @throws Exception
225    */
226   @SuppressWarnings("unchecked")
227   private void jbInit() throws Exception
228   {
229     Integer width = tempUserPrefs.get("structureChooser.width") == null ? 800
230             : tempUserPrefs.get("structureChooser.width");
231     Integer height = tempUserPrefs.get("structureChooser.height") == null ? 400
232             : tempUserPrefs.get("structureChooser.height");
233     tbl_summary.setAutoCreateRowSorter(true);
234     tbl_summary.getTableHeader().setReorderingAllowed(false);
235     tbl_summary.addMouseListener(new MouseAdapter()
236     {
237       @Override
238       public void mouseClicked(MouseEvent e)
239       {
240         validateSelections();
241       }
242
243       @Override
244       public void mouseReleased(MouseEvent e)
245       {
246         validateSelections();
247       }
248     });
249     tbl_summary.addKeyListener(new KeyAdapter()
250     {
251       @Override
252       public void keyPressed(KeyEvent evt)
253       {
254         validateSelections();
255         switch (evt.getKeyCode())
256         {
257         case KeyEvent.VK_ESCAPE: // escape key
258           mainFrame.dispose();
259           break;
260         case KeyEvent.VK_ENTER: // enter key
261           if (btn_view.isEnabled())
262           {
263             ok_ActionPerformed();
264           }
265           break;
266         case KeyEvent.VK_TAB: // tab key
267           if (evt.isShiftDown())
268           {
269             pnl_filter.requestFocus();
270           }
271           else
272           {
273             btn_view.requestFocus();
274           }
275           evt.consume();
276           break;
277         default:
278           return;
279         }
280       }
281     });
282     tbl_local_pdb.setAutoCreateRowSorter(true);
283     tbl_local_pdb.getTableHeader().setReorderingAllowed(false);
284     tbl_local_pdb.addMouseListener(new MouseAdapter()
285     {
286       @Override
287       public void mouseClicked(MouseEvent e)
288       {
289         validateSelections();
290       }
291
292       @Override
293       public void mouseReleased(MouseEvent e)
294       {
295         validateSelections();
296       }
297     });
298     tbl_local_pdb.addKeyListener(new KeyAdapter()
299     {
300       @Override
301       public void keyPressed(KeyEvent evt)
302       {
303         validateSelections();
304         switch (evt.getKeyCode())
305         {
306         case KeyEvent.VK_ESCAPE: // escape key
307           mainFrame.dispose();
308           break;
309         case KeyEvent.VK_ENTER: // enter key
310           if (btn_view.isEnabled())
311           {
312             ok_ActionPerformed();
313           }
314           break;
315         case KeyEvent.VK_TAB: // tab key
316           if (evt.isShiftDown())
317           {
318             cmb_filterOption.requestFocus();
319           }
320           else
321           {
322             if (btn_view.isEnabled())
323             {
324               btn_view.requestFocus();
325             }
326             else
327             {
328               btn_cancel.requestFocus();
329             }
330           }
331           evt.consume();
332           break;
333         default:
334           return;
335         }
336       }
337     });
338     btn_view.setFont(new java.awt.Font("Verdana", 0, 12));
339     btn_view.setText(MessageManager.getString("action.view"));
340     btn_view.addActionListener(new java.awt.event.ActionListener()
341     {
342       @Override
343       public void actionPerformed(ActionEvent e)
344       {
345         ok_ActionPerformed();
346       }
347     });
348     btn_view.addKeyListener(new KeyAdapter()
349     {
350       @Override
351       public void keyPressed(KeyEvent evt)
352       {
353         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
354         {
355           ok_ActionPerformed();
356         }
357       }
358     });
359
360     btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12));
361     btn_cancel.setText(MessageManager.getString("action.cancel"));
362     btn_cancel.addActionListener(new java.awt.event.ActionListener()
363     {
364       @Override
365       public void actionPerformed(ActionEvent e)
366       {
367         closeAction(pnl_filter.getHeight());
368       }
369     });
370     btn_cancel.addKeyListener(new KeyAdapter()
371     {
372       @Override
373       public void keyPressed(KeyEvent evt)
374       {
375         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
376         {
377           closeAction(pnl_filter.getHeight());
378         }
379       }
380     });
381
382     btn_pdbFromFile.setFont(new java.awt.Font("Verdana", 0, 12));
383     String btn_title = MessageManager.getString("label.select_pdb_file");
384     btn_pdbFromFile.setText(btn_title + "              ");
385     btn_pdbFromFile.addActionListener(new java.awt.event.ActionListener()
386     {
387       @Override
388       public void actionPerformed(ActionEvent e)
389       {
390         pdbFromFile_actionPerformed();
391       }
392     });
393     btn_pdbFromFile.addKeyListener(new KeyAdapter()
394     {
395       @Override
396       public void keyPressed(KeyEvent evt)
397       {
398         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
399         {
400           pdbFromFile_actionPerformed();
401         }
402       }
403     });
404
405     btn_pdbFromFile.setFont(new java.awt.Font("Verdana", 0, 12));
406     tbl_phyre2_summary.setAutoCreateRowSorter(true);
407     tbl_phyre2_summary.getTableHeader().setReorderingAllowed(false);
408
409     tbl_phyre2_summary.addMouseListener(new MouseAdapter()
410     {
411       @Override
412       public void mouseClicked(MouseEvent e)
413       {
414         validateSelections();
415       }
416
417       @Override
418       public void mouseReleased(MouseEvent e)
419       {
420         validateSelections();
421       }
422     });
423     tbl_phyre2_summary.addKeyListener(new KeyAdapter()
424     {
425       @Override
426       public void keyPressed(KeyEvent evt)
427       {
428         validateSelections();
429         switch (evt.getKeyCode())
430         {
431         case KeyEvent.VK_ESCAPE: // escape key
432           mainFrame.dispose();
433           break;
434         case KeyEvent.VK_ENTER: // enter key
435           if (btn_view.isEnabled())
436           {
437             ok_ActionPerformed();
438           }
439           break;
440         case KeyEvent.VK_TAB: // tab key
441           if (evt.isShiftDown())
442           {
443             cmb_filterOption.requestFocus();
444           }
445           else
446           {
447             if (btn_view.isEnabled())
448             {
449               btn_view.requestFocus();
450             }
451             else
452             {
453               btn_cancel.requestFocus();
454             }
455           }
456           evt.consume();
457           break;
458         default:
459           return;
460         }
461       }
462     });
463
464     String btn_runPhyre2Prediction_title = MessageManager
465             .getString("label.run_phyre2_prediction");
466     btn_runPhyre2Prediction
467             .setText(btn_runPhyre2Prediction_title + "     ");
468     btn_runPhyre2Prediction
469             .addActionListener(new java.awt.event.ActionListener()
470             {
471               @Override
472               public void actionPerformed(ActionEvent e)
473               {
474                 predict3DModelWithPhyre2();
475               }
476             });
477     btn_runPhyre2Prediction.addKeyListener(new KeyAdapter()
478     {
479       @Override
480       public void keyPressed(KeyEvent evt)
481       {
482         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
483         {
484           predict3DModelWithPhyre2();
485         }
486       }
487     });
488
489     scrl_foundStructures.setPreferredSize(new Dimension(width, height));
490
491     scrl_localPDB.setPreferredSize(new Dimension(width, height));
492     scrl_localPDB
493             .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
494
495     cmb_filterOption.setFont(new java.awt.Font("Verdana", 0, 12));
496     chk_invertFilter.setFont(new java.awt.Font("Verdana", 0, 12));
497     chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12));
498     chk_rememberSettings.setVisible(false);
499     txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
500             MessageManager.getString("label.enter_pdb_id")));
501     cmb_filterOption.setToolTipText(MessageManager
502             .getString("info.select_filter_option"));
503     txt_search.getDocument().addDocumentListener(new DocumentListener()
504     {
505       @Override
506       public void insertUpdate(DocumentEvent e)
507       {
508         txt_search_ActionPerformed();
509       }
510
511       @Override
512       public void removeUpdate(DocumentEvent e)
513       {
514         txt_search_ActionPerformed();
515       }
516
517       @Override
518       public void changedUpdate(DocumentEvent e)
519       {
520         txt_search_ActionPerformed();
521       }
522     });
523
524     cmb_filterOption.addItemListener(this);
525
526     // add CustomComboSeparatorsRenderer to filter option combo-box
527     cmb_filterOption.setRenderer(new CustomComboSeparatorsRenderer(
528             (ListCellRenderer<Object>) cmb_filterOption.getRenderer())
529     {
530       @Override
531       protected boolean addSeparatorAfter(JList list, FilterOption value,
532               int index)
533       {
534         return value.isAddSeparatorAfter();
535       }
536     });
537
538     chk_invertFilter.addItemListener(this);
539
540     pnl_actions.add(chk_rememberSettings);
541     pnl_actions.add(btn_view);
542     pnl_actions.add(btn_cancel);
543
544     // pnl_filter.add(lbl_result);
545     pnl_main.add(cmb_filterOption);
546     pnl_main.add(lbl_loading);
547     pnl_main.add(chk_invertFilter);
548     lbl_loading.setVisible(false);
549
550     pnl_fileChooser.add(btn_pdbFromFile);
551     pnl_fileChooser.add(lbl_fromFileStatus);
552     pnl_fileChooserBL.add(fileChooserAssSeqPanel, BorderLayout.NORTH);
553     pnl_fileChooserBL.add(pnl_fileChooser, BorderLayout.CENTER);
554
555     scrl_phyre2Summary.setPreferredSize(new Dimension(width, height));
556     scrl_phyre2Summary
557             .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
558
559     phyreResultPanel.add(pnl_phyre2Prediction, BorderLayout.NORTH);
560     phyreResultPanel.add(scrl_phyre2Summary, BorderLayout.CENTER);
561
562     pnl_phyre2Prediction.add(btn_runPhyre2Prediction);
563     pnl_phyre2PredictionBL.add(phyre2InputAssSeqPanel, BorderLayout.NORTH);
564     pnl_phyre2PredictionBL.add(phyreResultPanel, BorderLayout.CENTER);
565
566     pnl_idInput.add(txt_search);
567     pnl_idInput.add(lbl_pdbManualFetchStatus);
568     pnl_idInputBL.add(idInputAssSeqPanel, BorderLayout.NORTH);
569     pnl_idInputBL.add(pnl_idInput, BorderLayout.CENTER);
570
571     final String foundStructureSummary = MessageManager
572             .getString("label.found_structures_summary");
573     final String configureCols = MessageManager
574             .getString("label.configure_displayed_columns");
575     ChangeListener changeListener = new ChangeListener()
576     {
577       @Override
578       public void stateChanged(ChangeEvent changeEvent)
579       {
580         JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
581                 .getSource();
582         int index = sourceTabbedPane.getSelectedIndex();
583         btn_view.setVisible(true);
584         btn_cancel.setVisible(true);
585         if (sourceTabbedPane.getTitleAt(index).equals(configureCols))
586         {
587           btn_view.setEnabled(false);
588           btn_cancel.setEnabled(false);
589           btn_view.setVisible(false);
590           btn_cancel.setVisible(false);
591           previousWantedFields = pdbDocFieldPrefs
592                   .getStructureSummaryFields().toArray(
593                           new FTSDataColumnI[0]);
594         }
595         if (sourceTabbedPane.getTitleAt(index)
596                 .equals(foundStructureSummary))
597         {
598           btn_cancel.setEnabled(true);
599           if (wantedFieldsUpdated())
600           {
601             tabRefresh();
602           }
603           else
604           {
605             validateSelections();
606           }
607         }
608       }
609     };
610     pnl_filter.addChangeListener(changeListener);
611     pnl_filter.setPreferredSize(new Dimension(width, height));
612     pnl_filter.add(foundStructureSummary, scrl_foundStructures);
613     pnl_filter.add(configureCols, pdbDocFieldPrefs);
614
615     pnl_locPDB.add(scrl_localPDB);
616
617     pnl_switchableViews.add(pnl_fileChooserBL, VIEWS_FROM_FILE);
618     pnl_switchableViews.add(pnl_idInputBL, VIEWS_ENTER_ID);
619     pnl_switchableViews.add(pnl_filter, VIEWS_FILTER);
620     pnl_switchableViews.add(pnl_locPDB, VIEWS_LOCAL_PDB);
621     pnl_switchableViews
622             .add(pnl_phyre2PredictionBL, VIEWS_PHYRE2_PREDICTION);
623
624     this.setLayout(mainLayout);
625     this.add(pnl_main, java.awt.BorderLayout.NORTH);
626     this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER);
627     // this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
628     statusPanel.setLayout(new GridLayout());
629     pnl_actionsAndStatus.add(pnl_actions, BorderLayout.CENTER);
630     pnl_actionsAndStatus.add(statusPanel, BorderLayout.SOUTH);
631     statusPanel.add(statusBar, null);
632     this.add(pnl_actionsAndStatus, java.awt.BorderLayout.SOUTH);
633
634     mainFrame
635             .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
636             {
637               @Override
638               public void internalFrameClosing(InternalFrameEvent e)
639               {
640                 closeAction(pnl_filter.getHeight());
641               }
642             });
643     mainFrame.setVisible(true);
644     mainFrame.setContentPane(this);
645     mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
646     Integer x = tempUserPrefs.get("structureChooser.x");
647     Integer y = tempUserPrefs.get("structureChooser.y");
648     if (x != null && y != null)
649     {
650       mainFrame.setLocation(x, y);
651     }
652     Desktop.addInternalFrame(mainFrame, frameTitle, width, height);
653   }
654
655   protected void closeAction(int preferredHeight)
656   {
657     // System.out.println(">>>>>>>>>> closing internal frame!!!");
658     // System.out.println("width : " + mainFrame.getWidth());
659     // System.out.println("heigh : " + mainFrame.getHeight());
660     // System.out.println("x : " + mainFrame.getX());
661     // System.out.println("y : " + mainFrame.getY());
662     tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
663     tempUserPrefs.put("structureChooser.height", preferredHeight);
664     tempUserPrefs.put("structureChooser.x", mainFrame.getX());
665     tempUserPrefs.put("structureChooser.y", mainFrame.getY());
666     mainFrame.dispose();
667   }
668
669   public boolean wantedFieldsUpdated()
670   {
671     if (previousWantedFields == null)
672     {
673       return true;
674     }
675
676     FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
677             .getStructureSummaryFields().toArray(new FTSDataColumnI[0]);
678     return Arrays.equals(currentWantedFields, previousWantedFields) ? false
679             : true;
680
681   }
682
683   @Override
684   /**
685    * Event listener for the 'filter' combo-box and 'invert' check-box
686    */
687   public void itemStateChanged(ItemEvent e)
688   {
689     stateChanged(e);
690   }
691
692   /**
693    * This inner class provides the data model for the structure filter combo-box
694    * 
695    * @author tcnofoegbu
696    *
697    */
698   public class FilterOption
699   {
700     private String name;
701
702     private String value;
703
704     private String view;
705
706     private boolean addSeparatorAfter;
707
708     public FilterOption(String name, String value, String view,
709             boolean addSeparatorAfter)
710     {
711       this.name = name;
712       this.value = value;
713       this.view = view;
714       this.addSeparatorAfter = addSeparatorAfter;
715     }
716
717     public String getName()
718     {
719       return name;
720     }
721
722     public void setName(String name)
723     {
724       this.name = name;
725     }
726
727     public String getValue()
728     {
729       return value;
730     }
731
732     public void setValue(String value)
733     {
734       this.value = value;
735     }
736
737     public String getView()
738     {
739       return view;
740     }
741
742     public void setView(String view)
743     {
744       this.view = view;
745     }
746
747     @Override
748     public String toString()
749     {
750       return this.name;
751     }
752
753     public boolean isAddSeparatorAfter()
754     {
755       return addSeparatorAfter;
756     }
757
758     public void setAddSeparatorAfter(boolean addSeparatorAfter)
759     {
760       this.addSeparatorAfter = addSeparatorAfter;
761     }
762   }
763
764   /**
765    * This inner class provides the provides the data model for associate
766    * sequence combo-box - cmb_assSeq
767    * 
768    * @author tcnofoegbu
769    *
770    */
771   public class AssociateSeqOptions
772   {
773     private SequenceI sequence;
774
775     private String name;
776
777     public AssociateSeqOptions(SequenceI seq)
778     {
779       this.sequence = seq;
780       this.name = (seq.getName().length() >= 23) ? seq.getName().substring(
781               0, 23) : seq.getName();
782     }
783
784     public AssociateSeqOptions(String name, SequenceI seq)
785     {
786       this.name = name;
787       this.sequence = seq;
788     }
789
790     @Override
791     public String toString()
792     {
793       return name;
794     }
795
796     public String getName()
797     {
798       return name;
799     }
800
801     public void setName(String name)
802     {
803       this.name = name;
804     }
805
806     public SequenceI getSequence()
807     {
808       return sequence;
809     }
810
811     public void setSequence(SequenceI sequence)
812     {
813       this.sequence = sequence;
814     }
815
816   }
817
818   /**
819    * This inner class holds the Layout and configuration of the panel which
820    * handles association of manually fetched structures to a unique sequence
821    * when more than one sequence selection is made
822    * 
823    * @author tcnofoegbu
824    *
825    */
826   public class AssciateSeqPanel extends JPanel implements ItemListener
827   {
828     private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
829
830     private JLabel lbl_associateSeq = new JLabel();
831
832     public AssciateSeqPanel()
833     {
834       this.setLayout(new FlowLayout());
835       this.add(cmb_assSeq);
836       this.add(lbl_associateSeq);
837       cmb_assSeq.setToolTipText(MessageManager
838               .getString("info.associate_wit_sequence"));
839       cmb_assSeq.addItemListener(this);
840     }
841
842     public void loadCmbAssSeq()
843     {
844       populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq);
845     }
846
847     public JComboBox<AssociateSeqOptions> getCmb_assSeq()
848     {
849       return cmb_assSeq;
850     }
851
852     public void setCmb_assSeq(JComboBox<AssociateSeqOptions> cmb_assSeq)
853     {
854       this.cmb_assSeq = cmb_assSeq;
855     }
856
857     @Override
858     public void itemStateChanged(ItemEvent e)
859     {
860       if (e.getStateChange() == ItemEvent.SELECTED)
861       {
862         cmbAssSeqStateChanged();
863       }
864     }
865   }
866
867   public JTable getResultTable()
868   {
869     return tbl_summary;
870   }
871
872   public JComboBox<FilterOption> getCmbFilterOption()
873   {
874     return cmb_filterOption;
875   }
876
877
878   public JTable getPhyreResultTable()
879   {
880     return tbl_phyre2_summary;
881   }
882
883   public abstract class CustomComboSeparatorsRenderer implements
884           ListCellRenderer<Object>
885   {
886     private ListCellRenderer<Object> regent;
887
888     private JPanel separatorPanel = new JPanel(new BorderLayout());
889
890     private JSeparator jSeparator = new JSeparator();
891
892     public CustomComboSeparatorsRenderer(ListCellRenderer<Object> listCellRenderer)
893     {
894       this.regent = listCellRenderer;
895     }
896
897     @Override
898     public Component getListCellRendererComponent(JList list,
899             Object value,
900             int index, boolean isSelected, boolean cellHasFocus)
901     {
902
903       Component comp = regent.getListCellRendererComponent(list, value,
904               index, isSelected, cellHasFocus);
905       if (index != -1
906               && addSeparatorAfter(list, (FilterOption) value, index))
907       { 
908         separatorPanel.removeAll();
909         separatorPanel.add(comp, BorderLayout.CENTER);
910         separatorPanel.add(jSeparator, BorderLayout.SOUTH);
911         return separatorPanel;
912       }
913       else
914       {
915         return comp;
916       }
917     }
918
919     protected abstract boolean addSeparatorAfter(JList list,
920             FilterOption value,
921             int index);
922   }
923
924   protected abstract void stateChanged(ItemEvent e);
925
926   protected abstract void ok_ActionPerformed();
927
928   protected abstract void pdbFromFile_actionPerformed();
929
930   protected abstract void txt_search_ActionPerformed();
931
932   public abstract void populateCmbAssociateSeqOptions(
933           JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq);
934
935   public abstract void cmbAssSeqStateChanged();
936
937   public abstract void tabRefresh();
938
939   public abstract void validateSelections();
940
941   public abstract void predict3DModelWithPhyre2();
942
943 }