JAL-2388 Rationalised overview panel drawing thread
[jalview.git] / src / jalview / gui / OverviewPanel.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.gui;
22
23 import jalview.viewmodel.OverviewDimensions;
24
25 import java.awt.BorderLayout;
26 import java.awt.Dimension;
27 import java.awt.event.ComponentAdapter;
28 import java.awt.event.ComponentEvent;
29 import java.awt.event.MouseAdapter;
30 import java.awt.event.MouseEvent;
31 import java.awt.event.MouseMotionAdapter;
32
33 import javax.swing.JPanel;
34
35 /**
36  * Panel displaying an overview of the full alignment, with an interactive box
37  * representing the viewport onto the alignment.
38  * 
39  * @author $author$
40  * @version $Revision$
41  */
42 public class OverviewPanel extends JPanel implements Runnable
43 {
44   private OverviewDimensions od;
45
46   private OverviewCanvas oviewCanvas;
47
48   private AlignViewport av;
49
50   private AlignmentPanel ap;
51
52   boolean updateRunning = false;
53
54   /**
55    * Creates a new OverviewPanel object.
56    * 
57    * @param alPanel
58    *          The alignment panel which is shown in the overview panel
59    */
60   public OverviewPanel(AlignmentPanel alPanel)
61   {
62     this.av = alPanel.av;
63     this.ap = alPanel;
64
65     od = new OverviewDimensions(av.getRanges(),
66             (av.isShowAnnotation() && av
67                     .getAlignmentConservationAnnotation() != null));
68
69     oviewCanvas = new OverviewCanvas(od, av, ap);
70     setLayout(new BorderLayout());
71     add(oviewCanvas, BorderLayout.CENTER);
72
73     addComponentListener(new ComponentAdapter()
74     {
75       @Override
76       public void componentResized(ComponentEvent evt)
77       {
78         if ((getWidth() != od.getWidth())
79                 || (getHeight() != (od.getHeight())))
80         {
81           updateOverviewImage();
82         }
83       }
84     });
85
86     addMouseMotionListener(new MouseMotionAdapter()
87     {
88       @Override
89       public void mouseDragged(MouseEvent evt)
90       {
91         if (!av.getWrapAlignment())
92         {
93           od.updateViewportFromMouse(evt.getX(), evt.getY(), av
94                   .getAlignment().getHiddenSequences(), av
95                   .getColumnSelection(), av.getRanges());
96           ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
97         }
98       }
99     });
100
101     addMouseListener(new MouseAdapter()
102     {
103       @Override
104       public void mousePressed(MouseEvent evt)
105       {
106         if (!av.getWrapAlignment())
107         {
108           od.updateViewportFromMouse(evt.getX(), evt.getY(), av
109                   .getAlignment().getHiddenSequences(), av
110                   .getColumnSelection(), av.getRanges());
111           ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
112         }
113       }
114     });
115
116     updateOverviewImage();
117   }
118
119   /**
120    * Updates the overview image when the related alignment panel is updated
121    */
122   public void updateOverviewImage()
123   {
124     if ((getWidth() > 0) && (getHeight() > 0))
125     {
126       od.setWidth(getWidth());
127       od.setHeight(getHeight());
128     }
129
130     setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
131
132     if (updateRunning)
133     {
134       oviewCanvas.restartDraw();
135       return;
136     }
137
138     updateRunning = true;
139     Thread thread = new Thread(this);
140     thread.start();
141     repaint();
142     updateRunning = false;
143   }
144
145   @Override
146   public void run()
147   {
148     oviewCanvas.draw(av.isShowSequenceFeatures(),
149             (av.isShowAnnotation() && av
150                     .getAlignmentConservationAnnotation() != null));
151     setBoxPosition();
152   }
153
154   /**
155    * Update the overview panel box when the associated alignment panel is
156    * changed
157    * 
158    */
159   public void setBoxPosition()
160   {
161     od.setBoxPosition(av.getAlignment()
162             .getHiddenSequences(), av.getColumnSelection(), av.getRanges());
163     repaint();
164   }
165 }