JAL-3161 limit tooltip and status updates to visible columns
[jalview.git] / src / jalview / appletgui / PaintRefresher.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 package jalview.appletgui;
22
23 import jalview.datamodel.AlignmentI;
24 import jalview.datamodel.SequenceI;
25
26 import java.awt.Component;
27 import java.util.Hashtable;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Vector;
32
33 /**
34  * DOCUMENT ME!
35  * 
36  * @author $author$
37  * @version $Revision$
38  */
39 public class PaintRefresher
40 {
41   static Map<String, Vector<Component>> components;
42
43   /**
44    * DOCUMENT ME!
45    * 
46    * @param comp
47    *          DOCUMENT ME!
48    * @param al
49    *          DOCUMENT ME!
50    */
51   public static void Register(Component comp, String seqSetId)
52   {
53     if (components == null)
54     {
55       components = new Hashtable<String, Vector<Component>>();
56     }
57
58     if (components.containsKey(seqSetId))
59     {
60       Vector<Component> comps = components.get(seqSetId);
61       if (!comps.contains(comp))
62       {
63         comps.addElement(comp);
64       }
65     }
66     else
67     {
68       Vector<Component> vcoms = new Vector<>();
69       vcoms.addElement(comp);
70       components.put(seqSetId, vcoms);
71     }
72   }
73
74   public static void RemoveComponent(Component comp)
75   {
76     if (components == null)
77     {
78       return;
79     }
80
81     Iterator<String> it = components.keySet().iterator();
82     while (it.hasNext())
83     {
84       Vector<Component> comps = components.get(it.next());
85       comps.removeElement(comp);
86       if (comps.isEmpty())
87       {
88         it.remove();
89       }
90     }
91   }
92
93   public static void Refresh(Component source, String id)
94   {
95     Refresh(source, id, false, false);
96   }
97
98   public static void Refresh(Component source, String id,
99           boolean alignmentChanged, boolean validateSequences)
100   {
101     if (components == null)
102     {
103       return;
104     }
105
106     Component comp;
107     Vector<Component> comps = components.get(id);
108
109     if (comps == null)
110     {
111       return;
112     }
113
114     Iterator<Component> it = comps.iterator();
115     while (it.hasNext())
116     {
117       comp = it.next();
118
119       if (comp == source)
120       {
121         continue;
122       }
123
124       if (!comp.isValid())
125       {
126         it.remove();
127       }
128       else if (validateSequences && comp instanceof AlignmentPanel
129               && source instanceof AlignmentPanel)
130       {
131         validateSequences(((AlignmentPanel) source).av.getAlignment(),
132                 ((AlignmentPanel) comp).av.getAlignment());
133       }
134
135       if (comp instanceof AlignmentPanel && alignmentChanged)
136       {
137         ((AlignmentPanel) comp).alignmentChanged();
138       }
139
140       comp.repaint();
141     }
142   }
143
144   static void validateSequences(AlignmentI source, AlignmentI comp)
145   {
146     SequenceI[] a1;
147     if (source.getHiddenSequences().getSize() > 0)
148     {
149       a1 = source.getHiddenSequences().getFullAlignment()
150               .getSequencesArray();
151     }
152     else
153     {
154       a1 = source.getSequencesArray();
155     }
156
157     SequenceI[] a2;
158     if (comp.getHiddenSequences().getSize() > 0)
159     {
160       a2 = comp.getHiddenSequences().getFullAlignment().getSequencesArray();
161     }
162     else
163     {
164       a2 = comp.getSequencesArray();
165     }
166
167     int i, iSize = a1.length, j, jSize = a2.length;
168
169     if (iSize == jSize)
170     {
171       return;
172     }
173
174     boolean exists = false;
175     for (i = 0; i < iSize; i++)
176     {
177       exists = false;
178
179       for (j = 0; j < jSize; j++)
180       {
181         if (a2[j] == a1[i])
182         {
183           exists = true;
184           break;
185         }
186       }
187
188       if (!exists)
189       {
190         if (i < comp.getHeight())
191         {
192           // TODO: the following does not trigger any recalculation of
193           // height/etc, or maintain the dataset
194           List<SequenceI> alsq;
195           synchronized (alsq = comp.getSequences())
196           {
197             alsq.add(i, a1[i]);
198           }
199         }
200         else
201         {
202           comp.addSequence(a1[i]);
203         }
204
205         if (comp.getHiddenSequences().getSize() > 0)
206         {
207           a2 = comp.getHiddenSequences().getFullAlignment()
208                   .getSequencesArray();
209         }
210         else
211         {
212           a2 = comp.getSequencesArray();
213         }
214
215         jSize = a2.length;
216       }
217     }
218
219     iSize = a1.length;
220     jSize = a2.length;
221
222     for (j = 0; j < jSize; j++)
223     {
224       exists = false;
225       for (i = 0; i < iSize; i++)
226       {
227         if (a2[j] == a1[i])
228         {
229           exists = true;
230           break;
231         }
232       }
233
234       if (!exists)
235       {
236         comp.deleteSequence(a2[j]);
237       }
238     }
239   }
240
241   public static AlignmentPanel[] getAssociatedPanels(String id)
242   {
243     Vector<Component> comps = components.get(id);
244     Vector<Component> tmp = new Vector<>();
245     int i, iSize = comps.size();
246     for (i = 0; i < iSize; i++)
247     {
248       if (comps.elementAt(i) instanceof AlignmentPanel)
249       {
250         tmp.addElement(comps.elementAt(i));
251       }
252     }
253     AlignmentPanel[] result = new AlignmentPanel[tmp.size()];
254     for (int ix = 0; ix < result.length; ix++)
255     {
256       result[ix] = (AlignmentPanel) tmp.elementAt(ix);
257     }
258
259     return result;
260   }
261
262 }