JAL-2591 Refactor HiddenColumns to use ArrayList instead of Vector
[jalview.git] / src / jalview / gui / AnnotationColumnChooser.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.gui;
23
24 import jalview.datamodel.HiddenColumns;
25 import jalview.io.cache.JvCacheableInputBox;
26 import jalview.schemes.AnnotationColourGradient;
27 import jalview.util.MessageManager;
28 import jalview.viewmodel.annotationfilter.AnnotationFilterParameter;
29
30 import java.awt.BorderLayout;
31 import java.awt.CardLayout;
32 import java.awt.Color;
33 import java.awt.Dimension;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ActionListener;
36 import java.awt.event.ItemEvent;
37 import java.awt.event.ItemListener;
38 import java.awt.event.KeyEvent;
39 import java.util.ArrayList;
40
41 import javax.swing.ButtonGroup;
42 import javax.swing.JCheckBox;
43 import javax.swing.JComboBox;
44 import javax.swing.JInternalFrame;
45 import javax.swing.JLayeredPane;
46 import javax.swing.JPanel;
47 import javax.swing.JRadioButton;
48 import javax.swing.border.TitledBorder;
49
50 import net.miginfocom.swing.MigLayout;
51
52 @SuppressWarnings("serial")
53 public class AnnotationColumnChooser extends AnnotationRowFilter implements
54         ItemListener
55 {
56   private JPanel switchableViewsPanel = new JPanel(new CardLayout());
57
58   private JPanel annotationComboBoxPanel = new JPanel();
59
60   private StructureFilterPanel gStructureFilterPanel;
61
62   private StructureFilterPanel ngStructureFilterPanel;
63
64   private StructureFilterPanel currentStructureFilterPanel;
65
66   private SearchPanel currentSearchPanel;
67
68   private SearchPanel gSearchPanel;
69
70   private SearchPanel ngSearchPanel;
71
72   private FurtherActionPanel currentFurtherActionPanel;
73
74   private FurtherActionPanel gFurtherActionPanel;
75
76   private FurtherActionPanel ngFurtherActionPanel;
77
78   public static final int ACTION_OPTION_SELECT = 1;
79
80   public static int ACTION_OPTION_HIDE = 2;
81
82   public static String NO_GRAPH_VIEW = "0";
83
84   public static String GRAPH_VIEW = "1";
85
86   private int actionOption = ACTION_OPTION_SELECT;
87
88   private HiddenColumns oldHiddenColumns;
89
90   protected int MIN_WIDTH = 420;
91
92   protected int MIN_HEIGHT = 430;
93
94   public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap)
95   {
96     super(av, ap);
97     frame = new JInternalFrame();
98     frame.setContentPane(this);
99     frame.setLayer(JLayeredPane.PALETTE_LAYER);
100     Desktop.addInternalFrame(frame,
101             MessageManager.getString("label.select_by_annotation"), 520,
102             215);
103     frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
104
105     addSliderChangeListener();
106     addSliderMouseListeners();
107
108     if (av.getAlignment().getAlignmentAnnotation() == null)
109     {
110       return;
111     }
112     setOldHiddenColumns(av.getAlignment().getHiddenColumns());
113     adjusting = true;
114
115     setAnnotations(new JComboBox<>(getAnnotationItems(false)));
116     populateThresholdComboBox(threshold);
117     AnnotationColumnChooser lastChooser = av
118             .getAnnotationColumnSelectionState();
119     // restore Object state from the previous session if one exists
120     if (lastChooser != null)
121     {
122       currentSearchPanel = lastChooser
123               .getCurrentSearchPanel();
124       currentStructureFilterPanel = lastChooser
125               .getCurrentStructureFilterPanel();
126       annotations.setSelectedIndex(lastChooser
127               .getAnnotations().getSelectedIndex());
128       threshold.setSelectedIndex(lastChooser
129               .getThreshold().getSelectedIndex());
130       actionOption = lastChooser
131               .getActionOption();
132       percentThreshold.setSelected(lastChooser.percentThreshold
133               .isSelected());
134     }
135
136     try
137     {
138       jbInit();
139     } catch (Exception ex)
140     {
141     }
142     adjusting = false;
143
144     updateView();
145     frame.invalidate();
146     frame.pack();
147   }
148
149   @Override
150   protected void jbInit()
151   {
152     super.jbInit();
153
154     JPanel thresholdPanel = new JPanel();
155     thresholdPanel.setBorder(new TitledBorder(MessageManager
156             .getString("label.threshold_filter")));
157     thresholdPanel.setBackground(Color.white);
158     thresholdPanel.setFont(JvSwingUtils.getLabelFont());
159     thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]"));
160
161     percentThreshold.setBackground(Color.white);
162     percentThreshold.setFont(JvSwingUtils.getLabelFont());
163
164     JPanel actionPanel = new JPanel();
165     actionPanel.setBackground(Color.white);
166     actionPanel.setFont(JvSwingUtils.getLabelFont());
167
168     JPanel graphFilterView = new JPanel();
169     graphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]"));
170     graphFilterView.setBackground(Color.white);
171
172     JPanel noGraphFilterView = new JPanel();
173     noGraphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]"));
174     noGraphFilterView.setBackground(Color.white);
175
176     annotationComboBoxPanel.setBackground(Color.white);
177     annotationComboBoxPanel.setFont(JvSwingUtils.getLabelFont());
178
179     gSearchPanel = new SearchPanel(this);
180     ngSearchPanel = new SearchPanel(this);
181     gFurtherActionPanel = new FurtherActionPanel(this);
182     ngFurtherActionPanel = new FurtherActionPanel(this);
183     gStructureFilterPanel = new StructureFilterPanel(this);
184     ngStructureFilterPanel = new StructureFilterPanel(this);
185
186     thresholdPanel.add(getThreshold());
187     thresholdPanel.add(percentThreshold, "wrap");
188     thresholdPanel.add(slider, "grow");
189     thresholdPanel.add(thresholdValue, "span, wrap");
190
191     actionPanel.add(ok);
192     actionPanel.add(cancel);
193
194     graphFilterView.add(gSearchPanel, "grow, span, wrap");
195     graphFilterView.add(gStructureFilterPanel, "grow, span, wrap");
196     graphFilterView.add(thresholdPanel, "grow, span, wrap");
197     graphFilterView.add(gFurtherActionPanel);
198
199     noGraphFilterView.add(ngSearchPanel, "grow, span, wrap");
200     noGraphFilterView.add(ngStructureFilterPanel, "grow, span, wrap");
201     noGraphFilterView.add(ngFurtherActionPanel);
202
203     annotationComboBoxPanel.add(getAnnotations());
204     switchableViewsPanel.add(noGraphFilterView,
205             AnnotationColumnChooser.NO_GRAPH_VIEW);
206     switchableViewsPanel.add(graphFilterView,
207             AnnotationColumnChooser.GRAPH_VIEW);
208
209     this.setLayout(new BorderLayout());
210     this.add(annotationComboBoxPanel, java.awt.BorderLayout.PAGE_START);
211     this.add(switchableViewsPanel, java.awt.BorderLayout.CENTER);
212     this.add(actionPanel, java.awt.BorderLayout.SOUTH);
213
214     selectedAnnotationChanged();
215     updateThresholdPanelToolTip();
216     this.validate();
217   }
218
219   protected void updateThresholdPanelToolTip()
220   {
221     thresholdValue.setToolTipText("");
222     slider.setToolTipText("");
223
224     String defaultTtip = MessageManager
225             .getString("info.change_threshold_mode_to_enable");
226
227     String thresh = getThreshold().getSelectedItem().toString();
228     if (thresh.equalsIgnoreCase("No Threshold"))
229     {
230       thresholdValue.setToolTipText(defaultTtip);
231       slider.setToolTipText(defaultTtip);
232     }
233   }
234
235   @Override
236   protected void reset()
237   {
238     if (this.getOldHiddenColumns() != null)
239     {
240       av.getColumnSelection().clear();
241
242       if (av.getAnnotationColumnSelectionState() != null)
243       {
244         HiddenColumns oldHidden = av
245                 .getAnnotationColumnSelectionState()
246                 .getOldHiddenColumns();
247         if (oldHidden != null)
248         {
249           ArrayList<int[]> regions = oldHidden.getHiddenColumnsCopy();
250           for (int[] positions : regions)
251           {
252             av.hideColumns(positions[0], positions[1]);
253           }
254         }
255         // TODO not clear why we need to hide all the columns (above) if we are
256         // going to copy the hidden columns over wholesale anyway
257         av.getAlignment().setHiddenColumns(oldHidden);
258       }
259       ap.paintAlignment(true);
260     }
261
262   }
263
264   @Override
265   public void valueChanged(boolean updateAllAnnotation)
266   {
267     if (slider.isEnabled())
268     {
269       getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
270       updateView();
271       propagateSeqAssociatedThreshold(updateAllAnnotation,
272               getCurrentAnnotation());
273       ap.paintAlignment(false);
274     }
275   }
276
277   @Override
278   public void updateView()
279   {
280     // Check if combobox is still adjusting
281     if (adjusting)
282     {
283       return;
284     }
285
286     AnnotationFilterParameter filterParams = new AnnotationFilterParameter();
287
288     setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations()
289             .getSelectedIndex()]]);
290
291     int selectedThresholdItem = getSelectedThresholdItem(getThreshold()
292             .getSelectedIndex());
293
294     slider.setEnabled(true);
295     thresholdValue.setEnabled(true);
296     percentThreshold.setEnabled(true);
297
298     if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD)
299     {
300       slider.setEnabled(false);
301       thresholdValue.setEnabled(false);
302       thresholdValue.setText("");
303       percentThreshold.setEnabled(false);
304       // build filter params
305     }
306     else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD)
307     {
308       if (getCurrentAnnotation().threshold == null)
309       {
310         getCurrentAnnotation()
311                 .setThreshold(
312                         new jalview.datamodel.GraphLine(
313                                 (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f,
314                                 "Threshold", Color.black));
315       }
316
317       adjusting = true;
318       float range = getCurrentAnnotation().graphMax * 1000
319               - getCurrentAnnotation().graphMin * 1000;
320
321       slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000));
322       slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000));
323       slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000));
324       
325       setThresholdValueText();
326
327       slider.setMajorTickSpacing((int) (range / 10f));
328       slider.setEnabled(true);
329       thresholdValue.setEnabled(true);
330       adjusting = false;
331
332       // build filter params
333       filterParams
334               .setThresholdType(AnnotationFilterParameter.ThresholdType.NO_THRESHOLD);
335       if (getCurrentAnnotation().isQuantitative())
336       {
337         filterParams
338                 .setThresholdValue(getCurrentAnnotation().threshold.value);
339
340         if (selectedThresholdItem == AnnotationColourGradient.ABOVE_THRESHOLD)
341         {
342           filterParams
343                   .setThresholdType(AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD);
344         }
345         else if (selectedThresholdItem == AnnotationColourGradient.BELOW_THRESHOLD)
346         {
347           filterParams
348                   .setThresholdType(AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD);
349         }
350       }
351     }
352
353     updateThresholdPanelToolTip();
354     if (currentStructureFilterPanel != null)
355     {
356       if (currentStructureFilterPanel.alphaHelix.isSelected())
357       {
358         filterParams.setFilterAlphaHelix(true);
359       }
360       if (currentStructureFilterPanel.betaStrand.isSelected())
361       {
362         filterParams.setFilterBetaSheet(true);
363       }
364       if (currentStructureFilterPanel.turn.isSelected())
365       {
366         filterParams.setFilterTurn(true);
367       }
368     }
369
370     if (currentSearchPanel != null)
371     {
372       if (!currentSearchPanel.searchBox.getUserInput().isEmpty())
373       {
374         filterParams.setRegexString(currentSearchPanel.searchBox
375                 .getUserInput());
376         if (currentSearchPanel.displayName.isSelected())
377         {
378           filterParams
379                   .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DISPLAY_STRING);
380         }
381         if (currentSearchPanel.description.isSelected())
382         {
383           filterParams
384                   .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DESCRIPTION);
385         }
386       }
387     }
388
389     // show hidden columns here, before changing the column selection in
390     // filterAnnotations, because showing hidden columns has the side effect of
391     // adding them to the selection
392     av.showAllHiddenColumns();
393     av.getColumnSelection().filterAnnotations(
394             getCurrentAnnotation().annotations, filterParams);
395
396     if (getActionOption() == ACTION_OPTION_HIDE)
397     {
398       av.hideSelectedColumns();
399     }
400
401     filterParams = null;
402     av.setAnnotationColumnSelectionState(this);
403     ap.paintAlignment(true);
404   }
405
406   public HiddenColumns getOldHiddenColumns()
407   {
408     return oldHiddenColumns;
409   }
410
411   public void setOldHiddenColumns(HiddenColumns currentHiddenColumns)
412   {
413     if (currentHiddenColumns != null)
414     {
415       this.oldHiddenColumns = new HiddenColumns(currentHiddenColumns);
416     }
417   }
418
419   public FurtherActionPanel getCurrentFutherActionPanel()
420   {
421     return currentFurtherActionPanel;
422   }
423
424   public void setCurrentFutherActionPanel(
425           FurtherActionPanel currentFutherActionPanel)
426   {
427     this.currentFurtherActionPanel = currentFutherActionPanel;
428   }
429
430   public SearchPanel getCurrentSearchPanel()
431   {
432     return currentSearchPanel;
433   }
434
435   public void setCurrentSearchPanel(SearchPanel currentSearchPanel)
436   {
437     this.currentSearchPanel = currentSearchPanel;
438   }
439
440   public int getActionOption()
441   {
442     return actionOption;
443   }
444
445   public void setActionOption(int actionOption)
446   {
447     this.actionOption = actionOption;
448   }
449
450   public StructureFilterPanel getCurrentStructureFilterPanel()
451   {
452     return currentStructureFilterPanel;
453   }
454
455   public void setCurrentStructureFilterPanel(
456           StructureFilterPanel currentStructureFilterPanel)
457   {
458     this.currentStructureFilterPanel = currentStructureFilterPanel;
459   }
460
461   public void select_action(ActionEvent actionEvent)
462   {
463     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
464     if (radioButton.isSelected())
465     {
466       setActionOption(ACTION_OPTION_SELECT);
467       updateView();
468     }
469   }
470
471   public void hide_action(ActionEvent actionEvent)
472   {
473     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
474     if (radioButton.isSelected())
475     {
476       setActionOption(ACTION_OPTION_HIDE);
477       updateView();
478     }
479   }
480
481   @Override
482   public void itemStateChanged(ItemEvent e)
483   {
484     selectedAnnotationChanged();
485   }
486
487   @Override
488   public void selectedAnnotationChanged()
489   {
490     String currentView = AnnotationColumnChooser.NO_GRAPH_VIEW;
491     if (av.getAlignment()
492             .getAlignmentAnnotation()[annmap[getAnnotations()
493             .getSelectedIndex()]].isQuantitative())
494     {
495       currentView = AnnotationColumnChooser.GRAPH_VIEW;
496     }
497     saveCache();
498     gSearchPanel.syncState();
499     gFurtherActionPanel.syncState();
500     gStructureFilterPanel.syncState();
501
502     ngSearchPanel.syncState();
503     ngFurtherActionPanel.syncState();
504     ngStructureFilterPanel.syncState();
505
506     CardLayout switchableViewsLayout = (CardLayout) switchableViewsPanel
507             .getLayout();
508     switchableViewsLayout.show(switchableViewsPanel, currentView);
509     updateView();
510   }
511
512   public class FurtherActionPanel extends JPanel
513   {
514     private AnnotationColumnChooser aColChooser;
515
516     private JRadioButton hideOption = new JRadioButton();
517
518     private JRadioButton selectOption = new JRadioButton();
519
520     private ButtonGroup optionsGroup = new ButtonGroup();
521
522     public FurtherActionPanel(AnnotationColumnChooser aColChooser)
523     {
524       this.aColChooser = aColChooser;
525       JvSwingUtils.jvInitComponent(selectOption, "action.select");
526       selectOption.addActionListener(new ActionListener()
527       {
528         @Override
529         public void actionPerformed(ActionEvent actionEvent)
530         {
531           selectRadioAction(actionEvent);
532         }
533       });
534
535       JvSwingUtils.jvInitComponent(hideOption, "action.hide");
536       hideOption.addActionListener(new ActionListener()
537       {
538         @Override
539         public void actionPerformed(ActionEvent actionEvent)
540         {
541           hideRadioAction(actionEvent);
542         }
543       });
544
545       optionsGroup.add(selectOption);
546       optionsGroup.add(hideOption);
547       optionsGroup.setSelected(selectOption.getModel(), true);
548
549       JvSwingUtils.jvInitComponent(this);
550       syncState();
551
552       this.add(selectOption);
553       this.add(hideOption);
554     }
555
556     public void selectRadioAction(ActionEvent actionEvent)
557     {
558       aColChooser.setCurrentFutherActionPanel(this);
559       aColChooser.select_action(actionEvent);
560     }
561
562     public void hideRadioAction(ActionEvent actionEvent)
563     {
564       aColChooser.setCurrentFutherActionPanel(this);
565       aColChooser.hide_action(actionEvent);
566     }
567
568     public void syncState()
569     {
570       if (aColChooser.getActionOption() == AnnotationColumnChooser.ACTION_OPTION_HIDE)
571       {
572         this.optionsGroup.setSelected(this.hideOption.getModel(), true);
573       }
574       else
575       {
576         this.optionsGroup.setSelected(this.selectOption.getModel(), true);
577       }
578     }
579   }
580
581   public class StructureFilterPanel extends JPanel
582   {
583     private AnnotationColumnChooser aColChooser;
584
585     private JCheckBox alphaHelix = new JCheckBox();
586
587     private JCheckBox betaStrand = new JCheckBox();
588
589     private JCheckBox turn = new JCheckBox();
590
591     private JCheckBox all = new JCheckBox();
592
593     public StructureFilterPanel(AnnotationColumnChooser aColChooser)
594     {
595       this.aColChooser = aColChooser;
596
597       JvSwingUtils.jvInitComponent(alphaHelix, "label.alpha_helix");
598       alphaHelix.addActionListener(new ActionListener()
599       {
600         @Override
601         public void actionPerformed(ActionEvent actionEvent)
602         {
603           alphaHelix_actionPerformed();
604         }
605       });
606
607       JvSwingUtils.jvInitComponent(betaStrand, "label.beta_strand");
608       betaStrand.addActionListener(new ActionListener()
609       {
610         @Override
611         public void actionPerformed(ActionEvent actionEvent)
612         {
613           betaStrand_actionPerformed();
614         }
615       });
616
617       JvSwingUtils.jvInitComponent(turn, "label.turn");
618       turn.addActionListener(new ActionListener()
619       {
620         @Override
621         public void actionPerformed(ActionEvent actionEvent)
622         {
623           turn_actionPerformed();
624         }
625       });
626
627       JvSwingUtils.jvInitComponent(all, "label.select_all");
628       all.addActionListener(new ActionListener()
629       {
630         @Override
631         public void actionPerformed(ActionEvent actionEvent)
632         {
633           all_actionPerformed();
634         }
635       });
636
637       this.setBorder(new TitledBorder(MessageManager
638               .getString("label.structures_filter")));
639       JvSwingUtils.jvInitComponent(this);
640
641       this.add(all);
642       this.add(alphaHelix);
643       this.add(betaStrand);
644       this.add(turn);
645     }
646
647     public void alphaHelix_actionPerformed()
648     {
649       updateSelectAllState();
650       aColChooser.setCurrentStructureFilterPanel(this);
651       aColChooser.updateView();
652     }
653
654     public void betaStrand_actionPerformed()
655     {
656       updateSelectAllState();
657       aColChooser.setCurrentStructureFilterPanel(this);
658       aColChooser.updateView();
659     }
660
661     public void turn_actionPerformed()
662     {
663       updateSelectAllState();
664       aColChooser.setCurrentStructureFilterPanel(this);
665       aColChooser.updateView();
666     }
667
668     public void all_actionPerformed()
669     {
670       if (all.isSelected())
671       {
672         alphaHelix.setSelected(true);
673         betaStrand.setSelected(true);
674         turn.setSelected(true);
675       }
676       else
677       {
678         alphaHelix.setSelected(false);
679         betaStrand.setSelected(false);
680         turn.setSelected(false);
681       }
682       aColChooser.setCurrentStructureFilterPanel(this);
683       aColChooser.updateView();
684     }
685
686     public void updateSelectAllState()
687     {
688       if (alphaHelix.isSelected() && betaStrand.isSelected()
689               && turn.isSelected())
690       {
691         all.setSelected(true);
692       }
693       else
694       {
695         all.setSelected(false);
696       }
697     }
698
699     public void syncState()
700     {
701       StructureFilterPanel sfp = aColChooser
702               .getCurrentStructureFilterPanel();
703       if (sfp != null)
704       {
705         alphaHelix.setSelected(sfp.alphaHelix.isSelected());
706         betaStrand.setSelected(sfp.betaStrand.isSelected());
707         turn.setSelected(sfp.turn.isSelected());
708         if (sfp.all.isSelected())
709         {
710           all.setSelected(true);
711           alphaHelix.setSelected(true);
712           betaStrand.setSelected(true);
713           turn.setSelected(true);
714         }
715       }
716
717     }
718   }
719
720   public class SearchPanel extends JPanel
721   {
722     private AnnotationColumnChooser aColChooser;
723
724     private JCheckBox displayName = new JCheckBox();
725
726     private JCheckBox description = new JCheckBox();
727
728     private static final String FILTER_BY_ANN_CACHE_KEY = "CACHE.SELECT_FILTER_BY_ANNOT";
729
730     public JvCacheableInputBox<String> searchBox = new JvCacheableInputBox<>(
731             FILTER_BY_ANN_CACHE_KEY);
732
733     public SearchPanel(AnnotationColumnChooser aColChooser)
734     {
735
736       this.aColChooser = aColChooser;
737       JvSwingUtils.jvInitComponent(this);
738       this.setBorder(new TitledBorder(MessageManager
739               .getString("label.search_filter")));
740
741       searchBox.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXX");
742       searchBox.setToolTipText(MessageManager
743               .getString("info.enter_search_text_here"));
744       searchBox.getEditor().getEditorComponent()
745               .addKeyListener(new java.awt.event.KeyAdapter()
746               {
747                 @Override
748                 public void keyPressed(KeyEvent e)
749                 {
750                   if (e.getKeyCode() == KeyEvent.VK_ENTER)
751                   {
752                     e.consume();
753                     searchStringAction();
754                   }
755                 }
756               });
757
758
759
760       JvSwingUtils.jvInitComponent(displayName, "label.label");
761       displayName.addActionListener(new ActionListener()
762       {
763         @Override
764         public void actionPerformed(ActionEvent actionEvent)
765         {
766           displayNameCheckboxAction();
767         }
768       });
769
770       JvSwingUtils.jvInitComponent(description, "label.description");
771       description.addActionListener(new ActionListener()
772       {
773         @Override
774         public void actionPerformed(ActionEvent actionEvent)
775         {
776           discriptionCheckboxAction();
777         }
778       });
779
780       syncState();
781       this.add(searchBox);
782       this.add(displayName);
783       this.add(description);
784     }
785
786     public void displayNameCheckboxAction()
787     {
788       aColChooser.setCurrentSearchPanel(this);
789       aColChooser.updateView();
790     }
791
792     public void discriptionCheckboxAction()
793     {
794       aColChooser.setCurrentSearchPanel(this);
795       aColChooser.updateView();
796     }
797
798     public void searchStringAction()
799     {
800       aColChooser.setCurrentSearchPanel(this);
801       aColChooser.updateView();
802       updateSearchPanelToolTips();
803       searchBox.updateCache();
804     }
805
806     public void syncState()
807     {
808       SearchPanel sp = aColChooser.getCurrentSearchPanel();
809       if (sp != null)
810       {
811         description.setEnabled(sp.description.isEnabled());
812         description.setSelected(sp.description.isSelected());
813
814         displayName.setEnabled(sp.displayName.isEnabled());
815         displayName.setSelected(sp.displayName.isSelected());
816
817         searchBox.setSelectedItem(sp.searchBox.getUserInput());
818       }
819       updateSearchPanelToolTips();
820     }
821
822     public void updateSearchPanelToolTips()
823     {
824       String defaultTtip = MessageManager
825               .getString("info.enter_search_text_to_enable");
826       String labelTtip = MessageManager.formatMessage(
827               "info.search_in_annotation_label", annotations
828                       .getSelectedItem().toString());
829       String descTtip = MessageManager.formatMessage(
830               "info.search_in_annotation_description", annotations
831                       .getSelectedItem().toString());
832       displayName.setToolTipText(displayName.isEnabled() ? labelTtip
833               : defaultTtip);
834       description.setToolTipText(description.isEnabled() ? descTtip
835               : defaultTtip);
836     }
837   }
838
839   @Override
840   public void ok_actionPerformed()
841   {
842     saveCache();
843     super.ok_actionPerformed();
844   }
845
846   @Override
847   public void cancel_actionPerformed()
848   {
849     saveCache();
850     super.cancel_actionPerformed();
851   }
852
853   private void saveCache()
854   {
855     gSearchPanel.searchBox.persistCache();
856     ngSearchPanel.searchBox.persistCache();
857     gSearchPanel.searchBox.updateCache();
858     ngSearchPanel.searchBox.updateCache();
859   }
860 }