Merge branch 'releases/Release_2_11_4_Branch'
[jalview.git] / 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       av.sendSelection();
260       ap.paintAlignment(true);
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     av.sendSelection();
401
402     filterParams = null;
403     av.setAnnotationColumnSelectionState(this);
404     ap.paintAlignment(true);
405   }
406
407   public HiddenColumns getOldHiddenColumns()
408   {
409     return oldHiddenColumns;
410   }
411
412   public void setOldHiddenColumns(HiddenColumns currentHiddenColumns)
413   {
414     if (currentHiddenColumns != null)
415     {
416       this.oldHiddenColumns = new HiddenColumns(currentHiddenColumns);
417     }
418   }
419
420   public FurtherActionPanel getCurrentFutherActionPanel()
421   {
422     return currentFurtherActionPanel;
423   }
424
425   public void setCurrentFutherActionPanel(
426           FurtherActionPanel currentFutherActionPanel)
427   {
428     this.currentFurtherActionPanel = currentFutherActionPanel;
429   }
430
431   public SearchPanel getCurrentSearchPanel()
432   {
433     return currentSearchPanel;
434   }
435
436   public void setCurrentSearchPanel(SearchPanel currentSearchPanel)
437   {
438     this.currentSearchPanel = currentSearchPanel;
439   }
440
441   public int getActionOption()
442   {
443     return actionOption;
444   }
445
446   public void setActionOption(int actionOption)
447   {
448     this.actionOption = actionOption;
449   }
450
451   public StructureFilterPanel getCurrentStructureFilterPanel()
452   {
453     return currentStructureFilterPanel;
454   }
455
456   public void setCurrentStructureFilterPanel(
457           StructureFilterPanel currentStructureFilterPanel)
458   {
459     this.currentStructureFilterPanel = currentStructureFilterPanel;
460   }
461
462   public void select_action(ActionEvent actionEvent)
463   {
464     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
465     if (radioButton.isSelected())
466     {
467       setActionOption(ACTION_OPTION_SELECT);
468       updateView();
469     }
470   }
471
472   public void hide_action(ActionEvent actionEvent)
473   {
474     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
475     if (radioButton.isSelected())
476     {
477       setActionOption(ACTION_OPTION_HIDE);
478       updateView();
479     }
480   }
481
482   @Override
483   public void itemStateChanged(ItemEvent e)
484   {
485     selectedAnnotationChanged();
486   }
487
488   @Override
489   public void selectedAnnotationChanged()
490   {
491     String currentView = AnnotationColumnChooser.NO_GRAPH_VIEW;
492     if (av.getAlignment()
493             .getAlignmentAnnotation()[annmap[getAnnotations()
494             .getSelectedIndex()]].isQuantitative())
495     {
496       currentView = AnnotationColumnChooser.GRAPH_VIEW;
497     }
498     saveCache();
499     gSearchPanel.syncState();
500     gFurtherActionPanel.syncState();
501     gStructureFilterPanel.syncState();
502
503     ngSearchPanel.syncState();
504     ngFurtherActionPanel.syncState();
505     ngStructureFilterPanel.syncState();
506
507     CardLayout switchableViewsLayout = (CardLayout) switchableViewsPanel
508             .getLayout();
509     switchableViewsLayout.show(switchableViewsPanel, currentView);
510     updateView();
511   }
512
513   public class FurtherActionPanel extends JPanel
514   {
515     private AnnotationColumnChooser aColChooser;
516
517     private JRadioButton hideOption = new JRadioButton();
518
519     private JRadioButton selectOption = new JRadioButton();
520
521     private ButtonGroup optionsGroup = new ButtonGroup();
522
523     public FurtherActionPanel(AnnotationColumnChooser aColChooser)
524     {
525       this.aColChooser = aColChooser;
526       JvSwingUtils.jvInitComponent(selectOption, "action.select");
527       selectOption.addActionListener(new ActionListener()
528       {
529         @Override
530         public void actionPerformed(ActionEvent actionEvent)
531         {
532           selectRadioAction(actionEvent);
533         }
534       });
535
536       JvSwingUtils.jvInitComponent(hideOption, "action.hide");
537       hideOption.addActionListener(new ActionListener()
538       {
539         @Override
540         public void actionPerformed(ActionEvent actionEvent)
541         {
542           hideRadioAction(actionEvent);
543         }
544       });
545
546       optionsGroup.add(selectOption);
547       optionsGroup.add(hideOption);
548       optionsGroup.setSelected(selectOption.getModel(), true);
549
550       JvSwingUtils.jvInitComponent(this);
551       syncState();
552
553       this.add(selectOption);
554       this.add(hideOption);
555     }
556
557     public void selectRadioAction(ActionEvent actionEvent)
558     {
559       aColChooser.setCurrentFutherActionPanel(this);
560       aColChooser.select_action(actionEvent);
561     }
562
563     public void hideRadioAction(ActionEvent actionEvent)
564     {
565       aColChooser.setCurrentFutherActionPanel(this);
566       aColChooser.hide_action(actionEvent);
567     }
568
569     public void syncState()
570     {
571       if (aColChooser.getActionOption() == AnnotationColumnChooser.ACTION_OPTION_HIDE)
572       {
573         this.optionsGroup.setSelected(this.hideOption.getModel(), true);
574       }
575       else
576       {
577         this.optionsGroup.setSelected(this.selectOption.getModel(), true);
578       }
579     }
580   }
581
582   public class StructureFilterPanel extends JPanel
583   {
584     private AnnotationColumnChooser aColChooser;
585
586     private JCheckBox alphaHelix = new JCheckBox();
587
588     private JCheckBox betaStrand = new JCheckBox();
589
590     private JCheckBox turn = new JCheckBox();
591
592     private JCheckBox all = new JCheckBox();
593
594     public StructureFilterPanel(AnnotationColumnChooser aColChooser)
595     {
596       this.aColChooser = aColChooser;
597
598       JvSwingUtils.jvInitComponent(alphaHelix, "label.alpha_helix");
599       alphaHelix.addActionListener(new ActionListener()
600       {
601         @Override
602         public void actionPerformed(ActionEvent actionEvent)
603         {
604           alphaHelix_actionPerformed();
605         }
606       });
607
608       JvSwingUtils.jvInitComponent(betaStrand, "label.beta_strand");
609       betaStrand.addActionListener(new ActionListener()
610       {
611         @Override
612         public void actionPerformed(ActionEvent actionEvent)
613         {
614           betaStrand_actionPerformed();
615         }
616       });
617
618       JvSwingUtils.jvInitComponent(turn, "label.turn");
619       turn.addActionListener(new ActionListener()
620       {
621         @Override
622         public void actionPerformed(ActionEvent actionEvent)
623         {
624           turn_actionPerformed();
625         }
626       });
627
628       JvSwingUtils.jvInitComponent(all, "label.select_all");
629       all.addActionListener(new ActionListener()
630       {
631         @Override
632         public void actionPerformed(ActionEvent actionEvent)
633         {
634           all_actionPerformed();
635         }
636       });
637
638       this.setBorder(new TitledBorder(MessageManager
639               .getString("label.structures_filter")));
640       JvSwingUtils.jvInitComponent(this);
641
642       this.add(all);
643       this.add(alphaHelix);
644       this.add(betaStrand);
645       this.add(turn);
646     }
647
648     public void alphaHelix_actionPerformed()
649     {
650       updateSelectAllState();
651       aColChooser.setCurrentStructureFilterPanel(this);
652       aColChooser.updateView();
653     }
654
655     public void betaStrand_actionPerformed()
656     {
657       updateSelectAllState();
658       aColChooser.setCurrentStructureFilterPanel(this);
659       aColChooser.updateView();
660     }
661
662     public void turn_actionPerformed()
663     {
664       updateSelectAllState();
665       aColChooser.setCurrentStructureFilterPanel(this);
666       aColChooser.updateView();
667     }
668
669     public void all_actionPerformed()
670     {
671       if (all.isSelected())
672       {
673         alphaHelix.setSelected(true);
674         betaStrand.setSelected(true);
675         turn.setSelected(true);
676       }
677       else
678       {
679         alphaHelix.setSelected(false);
680         betaStrand.setSelected(false);
681         turn.setSelected(false);
682       }
683       aColChooser.setCurrentStructureFilterPanel(this);
684       aColChooser.updateView();
685     }
686
687     public void updateSelectAllState()
688     {
689       if (alphaHelix.isSelected() && betaStrand.isSelected()
690               && turn.isSelected())
691       {
692         all.setSelected(true);
693       }
694       else
695       {
696         all.setSelected(false);
697       }
698     }
699
700     public void syncState()
701     {
702       StructureFilterPanel sfp = aColChooser
703               .getCurrentStructureFilterPanel();
704       if (sfp != null)
705       {
706         alphaHelix.setSelected(sfp.alphaHelix.isSelected());
707         betaStrand.setSelected(sfp.betaStrand.isSelected());
708         turn.setSelected(sfp.turn.isSelected());
709         if (sfp.all.isSelected())
710         {
711           all.setSelected(true);
712           alphaHelix.setSelected(true);
713           betaStrand.setSelected(true);
714           turn.setSelected(true);
715         }
716       }
717
718     }
719   }
720
721   public class SearchPanel extends JPanel
722   {
723     private AnnotationColumnChooser aColChooser;
724
725     private JCheckBox displayName = new JCheckBox();
726
727     private JCheckBox description = new JCheckBox();
728
729     private static final String FILTER_BY_ANN_CACHE_KEY = "CACHE.SELECT_FILTER_BY_ANNOT";
730
731     public JvCacheableInputBox<String> searchBox = new JvCacheableInputBox<>(
732             FILTER_BY_ANN_CACHE_KEY);
733
734     public SearchPanel(AnnotationColumnChooser aColChooser)
735     {
736
737       this.aColChooser = aColChooser;
738       JvSwingUtils.jvInitComponent(this);
739       this.setBorder(new TitledBorder(MessageManager
740               .getString("label.search_filter")));
741
742       searchBox.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXX");
743       searchBox.setToolTipText(MessageManager
744               .getString("info.enter_search_text_here"));
745       searchBox.getEditor().getEditorComponent()
746               .addKeyListener(new java.awt.event.KeyAdapter()
747               {
748                 @Override
749                 public void keyPressed(KeyEvent e)
750                 {
751                   if (e.getKeyCode() == KeyEvent.VK_ENTER)
752                   {
753                     e.consume();
754                     searchStringAction();
755                   }
756                 }
757               });
758
759
760
761       JvSwingUtils.jvInitComponent(displayName, "label.label");
762       displayName.addActionListener(new ActionListener()
763       {
764         @Override
765         public void actionPerformed(ActionEvent actionEvent)
766         {
767           displayNameCheckboxAction();
768         }
769       });
770
771       JvSwingUtils.jvInitComponent(description, "label.description");
772       description.addActionListener(new ActionListener()
773       {
774         @Override
775         public void actionPerformed(ActionEvent actionEvent)
776         {
777           discriptionCheckboxAction();
778         }
779       });
780
781       syncState();
782       this.add(searchBox);
783       this.add(displayName);
784       this.add(description);
785     }
786
787     public void displayNameCheckboxAction()
788     {
789       aColChooser.setCurrentSearchPanel(this);
790       aColChooser.updateView();
791     }
792
793     public void discriptionCheckboxAction()
794     {
795       aColChooser.setCurrentSearchPanel(this);
796       aColChooser.updateView();
797     }
798
799     public void searchStringAction()
800     {
801       aColChooser.setCurrentSearchPanel(this);
802       aColChooser.updateView();
803       updateSearchPanelToolTips();
804       searchBox.updateCache();
805     }
806
807     public void syncState()
808     {
809       SearchPanel sp = aColChooser.getCurrentSearchPanel();
810       if (sp != null)
811       {
812         description.setEnabled(sp.description.isEnabled());
813         description.setSelected(sp.description.isSelected());
814
815         displayName.setEnabled(sp.displayName.isEnabled());
816         displayName.setSelected(sp.displayName.isSelected());
817
818         searchBox.setSelectedItem(sp.searchBox.getUserInput());
819       }
820       updateSearchPanelToolTips();
821     }
822
823     public void updateSearchPanelToolTips()
824     {
825       String defaultTtip = MessageManager
826               .getString("info.enter_search_text_to_enable");
827       String labelTtip = MessageManager.formatMessage(
828               "info.search_in_annotation_label", annotations
829                       .getSelectedItem().toString());
830       String descTtip = MessageManager.formatMessage(
831               "info.search_in_annotation_description", annotations
832                       .getSelectedItem().toString());
833       displayName.setToolTipText(displayName.isEnabled() ? labelTtip
834               : defaultTtip);
835       description.setToolTipText(description.isEnabled() ? descTtip
836               : defaultTtip);
837     }
838   }
839
840   @Override
841   public void ok_actionPerformed()
842   {
843     saveCache();
844     super.ok_actionPerformed();
845   }
846
847   @Override
848   public void cancel_actionPerformed()
849   {
850     saveCache();
851     super.cancel_actionPerformed();
852   }
853
854   private void saveCache()
855   {
856     gSearchPanel.searchBox.persistCache();
857     ngSearchPanel.searchBox.persistCache();
858     gSearchPanel.searchBox.updateCache();
859     ngSearchPanel.searchBox.updateCache();
860   }
861 }