JAL-2183 don't open two free text panels; give input field focus
[jalview.git] / src / jalview / fts / core / GFTSPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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.fts.core;
23
24 import jalview.fts.api.FTSDataColumnI;
25 import jalview.fts.api.GFTSPanelI;
26 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
27 import jalview.gui.Desktop;
28 import jalview.gui.IProgressIndicator;
29 import jalview.gui.JvSwingUtils;
30 import jalview.gui.SequenceFetcher;
31 import jalview.util.MessageManager;
32
33 import java.awt.BorderLayout;
34 import java.awt.CardLayout;
35 import java.awt.Dimension;
36 import java.awt.event.ActionEvent;
37 import java.awt.event.ActionListener;
38 import java.awt.event.FocusAdapter;
39 import java.awt.event.FocusEvent;
40 import java.awt.event.FocusListener;
41 import java.awt.event.KeyAdapter;
42 import java.awt.event.KeyEvent;
43 import java.awt.event.MouseAdapter;
44 import java.awt.event.MouseEvent;
45 import java.text.DecimalFormat;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Collection;
49 import java.util.Collections;
50 import java.util.Comparator;
51 import java.util.HashSet;
52 import java.util.List;
53
54 import javax.swing.ImageIcon;
55 import javax.swing.JButton;
56 import javax.swing.JComboBox;
57 import javax.swing.JFrame;
58 import javax.swing.JInternalFrame;
59 import javax.swing.JLabel;
60 import javax.swing.JPanel;
61 import javax.swing.JScrollPane;
62 import javax.swing.JTabbedPane;
63 import javax.swing.JTable;
64 import javax.swing.JTextField;
65 import javax.swing.Timer;
66 import javax.swing.event.ChangeEvent;
67 import javax.swing.event.ChangeListener;
68 import javax.swing.event.DocumentEvent;
69 import javax.swing.event.DocumentListener;
70 import javax.swing.event.InternalFrameEvent;
71 import javax.swing.table.DefaultTableModel;
72 import javax.swing.table.TableColumn;
73
74 /**
75  * This class provides the swing GUI layout for FTS Panel and implements most of
76  * the contracts defined in GFSPanelI
77  * 
78  * @author tcnofoegbu
79  *
80  */
81
82 @SuppressWarnings("serial")
83 public abstract class GFTSPanel extends JPanel implements GFTSPanelI
84 {
85   protected JInternalFrame mainFrame = new JInternalFrame(
86           getFTSFrameTitle());
87
88   protected IProgressIndicator progressIndicator;
89
90   protected JComboBox<FTSDataColumnI> cmb_searchTarget = new JComboBox<FTSDataColumnI>();
91
92   protected JButton btn_ok = new JButton();
93
94   protected JButton btn_back = new JButton();
95
96   protected JButton btn_cancel = new JButton();
97
98   protected JTextField txt_search = new JTextField(30);
99
100   protected SequenceFetcher seqFetcher;
101
102   protected Collection<FTSDataColumnI> wantedFields;
103
104   private String lastSearchTerm = "";
105
106   protected JButton btn_next_page = new JButton();
107
108   protected JButton btn_prev_page = new JButton();
109
110   protected StringBuilder errorWarning = new StringBuilder();
111
112   protected ImageIcon warningImage = new ImageIcon(getClass().getResource(
113           "/images/warning.gif"));
114
115   protected ImageIcon loadingImage = new ImageIcon(getClass().getResource(
116           "/images/loading.gif"));
117
118   protected ImageIcon balnkPlaceholderImage = new ImageIcon(getClass()
119           .getResource("/images/blank_16x16_placeholder.png"));
120
121   protected JLabel lbl_warning = new JLabel(warningImage);
122
123   protected JLabel lbl_loading = new JLabel(loadingImage);
124
125   protected JLabel lbl_blank = new JLabel(balnkPlaceholderImage);
126
127   private JTabbedPane tabbedPane = new JTabbedPane();
128
129   private JPanel pnl_actions = new JPanel();
130
131   private JPanel pnl_results = new JPanel(new CardLayout());
132
133   private JPanel pnl_inputs = new JPanel();
134
135   private BorderLayout mainLayout = new BorderLayout();
136
137   protected Object[] previousWantedFields;
138
139   protected int resultSetCount;
140
141   protected int totalResultSetCount;
142
143   protected int offSet;
144
145   protected int pageLimit;
146
147   protected HashSet<String> paginatorCart = new HashSet<String>();
148
149   protected static final DecimalFormat totalNumberformatter = new DecimalFormat(
150           "###,###");
151   private JTable tbl_summary = new JTable()
152   {
153     private boolean inLayout;
154
155     @Override
156     public boolean getScrollableTracksViewportWidth()
157     {
158       return hasExcessWidth();
159
160     }
161
162     @Override
163     public void doLayout()
164     {
165       if (hasExcessWidth())
166       {
167         autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
168       }
169       inLayout = true;
170       super.doLayout();
171       inLayout = false;
172       autoResizeMode = AUTO_RESIZE_OFF;
173     }
174
175     protected boolean hasExcessWidth()
176     {
177       return getPreferredSize().width < getParent().getWidth();
178     }
179
180     @Override
181     public void columnMarginChanged(ChangeEvent e)
182     {
183       if (isEditing())
184       {
185         removeEditor();
186       }
187       TableColumn resizingColumn = getTableHeader().getResizingColumn();
188       // Need to do this here, before the parent's
189       // layout manager calls getPreferredSize().
190       if (resizingColumn != null && autoResizeMode == AUTO_RESIZE_OFF
191               && !inLayout)
192       {
193         resizingColumn.setPreferredWidth(resizingColumn.getWidth());
194         String colHeader = resizingColumn.getHeaderValue().toString();
195         getTempUserPrefs().put(colHeader, resizingColumn.getWidth());
196       }
197       resizeAndRepaint();
198     }
199
200     @Override
201     public String getToolTipText(MouseEvent evt)
202     {
203       String toolTipText = null;
204       java.awt.Point pnt = evt.getPoint();
205       int rowIndex = rowAtPoint(pnt);
206       int colIndex = columnAtPoint(pnt);
207
208       try
209       {
210         if (getValueAt(rowIndex, colIndex) == null)
211         {
212           return null;
213         }
214         toolTipText = getValueAt(rowIndex, colIndex).toString();
215
216       } catch (Exception e)
217       {
218         e.printStackTrace();
219       }
220       toolTipText = (toolTipText == null ? null
221               : (toolTipText.length() > 500 ? JvSwingUtils.wrapTooltip(
222                       true, toolTipText.subSequence(0, 500) + "...")
223                       : JvSwingUtils.wrapTooltip(true, toolTipText)));
224
225       return toolTipText;
226     }
227   };
228   protected JScrollPane scrl_searchResult = new JScrollPane(tbl_summary);
229
230   public GFTSPanel()
231   {
232     try
233     {
234       jbInit();
235       mainFrame.addFocusListener(new FocusAdapter()
236       {
237         @Override
238         public void focusGained(FocusEvent e)
239         {
240           txt_search.requestFocusInWindow();
241         }
242       });
243       mainFrame.invalidate();
244       mainFrame.pack();
245     } catch (Exception e)
246     {
247       e.printStackTrace();
248     }
249   }
250
251   /**
252    * Initializes the GUI default properties
253    * 
254    * @throws Exception
255    */
256   private void jbInit() throws Exception
257   {
258     Integer width = getTempUserPrefs().get("FTSPanel.width") == null ? 800
259             : getTempUserPrefs().get("FTSPanel.width");
260     Integer height = getTempUserPrefs().get("FTSPanel.height") == null ? 400
261             : getTempUserPrefs().get("FTSPanel.height");
262     lbl_warning.setVisible(false);
263     lbl_warning.setFont(new java.awt.Font("Verdana", 0, 12));
264     lbl_loading.setVisible(false);
265     lbl_loading.setFont(new java.awt.Font("Verdana", 0, 12));
266     lbl_blank.setVisible(true);
267     lbl_blank.setFont(new java.awt.Font("Verdana", 0, 12));
268
269     tbl_summary.setAutoCreateRowSorter(true);
270     tbl_summary.getTableHeader().setReorderingAllowed(false);
271     tbl_summary.addMouseListener(new MouseAdapter()
272     {
273       @Override
274       public void mouseClicked(MouseEvent e)
275       {
276         validateSelection();
277       }
278
279       @Override
280       public void mouseReleased(MouseEvent e)
281       {
282         validateSelection();
283       }
284     });
285     tbl_summary.addKeyListener(new KeyAdapter()
286     {
287       @Override
288       public void keyPressed(KeyEvent evt)
289       {
290         validateSelection();
291         switch (evt.getKeyCode())
292         {
293         case KeyEvent.VK_ESCAPE: // escape key
294           btn_back_ActionPerformed();
295           break;
296         case KeyEvent.VK_ENTER: // enter key
297           if (btn_ok.isEnabled())
298           {
299             okAction();
300           }
301           evt.consume();
302           break;
303         case KeyEvent.VK_TAB: // tab key
304           if (evt.isShiftDown())
305           {
306             tabbedPane.requestFocus();
307           }
308           else
309           {
310             btn_back.requestFocus();
311           }
312           evt.consume();
313           break;
314         default:
315           return;
316         }
317       }
318     });
319
320     btn_back.setFont(new java.awt.Font("Verdana", 0, 12));
321     btn_back.setText(MessageManager.getString("action.back"));
322     btn_back.addActionListener(new java.awt.event.ActionListener()
323     {
324       @Override
325       public void actionPerformed(ActionEvent e)
326       {
327         btn_back_ActionPerformed();
328       }
329     });
330     btn_back.addKeyListener(new KeyAdapter()
331     {
332       @Override
333       public void keyPressed(KeyEvent evt)
334       {
335         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
336         {
337           btn_back_ActionPerformed();
338         }
339       }
340     });
341
342     btn_ok.setEnabled(false);
343     btn_ok.setFont(new java.awt.Font("Verdana", 0, 12));
344     btn_ok.setText(MessageManager.getString("action.ok"));
345     btn_ok.addActionListener(new java.awt.event.ActionListener()
346     {
347       @Override
348       public void actionPerformed(ActionEvent e)
349       {
350         okAction();
351       }
352     });
353     btn_ok.addKeyListener(new KeyAdapter()
354     {
355       @Override
356       public void keyPressed(KeyEvent evt)
357       {
358         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
359         {
360           okAction();
361         }
362       }
363     });
364     btn_next_page.setEnabled(false);
365     btn_next_page.setToolTipText(MessageManager
366             .getString("label.next_page_tooltip"));
367     btn_next_page.setFont(new java.awt.Font("Verdana", 0, 12));
368     btn_next_page.setText(MessageManager.getString("action.next_page"));
369     btn_next_page.addActionListener(new java.awt.event.ActionListener()
370     {
371       @Override
372       public void actionPerformed(ActionEvent e)
373       {
374         nextPageAction();
375       }
376     });
377     btn_next_page.addKeyListener(new KeyAdapter()
378     {
379       @Override
380       public void keyPressed(KeyEvent evt)
381       {
382         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
383         {
384           nextPageAction();
385         }
386       }
387     });
388
389     btn_prev_page.setEnabled(false);
390     btn_prev_page.setToolTipText(MessageManager
391             .getString("label.prev_page_tooltip"));
392     btn_prev_page.setFont(new java.awt.Font("Verdana", 0, 12));
393     btn_prev_page.setText(MessageManager.getString("action.prev_page"));
394     btn_prev_page.addActionListener(new java.awt.event.ActionListener()
395     {
396       @Override
397       public void actionPerformed(ActionEvent e)
398       {
399         prevPageAction();
400       }
401     });
402     btn_prev_page.addKeyListener(new KeyAdapter()
403     {
404       @Override
405       public void keyPressed(KeyEvent evt)
406       {
407         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
408         {
409           prevPageAction();
410         }
411       }
412     });
413
414     if (isPaginationEnabled())
415     {
416       btn_prev_page.setVisible(true);
417       btn_next_page.setVisible(true);
418     }
419     else
420     {
421       btn_prev_page.setVisible(false);
422       btn_next_page.setVisible(false);
423     }
424
425     btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12));
426     btn_cancel.setText(MessageManager.getString("action.cancel"));
427     btn_cancel.addActionListener(new java.awt.event.ActionListener()
428     {
429       @Override
430       public void actionPerformed(ActionEvent e)
431       {
432         btn_cancel_ActionPerformed();
433       }
434     });
435     btn_cancel.addKeyListener(new KeyAdapter()
436     {
437       @Override
438       public void keyPressed(KeyEvent evt)
439       {
440         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
441         {
442           btn_cancel_ActionPerformed();
443         }
444       }
445     });
446     scrl_searchResult.setPreferredSize(new Dimension(width, height));
447
448     cmb_searchTarget.setFont(new java.awt.Font("Verdana", 0, 12));
449     cmb_searchTarget.addActionListener(new ActionListener()
450     {
451       @Override
452       public void actionPerformed(ActionEvent e)
453       {
454         String tooltipText;
455         if ("all".equalsIgnoreCase(getCmbSearchTarget().getSelectedItem()
456                 .toString()))
457         {
458           tooltipText = MessageManager.getString("label.search_all");
459         }
460         else if ("pdb id".equalsIgnoreCase(getCmbSearchTarget()
461                 .getSelectedItem().toString()))
462         {
463           tooltipText = MessageManager
464                   .getString("label.separate_multiple_accession_ids");
465         }
466         else
467         {
468           tooltipText = MessageManager.formatMessage(
469                   "label.separate_multiple_query_values",
470                   new Object[] { getCmbSearchTarget().getSelectedItem()
471                           .toString() });
472         }
473         txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
474                 tooltipText));
475         searchAction(true);
476       }
477     });
478
479     populateCmbSearchTargetOptions();
480
481     txt_search.setFont(new java.awt.Font("Verdana", 0, 12));
482
483     txt_search.addKeyListener(new KeyAdapter()
484     {
485       @Override
486       public void keyPressed(KeyEvent e)
487       {
488         if (e.getKeyCode() == KeyEvent.VK_ENTER)
489         {
490           if (txt_search.getText() == null
491                   || txt_search.getText().isEmpty())
492           {
493             return;
494           }
495           String primaryKeyName = getFTSRestClient().getPrimaryKeyColumn()
496                   .getName();
497           if (primaryKeyName.equalsIgnoreCase(getCmbSearchTarget()
498                   .getSelectedItem().toString()))
499           {
500             transferToSequenceFetcher(txt_search.getText());
501           }
502         }
503       }
504     });
505
506     final DeferredTextInputListener listener = new DeferredTextInputListener(
507             1500,
508             new ActionListener()
509             {
510               @Override
511               public void actionPerformed(ActionEvent e)
512               {
513                 if (!getTypedText().equalsIgnoreCase(lastSearchTerm))
514                 {
515                   searchAction(true);
516                   paginatorCart.clear();
517                   lastSearchTerm = getTypedText();
518                 }
519               }
520             }, false);
521     txt_search.getDocument().addDocumentListener(listener);
522     txt_search.addFocusListener(new FocusListener()
523     {
524       @Override
525       public void focusGained(FocusEvent e)
526       {
527         listener.start();
528       }
529
530       @Override
531       public void focusLost(FocusEvent e)
532       {
533 //        listener.stop();
534       }
535     });
536
537     final String searchTabTitle = MessageManager
538             .getString("label.search_result");
539     final String configureCols = MessageManager
540             .getString("label.configure_displayed_columns");
541     ChangeListener changeListener = new ChangeListener()
542     {
543       @Override
544       public void stateChanged(ChangeEvent changeEvent)
545       {
546         JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
547                 .getSource();
548         int index = sourceTabbedPane.getSelectedIndex();
549
550         btn_back.setVisible(true);
551         btn_cancel.setVisible(true);
552         btn_ok.setVisible(true);
553         if (sourceTabbedPane.getTitleAt(index).equals(configureCols))
554         {
555           btn_back.setVisible(false);
556           btn_cancel.setVisible(false);
557           btn_ok.setVisible(false);
558           btn_back.setEnabled(false);
559           btn_cancel.setEnabled(false);
560           btn_ok.setEnabled(false);
561           btn_next_page.setEnabled(false);
562           btn_prev_page.setEnabled(false);
563           txt_search.setEnabled(false);
564           cmb_searchTarget.setEnabled(false);
565           previousWantedFields = getFTSRestClient()
566                   .getAllDefaultDisplayedFTSDataColumns()
567                   .toArray(new Object[0]);
568         }
569         if (sourceTabbedPane.getTitleAt(index).equals(searchTabTitle))
570         {
571           btn_back.setEnabled(true);
572           btn_cancel.setEnabled(true);
573           refreshPaginatorState();
574           txt_search.setEnabled(true);
575           cmb_searchTarget.setEnabled(true);
576           if (wantedFieldsUpdated())
577           {
578             searchAction(true);
579             paginatorCart.clear();
580           }
581           else
582           {
583             validateSelection();
584           }
585         }
586       }
587     };
588     tabbedPane.addChangeListener(changeListener);
589     tabbedPane.setPreferredSize(new Dimension(width, height));
590     tabbedPane.add(searchTabTitle, scrl_searchResult);
591     tabbedPane.add(configureCols, new FTSDataColumnPreferences(
592             PreferenceSource.SEARCH_SUMMARY, getFTSRestClient()));
593
594     pnl_actions.add(btn_back);
595     pnl_actions.add(btn_ok);
596     pnl_actions.add(btn_cancel);
597
598     pnl_results.add(tabbedPane);
599     pnl_inputs.add(cmb_searchTarget);
600     pnl_inputs.add(txt_search);
601     pnl_inputs.add(lbl_loading);
602     pnl_inputs.add(lbl_warning);
603     pnl_inputs.add(lbl_blank);
604     pnl_inputs.add(btn_prev_page);
605     pnl_inputs.add(btn_next_page);
606
607     this.setLayout(mainLayout);
608     this.add(pnl_inputs, java.awt.BorderLayout.NORTH);
609     this.add(pnl_results, java.awt.BorderLayout.CENTER);
610     this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
611     mainFrame.setVisible(true);
612     mainFrame.setContentPane(this);
613     mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
614     mainFrame
615             .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
616             {
617               @Override
618               public void internalFrameClosing(InternalFrameEvent e)
619               {
620                 closeAction();
621               }
622             });
623     mainFrame.setVisible(true);
624     mainFrame.setContentPane(this);
625     mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
626     Integer x = getTempUserPrefs().get("FTSPanel.x");
627     Integer y = getTempUserPrefs().get("FTSPanel.y");
628     if (x != null && y != null)
629     {
630       mainFrame.setLocation(x, y);
631     }
632     Desktop.addInternalFrame(mainFrame, getFTSFrameTitle(), width, height);
633   }
634
635   protected void closeAction()
636   {
637     // System.out.println(">>>>>>>>>> closing internal frame!!!");
638     // System.out.println("width : " + this.getWidth());
639     // System.out.println("heigh : " + this.getHeight());
640     // System.out.println("x : " + mainFrame.getX());
641     // System.out.println("y : " + mainFrame.getY());
642     getTempUserPrefs().put("FTSPanel.width", this.getWidth());
643     getTempUserPrefs().put("FTSPanel.height", pnl_results.getHeight());
644     getTempUserPrefs().put("FTSPanel.x", mainFrame.getX());
645     getTempUserPrefs().put("FTSPanel.y", mainFrame.getY());
646     mainFrame.dispose();
647   }
648   public class DeferredTextInputListener implements DocumentListener
649   {
650     private final Timer swingTimer;
651
652     public DeferredTextInputListener(int timeOut, ActionListener listener,
653             boolean repeats)
654     {
655       swingTimer = new Timer(timeOut, listener);
656       swingTimer.setRepeats(repeats);
657     }
658
659     public void start()
660     {
661       swingTimer.start();
662     }
663
664     public void stop()
665     {
666       swingTimer.stop();
667     }
668
669     @Override
670     public void insertUpdate(DocumentEvent e)
671     {
672       swingTimer.restart();
673     }
674
675     @Override
676     public void removeUpdate(DocumentEvent e)
677     {
678       swingTimer.restart();
679     }
680
681     @Override
682     public void changedUpdate(DocumentEvent e)
683     {
684       swingTimer.restart();
685     }
686
687   }
688
689   public boolean wantedFieldsUpdated()
690   {
691     if (previousWantedFields == null)
692     {
693       return true;
694     }
695
696     return Arrays.equals(getFTSRestClient()
697             .getAllDefaultDisplayedFTSDataColumns()
698             .toArray(new Object[0]), previousWantedFields) ? false
699             : true;
700
701   }
702
703   public void validateSelection()
704   {
705     if (tbl_summary.getSelectedRows().length > 0
706             || !paginatorCart.isEmpty())
707     {
708       btn_ok.setEnabled(true);
709     }
710     else
711     {
712       btn_ok.setEnabled(false);
713     }
714   }
715
716   public JComboBox<FTSDataColumnI> getCmbSearchTarget()
717   {
718     return cmb_searchTarget;
719   }
720
721   public JTextField getTxtSearch()
722   {
723     return txt_search;
724   }
725
726   public JInternalFrame getMainFrame()
727   {
728     return mainFrame;
729   }
730
731   protected void delayAndEnableActionButtons()
732   {
733     new Thread()
734     {
735       @Override
736       public void run()
737       {
738         try
739         {
740           Thread.sleep(1500);
741         } catch (InterruptedException e)
742         {
743           e.printStackTrace();
744         }
745         btn_ok.setEnabled(true);
746         btn_back.setEnabled(true);
747         btn_cancel.setEnabled(true);
748       }
749     }.start();
750   }
751
752   protected void checkForErrors()
753   {
754     lbl_warning.setVisible(false);
755     lbl_blank.setVisible(true);
756     if (errorWarning.length() > 0)
757     {
758       lbl_loading.setVisible(false);
759       lbl_blank.setVisible(false);
760       lbl_warning.setToolTipText(JvSwingUtils.wrapTooltip(true,
761               errorWarning.toString()));
762       lbl_warning.setVisible(true);
763     }
764   }
765
766   protected void btn_back_ActionPerformed()
767   {
768     closeAction();
769     new SequenceFetcher(progressIndicator);
770   }
771
772   protected void disableActionButtons()
773   {
774     btn_ok.setEnabled(false);
775     btn_back.setEnabled(false);
776     btn_cancel.setEnabled(false);
777   }
778
779   protected void btn_cancel_ActionPerformed()
780   {
781     closeAction();
782   }
783
784   /**
785    * Populates search target combo-box options
786    */
787   public void populateCmbSearchTargetOptions()
788   {
789     List<FTSDataColumnI> searchableTargets = new ArrayList<FTSDataColumnI>();
790     try
791     {
792       Collection<FTSDataColumnI> foundFTSTargets = getFTSRestClient()
793               .getSearchableDataColumns();
794       searchableTargets.addAll(foundFTSTargets);
795     } catch (Exception e)
796     {
797       e.printStackTrace();
798     }
799
800     Collections.sort(searchableTargets, new Comparator<FTSDataColumnI>()
801     {
802       @Override
803       public int compare(FTSDataColumnI o1, FTSDataColumnI o2)
804       {
805         return o1.getName().compareTo(o2.getName());
806       }
807     });
808
809     for (FTSDataColumnI searchTarget : searchableTargets)
810     {
811       cmb_searchTarget.addItem(searchTarget);
812     }
813   }
814
815
816   public void transferToSequenceFetcher(String ids)
817   {
818     // mainFrame.dispose();
819     seqFetcher.getTextArea().setText(ids);
820     Thread worker = new Thread(seqFetcher);
821     worker.start();
822   }
823
824   @Override
825   public String getTypedText()
826   {
827     return txt_search.getText().trim();
828   }
829
830   @Override
831   public JTable getResultTable()
832   {
833     return tbl_summary;
834   }
835
836   public void reset()
837   {
838     lbl_loading.setVisible(false);
839     errorWarning.setLength(0);
840     lbl_warning.setVisible(false);
841     lbl_blank.setVisible(true);
842     btn_ok.setEnabled(false);
843     mainFrame.setTitle(getFTSFrameTitle());
844     referesh();
845     tbl_summary.setModel(new DefaultTableModel());
846     tbl_summary.setVisible(false);
847   }
848
849   @Override
850   public void setPrevPageButtonEnabled(boolean isEnabled)
851   {
852     btn_prev_page.setEnabled(isEnabled);
853   }
854
855   @Override
856   public void setNextPageButtonEnabled(boolean isEnabled)
857   {
858     btn_next_page.setEnabled(isEnabled);
859   }
860
861   @Override
862   public void setErrorMessage(String message)
863   {
864     errorWarning.append(message);
865   }
866
867   @Override
868   public void updateSearchFrameTitle(String title)
869   {
870     mainFrame.setTitle(title);
871   }
872
873   @Override
874   public void setSearchInProgress(Boolean isSearchInProgress)
875   {
876     lbl_blank.setVisible(!isSearchInProgress);
877     lbl_loading.setVisible(isSearchInProgress);
878   }
879
880   @Override
881   public void prevPageAction()
882   {
883     updatePaginatorCart();
884     if (offSet >= pageLimit)
885     {
886       offSet = offSet - pageLimit;
887       searchAction(false);
888     }
889     else
890     {
891       refreshPaginatorState();
892     }
893   }
894
895   @Override
896   public void nextPageAction()
897   {
898     updatePaginatorCart();
899     offSet = offSet + pageLimit;
900     searchAction(false);
901   }
902
903   public void updatePaginatorCart()
904   {
905     int primaryKeyColIndex = 0;
906     JTable resultTable = getResultTable();
907     int totalRows = resultTable.getRowCount();
908     try
909     {
910       primaryKeyColIndex = getFTSRestClient().getPrimaryKeyColumIndex(
911               wantedFields, false);
912     } catch (Exception e)
913     {
914       e.printStackTrace();
915     }
916
917     for (int row = 0; row < totalRows; row++)
918     {
919       String id = (String) resultTable.getValueAt(row, primaryKeyColIndex);
920       if (paginatorCart.contains(id))
921       {
922         paginatorCart.remove(id);
923       }
924     }
925     int[] selectedRows = resultTable.getSelectedRows();
926     for (int summaryRow : selectedRows)
927     {
928       String idStr = resultTable.getValueAt(summaryRow,
929               primaryKeyColIndex).toString();
930       paginatorCart.add(idStr);
931     }
932     // System.out.println("Paginator shopping cart size : "
933     // + paginatorCart.size());
934   }
935
936   public void updateSummaryTableSelections()
937   {
938     JTable resultTable = getResultTable();
939     if (paginatorCart.isEmpty())
940     {
941       return;
942     }
943     int primaryKeyColIndex = 0;
944     try
945     {
946       primaryKeyColIndex = getFTSRestClient().getPrimaryKeyColumIndex(
947               wantedFields, false);
948     } catch (Exception e)
949     {
950       e.printStackTrace();
951     }
952     // System.out.println(">>>>>> got here : 1");
953     int totalRows = resultTable.getRowCount();
954     // resultTable.clearSelection();
955     for (int row = 0; row < totalRows; row++)
956     {
957       String id = (String) resultTable.getValueAt(row, primaryKeyColIndex);
958       if (paginatorCart.contains(id))
959       {
960         resultTable.addRowSelectionInterval(row, row);
961       }
962     }
963     validateSelection();
964   }
965   public void refreshPaginatorState()
966   {
967     // System.out.println("resultSet count : " + resultSetCount);
968     // System.out.println("offSet : " + offSet);
969     // System.out.println("page limit : " + pageLimit);
970     setPrevPageButtonEnabled(false);
971     setNextPageButtonEnabled(false);
972     if (resultSetCount == 0 && pageLimit == 0)
973     {
974       return;
975     }
976     if (resultSetCount >= pageLimit)
977     {
978       setNextPageButtonEnabled(true);
979     }
980     if (offSet >= pageLimit)
981     {
982       setPrevPageButtonEnabled(true);
983     }
984   }
985   public void referesh()
986   {
987     mainFrame.setTitle(getFTSFrameTitle());
988   }
989
990 }