ensure lastSeq is refreshed if new feature added
[jalview.git] / src / jalview / gui / FeatureRenderer.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 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.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import java.awt.*;\r
24 \r
25 import java.util.*;\r
26 \r
27 import java.awt.image.*;\r
28 import javax.swing.*;\r
29 import javax.swing.JOptionPane;\r
30 import java.awt.event.*;\r
31 \r
32 \r
33 /**\r
34  * DOCUMENT ME!\r
35  *\r
36  * @author $author$\r
37  * @version $Revision$\r
38  */\r
39 public class FeatureRenderer\r
40 {\r
41     AlignViewport av;\r
42     Color resBoxColour;\r
43     float transparency = 1.0f;\r
44     FontMetrics fm;\r
45     int charOffset;\r
46 \r
47     Hashtable featureColours = new Hashtable();\r
48 \r
49 \r
50     // A higher level for grouping features of a\r
51    // particular type\r
52     Hashtable featureGroups = null;\r
53 \r
54     // This is actually an Integer held in the hashtable,\r
55     // Retrieved using the key feature type\r
56     Object currentColour;\r
57 \r
58     String [] renderOrder;\r
59 \r
60     /**\r
61      * Creates a new FeatureRenderer object.\r
62      *\r
63      * @param av DOCUMENT ME!\r
64      */\r
65     public FeatureRenderer(AlignViewport av)\r
66     {\r
67         this.av = av;\r
68     }\r
69 \r
70     public void transferSettings(FeatureRenderer fr)\r
71     {\r
72       renderOrder = fr.renderOrder;\r
73       featureGroups = fr.featureGroups;\r
74       featureColours = fr.featureColours;\r
75       transparency =  fr.transparency;\r
76     }\r
77 \r
78     BufferedImage offscreenImage;\r
79     boolean offscreenRender = false;\r
80     public Color findFeatureColour(Color initialCol, SequenceI seq, int res)\r
81     {\r
82       return new Color( findFeatureColour (initialCol.getRGB(),\r
83                         seq, res ));\r
84     }\r
85 \r
86     /**\r
87      * This is used by the Molecule Viewer and Overview to\r
88      * get the accurate colourof the rendered sequence\r
89      */\r
90     public int findFeatureColour(int initialCol, SequenceI seq, int column)\r
91     {\r
92       if(!av.showSequenceFeatures)\r
93         return initialCol;\r
94 \r
95       if(seq!=lastSeq)\r
96       {\r
97         lastSeq = seq;\r
98         sequenceFeatures = lastSeq.getDatasetSequence().getSequenceFeatures();\r
99         if(sequenceFeatures==null)\r
100           return initialCol;\r
101 \r
102         sfSize = sequenceFeatures.length;\r
103       }\r
104 \r
105       if(jalview.util.Comparison.isGap(lastSeq.getCharAt(column)))\r
106         return Color.white.getRGB();\r
107 \r
108 \r
109       //Only bother making an offscreen image if transparency is applied\r
110       if(transparency!=1.0f && offscreenImage==null)\r
111       {\r
112         offscreenImage = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);\r
113       }\r
114 \r
115       currentColour = null;\r
116 \r
117       offscreenRender = true;\r
118 \r
119       if(offscreenImage!=null)\r
120       {\r
121         offscreenImage.setRGB(0,0,initialCol);\r
122         drawSequence(offscreenImage.getGraphics(),\r
123                      lastSeq,\r
124                      column,column,0);\r
125 \r
126         return offscreenImage.getRGB(0,0);\r
127       }\r
128       else\r
129       {\r
130         drawSequence(null,\r
131                     lastSeq,\r
132                     lastSeq.findPosition(column),\r
133                     -1, -1);\r
134 \r
135         if (currentColour == null)\r
136           return initialCol;\r
137         else\r
138           return  ((Integer)currentColour).intValue();\r
139       }\r
140 \r
141 \r
142     }\r
143 \r
144 \r
145     /**\r
146      * DOCUMENT ME!\r
147      *\r
148      * @param g DOCUMENT ME!\r
149      * @param seq DOCUMENT ME!\r
150      * @param sg DOCUMENT ME!\r
151      * @param start DOCUMENT ME!\r
152      * @param end DOCUMENT ME!\r
153      * @param x1 DOCUMENT ME!\r
154      * @param y1 DOCUMENT ME!\r
155      * @param width DOCUMENT ME!\r
156      * @param height DOCUMENT ME!\r
157      */\r
158    // String type;\r
159    // SequenceFeature sf;\r
160     SequenceI lastSeq;\r
161     SequenceFeature [] sequenceFeatures;\r
162     int sfSize, sfindex, spos, epos;\r
163 \r
164     public void drawSequence(Graphics g, SequenceI seq,\r
165                              int start, int end, int y1)\r
166     {\r
167       if ( seq.getDatasetSequence().getSequenceFeatures() == null\r
168           || seq.getDatasetSequence().getSequenceFeatures().length==0)\r
169         return;\r
170 \r
171       if(g!=null)\r
172         fm = g.getFontMetrics();\r
173 \r
174 \r
175       if (av.featuresDisplayed == null\r
176           || renderOrder==null\r
177           || newFeatureAdded)\r
178        {\r
179          findAllFeatures();\r
180          if(av.featuresDisplayed.size()<1)\r
181            return;\r
182 \r
183          sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();\r
184          sfSize = sequenceFeatures.length;\r
185        }\r
186 \r
187        if(lastSeq==null || seq!=lastSeq)\r
188       {\r
189         lastSeq = seq;\r
190         sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();\r
191         sfSize = sequenceFeatures.length;\r
192       }\r
193 \r
194 \r
195       if (transparency != 1 && g!=null)\r
196       {\r
197         Graphics2D g2 = (Graphics2D) g;\r
198         g2.setComposite(\r
199             AlphaComposite.getInstance(\r
200                 AlphaComposite.SRC_OVER, transparency));\r
201       }\r
202 \r
203       if(!offscreenRender)\r
204       {\r
205         spos = lastSeq.findPosition(start);\r
206         epos = lastSeq.findPosition(end);\r
207       }\r
208 \r
209 \r
210       String type;\r
211       for(int renderIndex=0; renderIndex<renderOrder.length; renderIndex++)\r
212        {\r
213         type =  renderOrder[renderIndex];\r
214 \r
215         if(type==null || !av.featuresDisplayed.containsKey(type))\r
216           continue;\r
217 \r
218         // loop through all features in sequence to find\r
219         // current feature to render\r
220         for (sfindex = 0; sfindex < sfSize; sfindex++)\r
221         {\r
222           if(sequenceFeatures.length<=sfindex)\r
223           {\r
224             continue;\r
225           }\r
226           if (!sequenceFeatures[sfindex].type.equals(type))\r
227             continue;\r
228 \r
229           if (featureGroups != null\r
230               && sequenceFeatures[sfindex].featureGroup != null\r
231               &&\r
232               featureGroups.containsKey(sequenceFeatures[sfindex].featureGroup)\r
233               &&\r
234               ! ( (Boolean) featureGroups.get(sequenceFeatures[sfindex].featureGroup)).\r
235               booleanValue())\r
236           {\r
237             continue;\r
238           }\r
239 \r
240           if (!offscreenRender && (sequenceFeatures[sfindex].getBegin() > epos\r
241                             || sequenceFeatures[sfindex].getEnd() < spos))\r
242             continue;\r
243 \r
244           if (offscreenRender && offscreenImage==null)\r
245           {\r
246             if (sequenceFeatures[sfindex].begin <= start &&\r
247                 sequenceFeatures[sfindex].end  >= start)\r
248             {\r
249               currentColour = av.featuresDisplayed.get(sequenceFeatures[sfindex].\r
250                  type);\r
251             }\r
252           }\r
253           else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))\r
254           {\r
255 \r
256             renderFeature(g, seq,\r
257                           seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
258                           seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
259                           new Color( ( (Integer) av.featuresDisplayed.get(\r
260                 sequenceFeatures[sfindex].type)).intValue()),\r
261                           start, end, y1);\r
262             renderFeature(g, seq,\r
263                           seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
264                           seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
265                           new Color( ( (Integer) av.featuresDisplayed.get(\r
266                 sequenceFeatures[sfindex].type)).intValue()),\r
267                           start, end, y1);\r
268 \r
269           }\r
270           else\r
271             renderFeature(g, seq,\r
272                           seq.findIndex(sequenceFeatures[sfindex].begin) - 1,\r
273                           seq.findIndex(sequenceFeatures[sfindex].end) - 1,\r
274                           getColour(sequenceFeatures[sfindex].type),\r
275                           start, end, y1);\r
276 \r
277 \r
278         }\r
279 \r
280       }\r
281 \r
282         if(transparency!=1.0f && g!=null)\r
283         {\r
284           Graphics2D g2 = (Graphics2D) g;\r
285           g2.setComposite(\r
286               AlphaComposite.getInstance(\r
287                   AlphaComposite.SRC_OVER, 1.0f));\r
288         }\r
289     }\r
290 \r
291 \r
292     char s;\r
293     int i;\r
294     void renderFeature(Graphics g, SequenceI seq,\r
295                        int fstart, int fend, Color featureColour, int start, int end,  int y1)\r
296     {\r
297 \r
298       if (((fstart <= end) && (fend >= start)))\r
299       {\r
300         if (fstart < start)\r
301         { // fix for if the feature we have starts before the sequence start,\r
302           fstart = start; // but the feature end is still valid!!\r
303         }\r
304 \r
305         if (fend >= end)\r
306         {\r
307           fend = end;\r
308         }\r
309           int pady = (y1 + av.charHeight) - av.charHeight / 5;\r
310           for (i = fstart; i <= fend; i++)\r
311           {\r
312             s = seq.getCharAt(i);\r
313 \r
314             if (jalview.util.Comparison.isGap(s))\r
315             {\r
316               continue;\r
317             }\r
318 \r
319             g.setColor(featureColour);\r
320 \r
321             g.fillRect( (i - start) * av.charWidth, y1, av.charWidth,av.charHeight);\r
322 \r
323             if(offscreenRender || !av.validCharWidth)\r
324               continue;\r
325 \r
326             g.setColor(Color.white);\r
327             charOffset = (av.charWidth - fm.charWidth(s)) / 2;\r
328             g.drawString(String.valueOf(s),\r
329                          charOffset + (av.charWidth * (i - start)),\r
330                          pady);\r
331 \r
332           }\r
333       }\r
334     }\r
335 \r
336 \r
337     boolean newFeatureAdded = false;\r
338 \r
339     public void featuresAdded()\r
340     {\r
341       findAllFeatures();\r
342     }\r
343 \r
344    boolean findingFeatures = false;\r
345    synchronized void findAllFeatures()\r
346    {\r
347       newFeatureAdded = false;\r
348 \r
349       if(findingFeatures)\r
350       {\r
351         newFeatureAdded = true;\r
352         return;\r
353       }\r
354 \r
355       findingFeatures = true;\r
356       jalview.schemes.UserColourScheme ucs = new\r
357           jalview.schemes.UserColourScheme();\r
358 \r
359       if(av.featuresDisplayed==null)\r
360         av.featuresDisplayed = new Hashtable();\r
361 \r
362       av.featuresDisplayed.clear();\r
363 \r
364       Vector allfeatures = new Vector();\r
365       for (int i = 0; i < av.alignment.getHeight(); i++)\r
366       {\r
367         SequenceFeature [] features\r
368             = av.alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();\r
369 \r
370         if (features == null)\r
371           continue;\r
372 \r
373         int index = 0;\r
374         while (index < features.length)\r
375         {\r
376           if (!av.featuresDisplayed.containsKey(features[index].getType()))\r
377           {\r
378             if(!(features[index].begin == 0 && features[index].end ==0))\r
379             {\r
380               // If beginning and end are 0, the feature is for the whole sequence\r
381               // and we don't want to render the feature in the normal way\r
382 \r
383               if (getColour(features[index].getType()) == null)\r
384               {\r
385                  featureColours.put(features[index].getType(),\r
386                                    ucs.createColourFromName(features[index].\r
387                     getType()));\r
388               }\r
389 \r
390               av.featuresDisplayed.put(features[index].getType(),\r
391                                        new Integer(getColour(features[index].\r
392                   getType()).getRGB()));\r
393               allfeatures.addElement(features[index].getType());\r
394             }\r
395           }\r
396           index++;\r
397         }\r
398       }\r
399 \r
400       renderOrder = new String[allfeatures.size()];\r
401       Enumeration en = allfeatures.elements();\r
402       int i = allfeatures.size()-1;\r
403       while(en.hasMoreElements())\r
404       {\r
405         renderOrder[i] = en.nextElement().toString();\r
406         i--;\r
407       }\r
408 \r
409       findingFeatures = false;\r
410     }\r
411 \r
412     public Color getColour(String featureType)\r
413     {\r
414       Color colour = (Color)featureColours.get(featureType);\r
415       return colour;\r
416     }\r
417 \r
418 \r
419     static String lastFeatureAdded;\r
420     static String lastFeatureGroupAdded;\r
421     static String lastDescriptionAdded;\r
422 \r
423     public boolean createNewFeatures(SequenceI[] sequences,\r
424                                   SequenceFeature [] features)\r
425     {\r
426       return amendFeatures(sequences, features, true, null);\r
427     }\r
428 \r
429     int featureIndex = 0;\r
430     boolean amendFeatures(final SequenceI[] sequences,\r
431                           final SequenceFeature[] features,\r
432                           boolean newFeatures,\r
433                           final AlignmentPanel ap)\r
434     {\r
435       JPanel bigPanel = new JPanel(new BorderLayout());\r
436       final JComboBox name = new JComboBox();\r
437       final JComboBox source = new JComboBox();\r
438       final JTextArea description = new JTextArea(3,25);\r
439       final JSpinner start = new JSpinner();\r
440       final JSpinner end = new JSpinner();\r
441       start.setPreferredSize(new Dimension(80,20));\r
442       end.setPreferredSize(new Dimension(80,20));\r
443       final JPanel colour = new JPanel();\r
444       colour.setBorder(BorderFactory.createEtchedBorder());\r
445       colour.setMaximumSize(new Dimension(40,10));\r
446       colour.addMouseListener(new MouseAdapter()\r
447           {\r
448             public void mousePressed(MouseEvent evt)\r
449             {\r
450               colour.setBackground(\r
451                   JColorChooser.showDialog(Desktop.desktop,\r
452                                            "Select Feature Colour",\r
453                                            colour.getBackground()));\r
454             }\r
455           });\r
456 \r
457       JPanel panel = new JPanel(new GridLayout(3, 2));\r
458       panel.add(new JLabel("Sequence Feature Name: ",JLabel.RIGHT));\r
459       panel.add(name);\r
460       panel.add(new JLabel("Feature Group: ", JLabel.RIGHT));\r
461       panel.add(source);\r
462       panel.add(new JLabel("Feature Colour: ", JLabel.RIGHT));\r
463       JPanel tmp = new JPanel();\r
464       tmp.add(colour);\r
465       colour.setPreferredSize(new Dimension(150,15));\r
466       panel.add(tmp);\r
467       name.setEditable(true);\r
468       source.setEditable(true);\r
469 \r
470       bigPanel.add(panel, BorderLayout.NORTH);\r
471       panel = new JPanel();\r
472       panel.add(new JLabel("Description: ", JLabel.RIGHT));\r
473       description.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
474       description.setLineWrap(true);\r
475       panel.add(new JScrollPane(description));\r
476 \r
477       if(!newFeatures)\r
478       {\r
479         bigPanel.add(panel, BorderLayout.SOUTH);\r
480 \r
481         panel = new JPanel();\r
482         panel.add(new JLabel(" Start:", JLabel.RIGHT));\r
483         panel.add(start);\r
484         panel.add(new JLabel("  End:", JLabel.RIGHT));\r
485         panel.add(end);\r
486         bigPanel.add(panel, BorderLayout.CENTER);\r
487       }\r
488       else\r
489         bigPanel.add(panel, BorderLayout.CENTER);\r
490 \r
491       if (lastFeatureAdded == null)\r
492         if (features[0].type != null)\r
493           lastFeatureAdded = features[0].type;\r
494         else\r
495           lastFeatureAdded = "feature_1";\r
496 \r
497       if (lastFeatureGroupAdded == null)\r
498         if (features[0].featureGroup != null)\r
499           lastFeatureGroupAdded = features[0].featureGroup;\r
500         else\r
501           lastFeatureAdded = "Jalview";\r
502 \r
503 \r
504       Enumeration en;\r
505       if (featureGroups != null)\r
506       {\r
507         en = featureGroups.keys();\r
508         while (en.hasMoreElements())\r
509         {\r
510           source.addItem(en.nextElement().toString());\r
511         }\r
512       }\r
513 \r
514       if (newFeatures)\r
515       {\r
516         if(av.featuresDisplayed != null)\r
517         {\r
518           en = av.featuresDisplayed.keys();\r
519           while (en.hasMoreElements())\r
520           {\r
521             name.addItem(en.nextElement().toString());\r
522           }\r
523         }\r
524 \r
525         name.setSelectedItem(lastFeatureAdded);\r
526         source.setSelectedItem(lastFeatureGroupAdded);\r
527         description.setText(\r
528             lastDescriptionAdded == null ?\r
529             features[0].description : lastDescriptionAdded);\r
530 \r
531         if (getColour(lastFeatureAdded) != null)\r
532         {\r
533           colour.setBackground(getColour(lastFeatureAdded));\r
534         }\r
535         else\r
536         {\r
537           colour.setBackground(new Color(60, 160, 115));\r
538         }\r
539 \r
540       }\r
541       else if (!newFeatures)\r
542       {\r
543         featureIndex = 0;\r
544         for(int f=0; f<features.length; f++)\r
545         {\r
546           name.addItem(features[f].getType().toString());\r
547         }\r
548 \r
549         description.setText(features[0].getDescription());\r
550         source.setSelectedItem(features[0].getFeatureGroup());\r
551         start.setValue(new Integer(features[0].getBegin()));\r
552         end.setValue(new Integer(features[0].getEnd()));\r
553         colour.setBackground(\r
554                 getColour(name.getSelectedItem().toString()));\r
555         name.addItemListener(new ItemListener()\r
556         {\r
557           public void itemStateChanged(ItemEvent e)\r
558           {\r
559             int index = name.getSelectedIndex();\r
560             if(index!=-1)\r
561             {\r
562               featureIndex = index;\r
563               description.setText(features[index].getDescription());\r
564               source.setSelectedItem(features[index].getFeatureGroup());\r
565               start.setValue(new Integer(features[index].getBegin()));\r
566               end.setValue(new Integer(features[index].getEnd()));\r
567               colour.setBackground(\r
568                   getColour(name.getSelectedItem().toString()));\r
569 \r
570               SearchResults highlight = new SearchResults();\r
571               highlight.addResult(sequences[0],\r
572                                   features[index].getBegin(),\r
573                                   features[index].getEnd());\r
574 \r
575               ap.seqPanel.seqCanvas.highlightSearchResults(highlight);\r
576 \r
577             }\r
578             Color col = getColour(name.getSelectedItem().toString());\r
579             if (col == null)\r
580               col = new\r
581                   jalview.schemes.UserColourScheme()\r
582                   .createColourFromName(name.getSelectedItem().toString());\r
583 \r
584             colour.setBackground(col);\r
585           }\r
586         });\r
587 \r
588       }\r
589 \r
590 \r
591       Object [] options;\r
592       if(!newFeatures)\r
593         options = new Object[]{"Amend", "Delete", "Cancel"};\r
594       else\r
595         options = new Object[]{"OK", "Cancel"};\r
596 \r
597       String title = newFeatures ?  "Create New Sequence Feature(s)" :\r
598                                     "Amend/Delete Features for "\r
599                                     +sequences[0].getName();\r
600 \r
601       int reply = JOptionPane.showInternalOptionDialog(Desktop.desktop,\r
602                                                    bigPanel,\r
603                                                    title,\r
604                                                    JOptionPane.YES_NO_CANCEL_OPTION,\r
605                                                    JOptionPane.QUESTION_MESSAGE,\r
606                                                    null,\r
607                                                    options, "OK");\r
608 \r
609       jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();\r
610 \r
611       if (reply == JOptionPane.OK_OPTION\r
612           && name.getSelectedItem() != null\r
613           && source.getSelectedItem() != null)\r
614       {\r
615         //This ensures that the last sequence\r
616         //is refreshed and new features are rendered\r
617         lastSeq=null;\r
618         lastFeatureAdded = name.getSelectedItem().toString();\r
619         lastFeatureGroupAdded = source.getSelectedItem().toString();\r
620         lastDescriptionAdded = description.getText().replaceAll("\n", " ");\r
621       }\r
622 \r
623       if(!newFeatures)\r
624       {\r
625         SequenceFeature sf = features[featureIndex];\r
626 \r
627         if(reply==JOptionPane.NO_OPTION)\r
628           sequences[0].getDatasetSequence().deleteFeature(sf);\r
629         else if(reply==JOptionPane.YES_OPTION)\r
630         {\r
631           sf.type = lastFeatureAdded;\r
632           sf.featureGroup = lastFeatureGroupAdded;\r
633           sf.description = lastDescriptionAdded;\r
634           setColour(sf.type, colour.getBackground());\r
635           try{\r
636             sf.begin = ((Integer)start.getValue()).intValue();\r
637             sf.end = ((Integer)end.getValue()).intValue();\r
638           }catch(NumberFormatException ex)\r
639           {}\r
640 \r
641           ffile.parseDescriptionHTML(sf, false);\r
642         }\r
643       }\r
644       else\r
645       {\r
646         if (reply == JOptionPane.OK_OPTION\r
647             && name.getSelectedItem() != null\r
648             && source.getSelectedItem() != null)\r
649         {\r
650           for (int i = 0; i < sequences.length; i++)\r
651           {\r
652             features[i].type = lastFeatureAdded;\r
653             features[i].featureGroup = lastFeatureGroupAdded;\r
654             features[i].description = lastDescriptionAdded;\r
655             sequences[i].addSequenceFeature(features[i]);\r
656             ffile.parseDescriptionHTML(features[i], false);\r
657           }\r
658 \r
659           if (av.featuresDisplayed == null)\r
660             av.featuresDisplayed = new Hashtable();\r
661 \r
662           if (featureGroups == null)\r
663             featureGroups = new Hashtable();\r
664 \r
665           featureGroups.put(lastFeatureGroupAdded, new Boolean(true));\r
666 \r
667           Color col = colour.getBackground();\r
668           setColour(lastFeatureAdded, colour.getBackground());\r
669 \r
670           av.featuresDisplayed.put(lastFeatureGroupAdded,\r
671                                    new Integer(col.getRGB()));\r
672 \r
673           findAllFeatures();\r
674 \r
675           return true;\r
676         }\r
677         else\r
678           return false;\r
679       }\r
680 \r
681       if(name.getSelectedIndex()==-1)\r
682         findAllFeatures();\r
683 \r
684 \r
685       return true;\r
686     }\r
687 \r
688     public void setColour(String featureType, Color col)\r
689     {\r
690       featureColours.put(featureType, col);\r
691     }\r
692 \r
693     public void setTransparency(float value)\r
694     {\r
695       transparency = value;\r
696     }\r
697 \r
698     public float getTransparency()\r
699     {\r
700       return transparency;\r
701     }\r
702 \r
703     public void setFeaturePriority(Object [][] data)\r
704     {\r
705       // The feature table will display high priority\r
706       // features at the top, but theses are the ones\r
707       // we need to render last, so invert the data\r
708       if(av.featuresDisplayed!=null)\r
709         av.featuresDisplayed.clear();\r
710       else\r
711         av.featuresDisplayed = new Hashtable();\r
712 \r
713       renderOrder = new String[data.length];\r
714 \r
715       if (data.length > 0)\r
716         for (int i = 0; i < data.length; i++)\r
717         {\r
718           String type = data[i][0].toString();\r
719           setColour(type, (Color) data[i][1]);\r
720           if ( ( (Boolean) data[i][2]).booleanValue())\r
721           {\r
722             av.featuresDisplayed.put(type, new Integer(getColour(type).getRGB()));\r
723           }\r
724 \r
725           renderOrder[data.length - i - 1] = type;\r
726         }\r
727 \r
728     }\r
729 \r
730 \r
731 \r
732 \r
733 }\r