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