Merge branch 'develop' into features/JAL-1648_cache_user_inputs
[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.Iterator;
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<String>(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 && oldHidden.getHiddenRegions() != null
248                 && !oldHidden.getHiddenRegions().isEmpty())
249         {
250           for (Iterator<int[]> itr = oldHidden.getHiddenRegions()
251                   .iterator(); itr.hasNext();)
252           {
253             int positions[] = itr.next();
254             av.hideColumns(positions[0], positions[1]);
255           }
256         }
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     av.getColumnSelection().filterAnnotations(
390             getCurrentAnnotation().annotations, filterParams);
391
392     av.showAllHiddenColumns();
393     if (getActionOption() == ACTION_OPTION_HIDE)
394     {
395       av.hideSelectedColumns();
396     }
397
398     filterParams = null;
399     av.setAnnotationColumnSelectionState(this);
400     ap.paintAlignment(true);
401   }
402
403   public HiddenColumns getOldHiddenColumns()
404   {
405     return oldHiddenColumns;
406   }
407
408   public void setOldHiddenColumns(HiddenColumns currentHiddenColumns)
409   {
410     if (currentHiddenColumns != null)
411     {
412       this.oldHiddenColumns = new HiddenColumns(currentHiddenColumns);
413     }
414   }
415
416   public FurtherActionPanel getCurrentFutherActionPanel()
417   {
418     return currentFurtherActionPanel;
419   }
420
421   public void setCurrentFutherActionPanel(
422           FurtherActionPanel currentFutherActionPanel)
423   {
424     this.currentFurtherActionPanel = currentFutherActionPanel;
425   }
426
427   public SearchPanel getCurrentSearchPanel()
428   {
429     return currentSearchPanel;
430   }
431
432   public void setCurrentSearchPanel(SearchPanel currentSearchPanel)
433   {
434     this.currentSearchPanel = currentSearchPanel;
435   }
436
437   public int getActionOption()
438   {
439     return actionOption;
440   }
441
442   public void setActionOption(int actionOption)
443   {
444     this.actionOption = actionOption;
445   }
446
447   public StructureFilterPanel getCurrentStructureFilterPanel()
448   {
449     return currentStructureFilterPanel;
450   }
451
452   public void setCurrentStructureFilterPanel(
453           StructureFilterPanel currentStructureFilterPanel)
454   {
455     this.currentStructureFilterPanel = currentStructureFilterPanel;
456   }
457
458   public void select_action(ActionEvent actionEvent)
459   {
460     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
461     if (radioButton.isSelected())
462     {
463       setActionOption(ACTION_OPTION_SELECT);
464       updateView();
465     }
466   }
467
468   public void hide_action(ActionEvent actionEvent)
469   {
470     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
471     if (radioButton.isSelected())
472     {
473       setActionOption(ACTION_OPTION_HIDE);
474       updateView();
475     }
476   }
477
478   @Override
479   public void itemStateChanged(ItemEvent e)
480   {
481     selectedAnnotationChanged();
482   }
483
484   @Override
485   public void selectedAnnotationChanged()
486   {
487     String currentView = AnnotationColumnChooser.NO_GRAPH_VIEW;
488     if (av.getAlignment()
489             .getAlignmentAnnotation()[annmap[getAnnotations()
490             .getSelectedIndex()]].isQuantitative())
491     {
492       currentView = AnnotationColumnChooser.GRAPH_VIEW;
493     }
494     saveCache();
495     gSearchPanel.syncState();
496     gFurtherActionPanel.syncState();
497     gStructureFilterPanel.syncState();
498
499     ngSearchPanel.syncState();
500     ngFurtherActionPanel.syncState();
501     ngStructureFilterPanel.syncState();
502
503     CardLayout switchableViewsLayout = (CardLayout) switchableViewsPanel
504             .getLayout();
505     switchableViewsLayout.show(switchableViewsPanel, currentView);
506     updateView();
507   }
508
509   public class FurtherActionPanel extends JPanel
510   {
511     private AnnotationColumnChooser aColChooser;
512
513     private JRadioButton hideOption = new JRadioButton();
514
515     private JRadioButton selectOption = new JRadioButton();
516
517     private ButtonGroup optionsGroup = new ButtonGroup();
518
519     public FurtherActionPanel(AnnotationColumnChooser aColChooser)
520     {
521       this.aColChooser = aColChooser;
522       JvSwingUtils.jvInitComponent(selectOption, "action.select");
523       selectOption.addActionListener(new ActionListener()
524       {
525         @Override
526         public void actionPerformed(ActionEvent actionEvent)
527         {
528           selectRadioAction(actionEvent);
529         }
530       });
531
532       JvSwingUtils.jvInitComponent(hideOption, "action.hide");
533       hideOption.addActionListener(new ActionListener()
534       {
535         @Override
536         public void actionPerformed(ActionEvent actionEvent)
537         {
538           hideRadioAction(actionEvent);
539         }
540       });
541
542       optionsGroup.add(selectOption);
543       optionsGroup.add(hideOption);
544       optionsGroup.setSelected(selectOption.getModel(), true);
545
546       JvSwingUtils.jvInitComponent(this);
547       syncState();
548
549       this.add(selectOption);
550       this.add(hideOption);
551     }
552
553     public void selectRadioAction(ActionEvent actionEvent)
554     {
555       aColChooser.setCurrentFutherActionPanel(this);
556       aColChooser.select_action(actionEvent);
557     }
558
559     public void hideRadioAction(ActionEvent actionEvent)
560     {
561       aColChooser.setCurrentFutherActionPanel(this);
562       aColChooser.hide_action(actionEvent);
563     }
564
565     public void syncState()
566     {
567       if (aColChooser.getActionOption() == AnnotationColumnChooser.ACTION_OPTION_HIDE)
568       {
569         this.optionsGroup.setSelected(this.hideOption.getModel(), true);
570       }
571       else
572       {
573         this.optionsGroup.setSelected(this.selectOption.getModel(), true);
574       }
575     }
576   }
577
578   public class StructureFilterPanel extends JPanel
579   {
580     private AnnotationColumnChooser aColChooser;
581
582     private JCheckBox alphaHelix = new JCheckBox();
583
584     private JCheckBox betaStrand = new JCheckBox();
585
586     private JCheckBox turn = new JCheckBox();
587
588     private JCheckBox all = new JCheckBox();
589
590     public StructureFilterPanel(AnnotationColumnChooser aColChooser)
591     {
592       this.aColChooser = aColChooser;
593
594       JvSwingUtils.jvInitComponent(alphaHelix, "label.alpha_helix");
595       alphaHelix.addActionListener(new ActionListener()
596       {
597         @Override
598         public void actionPerformed(ActionEvent actionEvent)
599         {
600           alphaHelix_actionPerformed();
601         }
602       });
603
604       JvSwingUtils.jvInitComponent(betaStrand, "label.beta_strand");
605       betaStrand.addActionListener(new ActionListener()
606       {
607         @Override
608         public void actionPerformed(ActionEvent actionEvent)
609         {
610           betaStrand_actionPerformed();
611         }
612       });
613
614       JvSwingUtils.jvInitComponent(turn, "label.turn");
615       turn.addActionListener(new ActionListener()
616       {
617         @Override
618         public void actionPerformed(ActionEvent actionEvent)
619         {
620           turn_actionPerformed();
621         }
622       });
623
624       JvSwingUtils.jvInitComponent(all, "label.select_all");
625       all.addActionListener(new ActionListener()
626       {
627         @Override
628         public void actionPerformed(ActionEvent actionEvent)
629         {
630           all_actionPerformed();
631         }
632       });
633
634       this.setBorder(new TitledBorder(MessageManager
635               .getString("label.structures_filter")));
636       JvSwingUtils.jvInitComponent(this);
637
638       this.add(all);
639       this.add(alphaHelix);
640       this.add(betaStrand);
641       this.add(turn);
642     }
643
644     public void alphaHelix_actionPerformed()
645     {
646       updateSelectAllState();
647       aColChooser.setCurrentStructureFilterPanel(this);
648       aColChooser.updateView();
649     }
650
651     public void betaStrand_actionPerformed()
652     {
653       updateSelectAllState();
654       aColChooser.setCurrentStructureFilterPanel(this);
655       aColChooser.updateView();
656     }
657
658     public void turn_actionPerformed()
659     {
660       updateSelectAllState();
661       aColChooser.setCurrentStructureFilterPanel(this);
662       aColChooser.updateView();
663     }
664
665     public void all_actionPerformed()
666     {
667       if (all.isSelected())
668       {
669         alphaHelix.setSelected(true);
670         betaStrand.setSelected(true);
671         turn.setSelected(true);
672       }
673       else
674       {
675         alphaHelix.setSelected(false);
676         betaStrand.setSelected(false);
677         turn.setSelected(false);
678       }
679       aColChooser.setCurrentStructureFilterPanel(this);
680       aColChooser.updateView();
681     }
682
683     public void updateSelectAllState()
684     {
685       if (alphaHelix.isSelected() && betaStrand.isSelected()
686               && turn.isSelected())
687       {
688         all.setSelected(true);
689       }
690       else
691       {
692         all.setSelected(false);
693       }
694     }
695
696     public void syncState()
697     {
698       StructureFilterPanel sfp = aColChooser
699               .getCurrentStructureFilterPanel();
700       if (sfp != null)
701       {
702         alphaHelix.setSelected(sfp.alphaHelix.isSelected());
703         betaStrand.setSelected(sfp.betaStrand.isSelected());
704         turn.setSelected(sfp.turn.isSelected());
705         if (sfp.all.isSelected())
706         {
707           all.setSelected(true);
708           alphaHelix.setSelected(true);
709           betaStrand.setSelected(true);
710           turn.setSelected(true);
711         }
712       }
713
714     }
715   }
716
717   public class SearchPanel extends JPanel
718   {
719     private AnnotationColumnChooser aColChooser;
720
721     private JCheckBox displayName = new JCheckBox();
722
723     private JCheckBox description = new JCheckBox();
724
725     private static final String FILTER_BY_ANN_CACHE_KEY = "CACHE.SELECT_FILTER_BY_ANNOT";
726
727     public JvCacheableInputBox<String> searchBox = new JvCacheableInputBox<String>(
728             FILTER_BY_ANN_CACHE_KEY);
729
730     public SearchPanel(AnnotationColumnChooser aColChooser)
731     {
732
733       this.aColChooser = aColChooser;
734       JvSwingUtils.jvInitComponent(this);
735       this.setBorder(new TitledBorder(MessageManager
736               .getString("label.search_filter")));
737
738       searchBox.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXX");
739       searchBox.setToolTipText(MessageManager
740               .getString("info.enter_search_text_here"));
741       searchBox.getEditor().getEditorComponent()
742               .addKeyListener(new java.awt.event.KeyAdapter()
743               {
744                 @Override
745                 public void keyPressed(KeyEvent e)
746                 {
747                   if (e.getKeyCode() == KeyEvent.VK_ENTER)
748                   {
749                     e.consume();
750                     searchStringAction();
751                   }
752                 }
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", annotations
825                       .getSelectedItem().toString());
826       String descTtip = MessageManager.formatMessage(
827               "info.search_in_annotation_description", annotations
828                       .getSelectedItem().toString());
829       displayName.setToolTipText(displayName.isEnabled() ? labelTtip
830               : defaultTtip);
831       description.setToolTipText(description.isEnabled() ? descTtip
832               : 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 }