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