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