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