1. Project Clover database Fri Dec 6 2024 13:47:14 GMT
  2. Package jalview.gui

File OverviewCanvas.java

 

Coverage histogram

../../img/srcFileCovDistChart8.png
21% of files have more coverage

Code metrics

26
80
10
1
323
213
28
0.35
8
10
2.8

Classes

Class
Line #
Actions
OverviewCanvas 39 80 28
0.775862177.6%
 

Contributing tests

This file is covered by 11 tests. .

Source view

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.gui;
22   
23    import java.awt.Color;
24    import java.awt.Dimension;
25    import java.awt.Graphics;
26    import java.awt.image.BufferedImage;
27    import java.awt.image.RasterFormatException;
28   
29    import javax.swing.JPanel;
30   
31    import jalview.api.AlignViewportI;
32    import jalview.bin.Cache;
33    import jalview.bin.Console;
34    import jalview.renderer.OverviewRenderer;
35    import jalview.renderer.OverviewResColourFinder;
36    import jalview.viewmodel.OverviewDimensions;
37    import jalview.viewmodel.seqfeatures.FeatureRendererModel;
38   
 
39    public class OverviewCanvas extends JPanel
40    {
41    public static final Color OVERVIEW_DEFAULT_GAP = Color.lightGray;
42   
43    public static final Color OVERVIEW_DEFAULT_LEGACY_GAP = Color.white;
44   
45    public static final Color OVERVIEW_DEFAULT_RESIDUE = Color.white;
46   
47    public static final Color OVERVIEW_DEFAULT_LEGACY_RESIDUE = Color.lightGray;
48   
49    public static final Color OVERVIEW_DEFAULT_HIDDEN = Color.darkGray
50    .darker();
51   
52    private static final Color TRANS_GREY = new Color(100, 100, 100, 25);
53   
54    // This is set true if the alignment view changes whilst
55    // the overview is being calculated
56    private volatile boolean restart = false;
57   
58    private volatile boolean updaterunning = false;
59   
60    private boolean dispose = false;
61   
62    private BufferedImage miniMe;
63   
64    private BufferedImage lastMiniMe = null;
65   
66    // Can set different properties in this seqCanvas than
67    // main visible SeqCanvas
68    private SequenceRenderer sr;
69   
70    private jalview.renderer.seqfeatures.FeatureRenderer fr;
71   
72    private OverviewDimensions od;
73   
74    private OverviewRenderer or = null;
75   
76    private AlignViewportI av;
77   
78    private OverviewResColourFinder cf;
79   
80    private ProgressPanel progressPanel;
81   
 
82  43 toggle public OverviewCanvas(OverviewDimensions overviewDims,
83    AlignViewportI alignvp, ProgressPanel pp)
84    {
85  43 od = overviewDims;
86  43 av = alignvp;
87  43 progressPanel = pp;
88   
89  43 sr = new SequenceRenderer(av);
90  43 sr.renderGaps = false;
91  43 fr = new jalview.renderer.seqfeatures.FeatureRenderer(av);
92   
93  43 boolean useLegacy = Cache.getDefault(Preferences.USE_LEGACY_GAP, false);
94  43 Color gapCol = Cache.getDefaultColour(Preferences.GAP_COLOUR,
95    OVERVIEW_DEFAULT_GAP);
96  43 Color hiddenCol = Cache.getDefaultColour(Preferences.HIDDEN_COLOUR,
97    OVERVIEW_DEFAULT_HIDDEN);
98  43 Color residueCol = useLegacy ? OVERVIEW_DEFAULT_LEGACY_RESIDUE
99    : OVERVIEW_DEFAULT_RESIDUE;
100   
101  43 cf = new OverviewResColourFinder(gapCol, residueCol, hiddenCol);
102   
103  43 setSize(od.getWidth(), od.getHeight());
104    }
105   
106    /**
107    * Update the overview dimensions object used by the canvas (e.g. if we change
108    * from showing hidden columns to hiding them or vice versa)
109    *
110    * @param overviewDims
111    */
 
112  0 toggle public void resetOviewDims(OverviewDimensions overviewDims)
113    {
114  0 od = overviewDims;
115    }
116   
117    /**
118    * Signals to drawing code that the associated alignment viewport has changed
119    * and a redraw will be required
120    */
 
121  558 toggle public boolean restartDraw()
122    {
123  558 synchronized (this)
124    {
125  558 if (updaterunning)
126    {
127  427 restart = true;
128  427 if (or != null)
129    {
130  260 or.setRedraw(true);
131    }
132    }
133    else
134    {
135  131 updaterunning = true;
136    }
137  558 return restart;
138    }
139    }
140   
141    /**
142    * Draw the overview sequences
143    *
144    * @param showSequenceFeatures
145    * true if sequence features are to be shown
146    * @param showAnnotation
147    * true if the annotation is to be shown
148    * @param transferRenderer
149    * the renderer to transfer feature colouring from
150    */
 
151  306 toggle public void draw(boolean showSequenceFeatures, boolean showAnnotation,
152    FeatureRendererModel transferRenderer)
153    {
154  306 miniMe = null;
155   
156  306 if (showSequenceFeatures)
157    {
158  45 fr.transferSettings(transferRenderer);
159    }
160   
161  306 setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
162   
163  306 or = new OverviewRenderer(fr, od, av.getAlignment(),
164    av.getResidueShading(), cf);
165   
166  306 or.addPropertyChangeListener(progressPanel);
167   
168  306 miniMe = or.draw(od.getRows(av.getAlignment()),
169    od.getColumns(av.getAlignment()));
170   
171  306 Graphics mg = miniMe.getGraphics();
172   
173  306 if (showAnnotation)
174    {
175  306 mg.translate(0, od.getSequencesHeight());
176  298 or.drawGraph(mg, av.getAlignmentConservationAnnotation(),
177    od.getGraphHeight(), od.getColumns(av.getAlignment()));
178  295 mg.translate(0, -od.getSequencesHeight());
179    }
180   
181  294 or.removePropertyChangeListener(progressPanel);
182  293 or = null;
183  293 if (restart)
184    {
185  172 restart = false;
186  172 if (!dispose)
187    {
188  172 draw(showSequenceFeatures, showAnnotation, transferRenderer);
189    }
190    }
191    else
192    {
193  121 updaterunning = false;
194  121 lastMiniMe = miniMe;
195    }
196    }
197   
 
198  24 toggle @Override
199    public void paintComponent(Graphics g)
200    {
201    // super.paintComponent(g);
202   
203  24 if (restart)
204    {
205  4 if (lastMiniMe == null)
206    {
207  4 g.setColor(Color.white);
208  4 g.fillRect(0, 0, getWidth(), getHeight());
209    }
210    else
211    {
212  0 g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
213    }
214  4 g.setColor(TRANS_GREY);
215  4 g.fillRect(0, 0, getWidth(), getHeight());
216    }
217  20 else if (lastMiniMe != null)
218    {
219    // is this a resize?
220  14 if ((getWidth() > 0) && (getHeight() > 0)
221    && ((getWidth() != od.getWidth())
222    || (getHeight() != od.getHeight())))
223    {
224    // if there is annotation, scale the alignment and annotation
225    // separately
226  0 if (od.getGraphHeight() > 0 && od.getSequencesHeight() > 0 // BH 2019
227    )
228    {
229  0 try
230    {
231  0 BufferedImage topImage = lastMiniMe.getSubimage(0, 0,
232    od.getWidth(), od.getSequencesHeight());
233  0 BufferedImage bottomImage = lastMiniMe.getSubimage(0,
234    od.getSequencesHeight(), od.getWidth(),
235    od.getGraphHeight());
236   
237    // must be done at this point as we rely on using old width/height
238    // above, and new width/height below
239  0 od.setWidth(getWidth());
240  0 od.setHeight(getHeight());
241   
242    // stick the images back together so lastMiniMe is consistent in the
243    // event of a repaint - BUT probably not thread safe
244  0 lastMiniMe = new BufferedImage(od.getWidth(), od.getHeight(),
245    BufferedImage.TYPE_INT_RGB);
246  0 Graphics lg = lastMiniMe.getGraphics();
247  0 lg.drawImage(topImage, 0, 0, od.getWidth(),
248    od.getSequencesHeight(), null);
249  0 lg.drawImage(bottomImage, 0, od.getSequencesHeight(),
250    od.getWidth(), od.getGraphHeight(), this);
251  0 lg.dispose();
252    } catch (RasterFormatException e)
253    {
254  0 Console.debug(
255    "Scaling miscalculation resizing Overview window");
256  0 od.setWidth(getWidth());
257  0 od.setHeight(getHeight());
258    }
259    }
260    else
261    {
262  0 od.setWidth(getWidth());
263  0 od.setHeight(getHeight());
264    }
265   
266    // make sure the box is in the right place
267  0 od.setBoxPosition(av.getAlignment().getHiddenSequences(),
268    av.getAlignment().getHiddenColumns());
269    }
270    // fall back to normal behaviour
271  14 g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
272    }
273    else
274    {
275  6 g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
276    }
277   
278    // draw the box
279  24 g.setColor(Color.red);
280  24 od.drawBox(g);
281    }
282   
 
283  40 toggle public void dispose()
284    {
285  40 dispose = true;
286  40 od = null;
287  40 synchronized (this)
288    {
289  40 restart = true;
290  40 if (or != null)
291    {
292  9 or.setRedraw(true);
293    }
294    }
295    }
296   
 
297  16 toggle public Color getGapColour()
298    {
299  16 return cf.getGapColour();
300    }
301   
 
302  16 toggle public Color getHiddenColour()
303    {
304  16 return cf.getHiddenColour();
305    }
306   
 
307  16 toggle public Color getResidueColour()
308    {
309  16 return cf.getResidueColour();
310    }
311   
312    /**
313    * Sets the colours to use for gaps, residues and hidden regions
314    *
315    * @param gaps
316    * @param residues
317    * @param hidden
318    */
 
319  11 toggle public void setColours(Color gaps, Color residues, Color hidden)
320    {
321  11 cf = new OverviewResColourFinder(gaps, residues, hidden);
322    }
323    }