e4e73d18f4038f857af017e5f8f11a3141c73155
[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     tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
658     tempUserPrefs.put("structureChooser.height",
659             pnl_filter.getHeight() - 76);
660     tempUserPrefs.put("structureChooser.x", mainFrame.getX());
661     tempUserPrefs.put("structureChooser.y", mainFrame.getY());
662     mainFrame.dispose();
663   }
664
665   public boolean wantedFieldsUpdated()
666   {
667     if (previousWantedFields == null)
668     {
669       return true;
670     }
671
672     FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
673             .getStructureSummaryFields().toArray(new FTSDataColumnI[0]);
674     return Arrays.equals(currentWantedFields, previousWantedFields) ? false
675             : true;
676
677   }
678
679   @Override
680   /**
681    * Event listener for the 'filter' combo-box and 'invert' check-box
682    */
683   public void itemStateChanged(ItemEvent e)
684   {
685     stateChanged(e);
686   }
687
688   /**
689    * This inner class provides the data model for the structure filter combo-box
690    * 
691    * @author tcnofoegbu
692    *
693    */
694   public class FilterOption
695   {
696     private String name;
697
698     private String value;
699
700     private String view;
701
702     private boolean addSeparatorAfter;
703
704     public FilterOption(String name, String value, String view,
705             boolean addSeparatorAfter)
706     {
707       this.name = name;
708       this.value = value;
709       this.view = view;
710       this.addSeparatorAfter = addSeparatorAfter;
711     }
712
713     public String getName()
714     {
715       return name;
716     }
717
718     public void setName(String name)
719     {
720       this.name = name;
721     }
722
723     public String getValue()
724     {
725       return value;
726     }
727
728     public void setValue(String value)
729     {
730       this.value = value;
731     }
732
733     public String getView()
734     {
735       return view;
736     }
737
738     public void setView(String view)
739     {
740       this.view = view;
741     }
742
743     @Override
744     public String toString()
745     {
746       return this.name;
747     }
748
749     public boolean isAddSeparatorAfter()
750     {
751       return addSeparatorAfter;
752     }
753
754     public void setAddSeparatorAfter(boolean addSeparatorAfter)
755     {
756       this.addSeparatorAfter = addSeparatorAfter;
757     }
758   }
759
760   /**
761    * This inner class provides the provides the data model for associate
762    * sequence combo-box - cmb_assSeq
763    * 
764    * @author tcnofoegbu
765    *
766    */
767   public class AssociateSeqOptions
768   {
769     private SequenceI sequence;
770
771     private String name;
772
773     public AssociateSeqOptions(SequenceI seq)
774     {
775       this.sequence = seq;
776       this.name = (seq.getName().length() >= 23) ? seq.getName().substring(
777               0, 23) : seq.getName();
778     }
779
780     public AssociateSeqOptions(String name, SequenceI seq)
781     {
782       this.name = name;
783       this.sequence = seq;
784     }
785
786     @Override
787     public String toString()
788     {
789       return name;
790     }
791
792     public String getName()
793     {
794       return name;
795     }
796
797     public void setName(String name)
798     {
799       this.name = name;
800     }
801
802     public SequenceI getSequence()
803     {
804       return sequence;
805     }
806
807     public void setSequence(SequenceI sequence)
808     {
809       this.sequence = sequence;
810     }
811
812   }
813
814   /**
815    * This inner class holds the Layout and configuration of the panel which
816    * handles association of manually fetched structures to a unique sequence
817    * when more than one sequence selection is made
818    * 
819    * @author tcnofoegbu
820    *
821    */
822   public class AssciateSeqPanel extends JPanel implements ItemListener
823   {
824     private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
825
826     private JLabel lbl_associateSeq = new JLabel();
827
828     public AssciateSeqPanel()
829     {
830       this.setLayout(new FlowLayout());
831       this.add(cmb_assSeq);
832       this.add(lbl_associateSeq);
833       cmb_assSeq.setToolTipText(MessageManager
834               .getString("info.associate_wit_sequence"));
835       cmb_assSeq.addItemListener(this);
836     }
837
838     public void loadCmbAssSeq()
839     {
840       populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq);
841     }
842
843     public JComboBox<AssociateSeqOptions> getCmb_assSeq()
844     {
845       return cmb_assSeq;
846     }
847
848     public void setCmb_assSeq(JComboBox<AssociateSeqOptions> cmb_assSeq)
849     {
850       this.cmb_assSeq = cmb_assSeq;
851     }
852
853     @Override
854     public void itemStateChanged(ItemEvent e)
855     {
856       if (e.getStateChange() == ItemEvent.SELECTED)
857       {
858         cmbAssSeqStateChanged();
859       }
860     }
861   }
862
863   public JTable getResultTable()
864   {
865     return tbl_summary;
866   }
867
868   public JComboBox<FilterOption> getCmbFilterOption()
869   {
870     return cmb_filterOption;
871   }
872
873
874   public JTable getPhyreResultTable()
875   {
876     return tbl_phyre2_summary;
877   }
878
879   public abstract class CustomComboSeparatorsRenderer implements
880           ListCellRenderer<Object>
881   {
882     private ListCellRenderer<Object> regent;
883
884     private JPanel separatorPanel = new JPanel(new BorderLayout());
885
886     private JSeparator jSeparator = new JSeparator();
887
888     public CustomComboSeparatorsRenderer(ListCellRenderer<Object> listCellRenderer)
889     {
890       this.regent = listCellRenderer;
891     }
892
893     @Override
894     public Component getListCellRendererComponent(JList list,
895             Object value,
896             int index, boolean isSelected, boolean cellHasFocus)
897     {
898
899       Component comp = regent.getListCellRendererComponent(list, value,
900               index, isSelected, cellHasFocus);
901       if (index != -1
902               && addSeparatorAfter(list, (FilterOption) value, index))
903       { 
904         separatorPanel.removeAll();
905         separatorPanel.add(comp, BorderLayout.CENTER);
906         separatorPanel.add(jSeparator, BorderLayout.SOUTH);
907         return separatorPanel;
908       }
909       else
910       {
911         return comp;
912       }
913     }
914
915     protected abstract boolean addSeparatorAfter(JList list,
916             FilterOption value,
917             int index);
918   }
919
920   protected abstract void stateChanged(ItemEvent e);
921
922   protected abstract void ok_ActionPerformed();
923
924   protected abstract void pdbFromFile_actionPerformed();
925
926   protected abstract void txt_search_ActionPerformed();
927
928   public abstract void populateCmbAssociateSeqOptions(
929           JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq);
930
931   public abstract void cmbAssSeqStateChanged();
932
933   public abstract void tabRefresh();
934
935   public abstract void validateSelections();
936
937   public abstract void predict3DModelWithPhyre2();
938
939 }