JAL-2776 repaint everything on toggle group colour
[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.Enumeration;
28 import java.util.Hashtable;
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     for (String id : components.keySet())
82     {
83       Vector<Component> comps = components.get(id);
84       comps.removeElement(comp);
85       if (comps.size() == 0)
86       {
87         components.remove(id);
88       }
89     }
90   }
91
92   public static void Refresh(Component source, String id)
93   {
94     Refresh(source, id, false, false);
95   }
96
97   public static void Refresh(Component source, String id,
98           boolean alignmentChanged, boolean validateSequences)
99   {
100     if (components == null)
101     {
102       return;
103     }
104
105     Component comp;
106     Vector<Component> comps = components.get(id);
107
108     if (comps == null)
109     {
110       return;
111     }
112
113     Enumeration<Component> e = comps.elements();
114     while (e.hasMoreElements())
115     {
116       comp = e.nextElement();
117
118       if (comp == source)
119       {
120         continue;
121       }
122
123       if (!comp.isValid())
124       {
125         comps.removeElement(comp);
126       }
127       else if (validateSequences && comp instanceof AlignmentPanel
128               && source instanceof AlignmentPanel)
129       {
130         validateSequences(((AlignmentPanel) source).av.getAlignment(),
131                 ((AlignmentPanel) comp).av.getAlignment());
132       }
133
134       if (comp instanceof AlignmentPanel && alignmentChanged)
135       {
136         ((AlignmentPanel) comp).alignmentChanged();
137       }
138
139       comp.repaint();
140     }
141   }
142
143   static void validateSequences(AlignmentI source, AlignmentI comp)
144   {
145     SequenceI[] a1;
146     if (source.getHiddenSequences().getSize() > 0)
147     {
148       a1 = source.getHiddenSequences().getFullAlignment()
149               .getSequencesArray();
150     }
151     else
152     {
153       a1 = source.getSequencesArray();
154     }
155
156     SequenceI[] a2;
157     if (comp.getHiddenSequences().getSize() > 0)
158     {
159       a2 = comp.getHiddenSequences().getFullAlignment().getSequencesArray();
160     }
161     else
162     {
163       a2 = comp.getSequencesArray();
164     }
165
166     int i, iSize = a1.length, j, jSize = a2.length;
167
168     if (iSize == jSize)
169     {
170       return;
171     }
172
173     boolean exists = false;
174     for (i = 0; i < iSize; i++)
175     {
176       exists = false;
177
178       for (j = 0; j < jSize; j++)
179       {
180         if (a2[j] == a1[i])
181         {
182           exists = true;
183           break;
184         }
185       }
186
187       if (!exists)
188       {
189         if (i < comp.getHeight())
190         {
191           // TODO: the following does not trigger any recalculation of
192           // height/etc, or maintain the dataset
193           List<SequenceI> alsq;
194           synchronized (alsq = comp.getSequences())
195           {
196             alsq.add(i, a1[i]);
197           }
198         }
199         else
200         {
201           comp.addSequence(a1[i]);
202         }
203
204         if (comp.getHiddenSequences().getSize() > 0)
205         {
206           a2 = comp.getHiddenSequences().getFullAlignment()
207                   .getSequencesArray();
208         }
209         else
210         {
211           a2 = comp.getSequencesArray();
212         }
213
214         jSize = a2.length;
215       }
216     }
217
218     iSize = a1.length;
219     jSize = a2.length;
220
221     for (j = 0; j < jSize; j++)
222     {
223       exists = false;
224       for (i = 0; i < iSize; i++)
225       {
226         if (a2[j] == a1[i])
227         {
228           exists = true;
229           break;
230         }
231       }
232
233       if (!exists)
234       {
235         comp.deleteSequence(a2[j]);
236       }
237     }
238   }
239
240   public static AlignmentPanel[] getAssociatedPanels(String id)
241   {
242     Vector<Component> comps = components.get(id);
243     Vector<Component> tmp = new Vector<>();
244     int i, iSize = comps.size();
245     for (i = 0; i < iSize; i++)
246     {
247       if (comps.elementAt(i) instanceof AlignmentPanel)
248       {
249         tmp.addElement(comps.elementAt(i));
250       }
251     }
252     AlignmentPanel[] result = new AlignmentPanel[tmp.size()];
253     for (int ix = 0; ix < result.length; ix++)
254     {
255       result[ix] = (AlignmentPanel) tmp.elementAt(ix);
256     }
257
258     return result;
259   }
260
261 }