21a222495efd79ec8dd8305af7946356fff40feb
[jalview.git] / src / jalview / gui / PaintRefresher.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.gui;
19
20 import java.util.*;
21 import java.util.List;
22
23 import java.awt.*;
24
25 import jalview.datamodel.*;
26
27 /**
28  * Route datamodel/view update events for a sequence set to any display components involved
29  * TODO: JV3 refactor to abstract gui/view package
30  * 
31  * @author $author$
32  * @version $Revision$
33  */
34 public class PaintRefresher
35 {
36   static Hashtable components;
37
38   /**
39    * DOCUMENT ME!
40    * 
41    * @param comp
42    *          DOCUMENT ME!
43    * @param al
44    *          DOCUMENT ME!
45    */
46   public static void Register(Component comp, String seqSetId)
47   {
48     if (components == null)
49     {
50       components = new Hashtable();
51     }
52
53     if (components.containsKey(seqSetId))
54     {
55       Vector comps = (Vector) components.get(seqSetId);
56       if (!comps.contains(comp))
57       {
58         comps.addElement(comp);
59       }
60     }
61     else
62     {
63       Vector vcoms = new Vector();
64       vcoms.addElement(comp);
65       components.put(seqSetId, vcoms);
66     }
67   }
68
69   public static void RemoveComponent(Component comp)
70   {
71     if (components == null)
72     {
73       return;
74     }
75
76     Enumeration en = components.keys();
77     while (en.hasMoreElements())
78     {
79       String id = en.nextElement().toString();
80       Vector comps = (Vector) components.get(id);
81       comps.remove(comp);
82       if (comps.size() == 0)
83       {
84         components.remove(id);
85       }
86     }
87   }
88
89   public static void Refresh(Component source, String id)
90   {
91     Refresh(source, id, false, false);
92   }
93
94   public static void Refresh(Component source, String id,
95           boolean alignmentChanged, boolean validateSequences)
96   {
97     if (components == null)
98     {
99       return;
100     }
101
102     Component comp;
103     Vector comps = (Vector) components.get(id);
104
105     if (comps == null)
106     {
107       return;
108     }
109
110     Enumeration e = comps.elements();
111     while (e.hasMoreElements())
112     {
113       comp = (Component) e.nextElement();
114
115       if (comp == source)
116       {
117         continue;
118       }
119
120       if (validateSequences && comp instanceof AlignmentPanel
121               && source instanceof AlignmentPanel)
122       {
123         validateSequences(((AlignmentPanel) source).av.getAlignment(),
124                 ((AlignmentPanel) comp).av.getAlignment());
125       }
126
127       if (comp instanceof AlignmentPanel && alignmentChanged)
128       {
129         ((AlignmentPanel) comp).alignmentChanged();
130       }
131
132       comp.repaint();
133     }
134   }
135
136   static void validateSequences(AlignmentI source, AlignmentI comp)
137   {
138     SequenceI[] a1;
139     if (source.getHiddenSequences().getSize() > 0)
140     {
141       a1 = source.getHiddenSequences().getFullAlignment()
142               .getSequencesArray();
143     }
144     else
145     {
146       a1 = source.getSequencesArray();
147     }
148
149     SequenceI[] a2;
150     if (comp.getHiddenSequences().getSize() > 0)
151     {
152       a2 = comp.getHiddenSequences().getFullAlignment().getSequencesArray();
153     }
154     else
155     {
156       a2 = comp.getSequencesArray();
157     }
158
159     int i, iSize = a1.length, j, jSize = a2.length;
160
161     if (iSize == jSize)
162     {
163       return;
164     }
165
166     boolean exists = false;
167     for (i = 0; i < iSize; i++)
168     {
169       exists = false;
170
171       for (j = 0; j < jSize; j++)
172       {
173         if (a2[j] == a1[i])
174         {
175           exists = true;
176           break;
177         }
178       }
179
180       if (!exists)
181       {
182         if (i < comp.getHeight())
183         {
184           // TODO: the following does not trigger any recalculation of
185           // height/etc, or maintain the dataset
186           if (comp.getDataset() != source.getDataset())
187           {
188             // raise an implementation warning here - not sure if this situation
189             // will ever occur
190             System.err
191                     .println("IMPLEMENTATION PROBLEM: DATASET out of sync due to an insert whilst calling PaintRefresher.validateSequences(AlignmentI, ALignmentI)");
192           }
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   static AlignmentPanel[] getAssociatedPanels(String id)
241   {
242     if (components == null)
243     {
244       return new AlignmentPanel[0];
245     }
246     ;
247     Vector comps = (Vector) components.get(id);
248     if (comps == null)
249     {
250       return new AlignmentPanel[0];
251     }
252     ;
253     Vector tmp = new Vector();
254     int i, iSize = comps.size();
255     for (i = 0; i < iSize; i++)
256     {
257       if (comps.elementAt(i) instanceof AlignmentPanel)
258       {
259         tmp.addElement(comps.elementAt(i));
260       }
261     }
262     AlignmentPanel[] result = new AlignmentPanel[tmp.size()];
263     tmp.toArray(result);
264
265     return result;
266   }
267
268 }