Features are an array, rendering is faster
[jalview.git] / src / jalview / appletgui / FeatureSettings.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.appletgui;\r
20 \r
21 import jalview.datamodel.*;\r
22 import java.awt.*;\r
23 import java.util.*;\r
24 import java.awt.event.*;\r
25 \r
26 \r
27 public class FeatureSettings extends Panel implements ItemListener,\r
28     MouseListener, MouseMotionListener\r
29 {\r
30   final FeatureRenderer fr;\r
31   final AlignmentPanel ap;\r
32   final AlignViewport av;\r
33   final Frame frame;\r
34   Panel groupPanel;\r
35   Panel featurePanel = new Panel();\r
36   ScrollPane scrollPane;\r
37 \r
38   public FeatureSettings(AlignViewport av, final AlignmentPanel ap)\r
39   {\r
40     this.ap = ap;\r
41     this.av = av;\r
42     fr = ap.seqPanel.seqCanvas.getFeatureRenderer();\r
43 \r
44     setTableData();\r
45 \r
46     this.setLayout(new BorderLayout());\r
47     scrollPane = new ScrollPane();\r
48     scrollPane.add(featurePanel);\r
49     add(scrollPane, BorderLayout.CENTER);\r
50     if(groupPanel!=null)\r
51     {\r
52       groupPanel.setLayout(\r
53           new GridLayout(groupPanel.getComponentCount() / 4, 4));\r
54       groupPanel.validate();\r
55 \r
56       add(groupPanel, BorderLayout.NORTH);\r
57     }\r
58     frame = new Frame();\r
59     frame.add(this);\r
60     int height = featurePanel.getComponentCount()*50 ;\r
61     if (height>400)\r
62       height = 400;\r
63 \r
64     jalview.bin.JalviewLite.addFrame(frame, "Feature Settings", 250,\r
65                                      height);\r
66   }\r
67 \r
68   void setTableData()\r
69   {\r
70     if(fr.featureGroups==null)\r
71       fr.featureGroups = new Hashtable();\r
72     else\r
73       fr.featureGroups.clear();\r
74 \r
75     Vector allFeatures = new Vector();\r
76     SequenceFeature[] tmpfeatures;\r
77 \r
78     for (int i = 0; i < av.alignment.getHeight(); i++)\r
79     {\r
80       if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)\r
81         continue;\r
82 \r
83       tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();\r
84       int index = 0;\r
85       while (index < tmpfeatures.length)\r
86       {\r
87         if(tmpfeatures[index].getFeatureGroup()!=null\r
88            && tmpfeatures[index].getFeatureGroup().length()>0\r
89            && !fr.featureGroups.containsKey(tmpfeatures[index].getFeatureGroup()))\r
90         {\r
91           fr.featureGroups.put(tmpfeatures[index].getFeatureGroup(), new Boolean(true));\r
92           if(groupPanel==null)\r
93           {\r
94             groupPanel = new Panel();\r
95           }\r
96 \r
97           Checkbox check = new Checkbox(tmpfeatures[index].getFeatureGroup(), true);\r
98           check.setFont(new Font("Serif", Font.BOLD, 12));\r
99           check.addItemListener(this);\r
100           groupPanel.add(check);\r
101         }\r
102 \r
103         if (!allFeatures.contains(tmpfeatures[index].getType()))\r
104         {\r
105             allFeatures.addElement(tmpfeatures[index].getType());\r
106         }\r
107 \r
108 \r
109         index ++;\r
110       }\r
111     }\r
112 \r
113     resetTable();\r
114     featurePanel.setLayout(new GridLayout(allFeatures.size(), 2, 10,5));\r
115     featurePanel.validate();\r
116   }\r
117 \r
118   void resetTable()\r
119   {\r
120     featurePanel.removeAll();\r
121     Enumeration groups = fr.featureGroups.keys();\r
122     SequenceFeature [] tmpfeatures;\r
123     String group, type;\r
124     Vector checksAdded = new Vector();\r
125 \r
126     while(groups.hasMoreElements())\r
127     {\r
128      group = groups.nextElement().toString();\r
129      if ( !( (Boolean) fr.featureGroups.get(group)).booleanValue())\r
130        continue;\r
131 \r
132      for (int i = 0; i < av.alignment.getHeight(); i++)\r
133        {\r
134          if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)\r
135            continue;\r
136 \r
137          tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();\r
138          int index = 0;\r
139          while (index < tmpfeatures.length)\r
140          {\r
141            if (tmpfeatures[index].getFeatureGroup() != null &&\r
142                tmpfeatures[index].getFeatureGroup().equals(group))\r
143            {\r
144              type = tmpfeatures[index].getType();\r
145              if(!checksAdded.contains(type))\r
146              {\r
147                checksAdded.addElement(type);\r
148                Checkbox check = new Checkbox(type, true);\r
149                check.addMouseListener(this);\r
150                check.addMouseMotionListener(this);\r
151                check.setBackground(fr.getColour(type));\r
152                check.addItemListener(this);\r
153                featurePanel.add(check);\r
154              }\r
155            }\r
156            index++;\r
157          }\r
158      }\r
159    }\r
160    featurePanel.validate();\r
161    if(scrollPane!=null)\r
162      scrollPane.validate();\r
163   }\r
164 \r
165   public void itemStateChanged(ItemEvent evt)\r
166   {\r
167     if (evt != null)\r
168     {\r
169       //Is the source a top level featureGroup?\r
170       Checkbox source = (Checkbox) evt.getSource();\r
171       if (fr.featureGroups.containsKey(source.getLabel()))\r
172       {\r
173         fr.featureGroups.put(source.getLabel(), new Boolean(source.getState()));\r
174         ap.seqPanel.seqCanvas.repaint();\r
175         if (ap.overviewPanel != null)\r
176           ap.overviewPanel.updateOverviewImage();\r
177 \r
178         resetTable();\r
179         return;\r
180       }\r
181     }\r
182 \r
183       Component[] comps = featurePanel.getComponents();\r
184       int cSize = comps.length;\r
185 \r
186       Object[][] tmp = new Object[cSize][3];\r
187       int tmpSize = 0;\r
188       for (int i = 0; i < cSize; i++)\r
189       {\r
190         Checkbox check = (Checkbox) comps[i];\r
191         if(!check.getState())\r
192           continue;\r
193 \r
194         tmp[tmpSize][0] = check.getLabel();\r
195         tmp[tmpSize][1] = fr.getColour(check.getLabel());\r
196         tmp[tmpSize][2] = new Boolean(check.getState());\r
197         tmpSize++;\r
198       }\r
199 \r
200       Object[][]data = new Object[tmpSize][3];\r
201       System.arraycopy(tmp, 0, data,0, tmpSize);\r
202 \r
203       fr.setFeaturePriority(data);\r
204       ap.seqPanel.seqCanvas.repaint();\r
205       if (ap.overviewPanel != null)\r
206         ap.overviewPanel.updateOverviewImage();\r
207   }\r
208 \r
209   Checkbox selectedCheck;\r
210   boolean dragging = false;\r
211 \r
212   public void mousePressed(MouseEvent evt)\r
213   {\r
214     selectedCheck = (Checkbox)evt.getSource();\r
215   }\r
216 \r
217   public void mouseDragged(MouseEvent evt)\r
218   {\r
219       dragging = true;\r
220   }\r
221 \r
222   public void mouseReleased(MouseEvent evt)\r
223   {\r
224     Component comp = null;\r
225     Checkbox  target = null;\r
226 \r
227     int height = evt.getY()+evt.getComponent().getLocation().y;\r
228 \r
229 \r
230     if(height > this.getSize().height)\r
231      {\r
232        comp = featurePanel.getComponent(featurePanel.getComponentCount()-1);\r
233      }\r
234      else if(height < 0)\r
235      {\r
236        comp = featurePanel.getComponent(0);\r
237      }\r
238      else\r
239      {\r
240        comp = featurePanel.getComponentAt(evt.getX(),\r
241                                   evt.getY() +\r
242                                   evt.getComponent().getLocation().y);\r
243      }\r
244 \r
245     if(comp!=null && comp instanceof Checkbox)\r
246       target = (Checkbox)comp;\r
247 \r
248     if (selectedCheck != null && target != null && selectedCheck != target)\r
249     {\r
250       int targetIndex = -1;\r
251       for(int i=0; i<featurePanel.getComponentCount(); i++)\r
252       {\r
253           if(target==featurePanel.getComponent(i))\r
254           { targetIndex = i; break; }\r
255       }\r
256 \r
257 \r
258       featurePanel.remove(selectedCheck);\r
259       featurePanel.add(selectedCheck, targetIndex);\r
260       featurePanel.validate();\r
261       itemStateChanged(null);\r
262     }\r
263   }\r
264 \r
265 \r
266   public void mouseEntered(MouseEvent evt){}\r
267   public void mouseExited(MouseEvent evt){}\r
268   public void mouseClicked(MouseEvent evt){}\r
269   public void mouseMoved(MouseEvent evt){}\r
270 }\r