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