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