JAL-1360 workaround for user defined colours display on Java 7
[jalview.git] / src / jalview / gui / UserDefinedColours.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 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.api.structures.JalviewStructureDisplayI;
24 import jalview.datamodel.SequenceGroup;
25 import jalview.io.JalviewFileChooser;
26 import jalview.jbgui.GUserDefinedColours;
27 import jalview.schemes.ColourSchemeI;
28 import jalview.schemes.ResidueProperties;
29 import jalview.schemes.UserColourScheme;
30 import jalview.util.MessageManager;
31
32 import java.awt.Color;
33 import java.awt.Font;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.MouseEvent;
36 import java.io.File;
37 import java.io.FileInputStream;
38 import java.io.FileOutputStream;
39 import java.io.InputStreamReader;
40 import java.io.OutputStreamWriter;
41 import java.io.PrintWriter;
42 import java.util.Hashtable;
43 import java.util.StringTokenizer;
44 import java.util.Vector;
45
46 import javax.swing.JButton;
47 import javax.swing.JInternalFrame;
48 import javax.swing.JOptionPane;
49 import javax.swing.event.ChangeEvent;
50 import javax.swing.event.ChangeListener;
51
52 /**
53  * DOCUMENT ME!
54  * 
55  * @author $author$
56  * @version $Revision$
57  */
58 public class UserDefinedColours extends GUserDefinedColours implements
59         ChangeListener
60 {
61   private static final int MY_FRAME_HEIGHT = 420;
62   private static final int MY_FRAME_WIDTH = 810;
63   private static final int MY_FRAME_WIDTH_CASE_SENSITIVE = 970;
64
65 AlignmentPanel ap;
66
67   SequenceGroup seqGroup;
68
69   Vector selectedButtons;
70
71   ColourSchemeI oldColourScheme;
72
73   JInternalFrame frame;
74
75   JalviewStructureDisplayI jmol;
76
77   Vector upperCaseButtons;
78
79   Vector lowerCaseButtons;
80
81   /**
82    * Creates a new UserDefinedColours object.
83    * 
84    * @param ap
85    *          DOCUMENT ME!
86    * @param sg
87    *          DOCUMENT ME!
88    */
89   public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)
90   {
91     super();
92
93     lcaseColour.setEnabled(false);
94
95     this.ap = ap;
96     seqGroup = sg;
97
98     if (seqGroup != null)
99     {
100       oldColourScheme = seqGroup.cs;
101     }
102     else
103     {
104       oldColourScheme = ap.av.getGlobalColourScheme();
105     }
106
107     if (oldColourScheme instanceof UserColourScheme)
108     {
109       schemeName.setText(((UserColourScheme) oldColourScheme).getName());
110       if (((UserColourScheme) oldColourScheme).getLowerCaseColours() != null)
111       {
112         caseSensitive.setSelected(true);
113         lcaseColour.setEnabled(true);
114         resetButtonPanel(true);
115       }
116       else
117       {
118         resetButtonPanel(false);
119       }
120     }
121     else
122     {
123       resetButtonPanel(false);
124     }
125
126     showFrame();
127   }
128
129   public UserDefinedColours(JalviewStructureDisplayI jmol, ColourSchemeI oldcs)
130   {
131     super();
132     this.jmol = jmol;
133
134     colorChooser.getSelectionModel().addChangeListener(this);
135
136     oldColourScheme = oldcs;
137
138     if (oldColourScheme instanceof UserColourScheme)
139     {
140       schemeName.setText(((UserColourScheme) oldColourScheme).getName());
141     }
142
143     resetButtonPanel(false);
144
145     showFrame();
146
147   }
148
149   void showFrame()
150   {
151     colorChooser.getSelectionModel().addChangeListener(this);
152     frame = new JInternalFrame();
153     frame.setContentPane(this);
154                 Desktop.addInternalFrame(frame,
155                                 MessageManager.getString("label.user_defined_colours"), MY_FRAME_WIDTH,
156                                 MY_FRAME_HEIGHT, true);
157
158     if (seqGroup != null)
159     {
160       frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");
161     }
162   }
163
164   void resetButtonPanel(boolean caseSensitive)
165   {
166     buttonPanel.removeAll();
167
168     if (upperCaseButtons == null)
169     {
170       upperCaseButtons = new Vector();
171     }
172
173     JButton button;
174     String label;
175     for (int i = 0; i < 20; i++)
176     {
177       if (caseSensitive)
178       {
179         label = ResidueProperties.aa[i];
180       }
181       else
182       {
183         label = ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i])
184                 .toString();
185       }
186
187       button = makeButton(label, ResidueProperties.aa[i], upperCaseButtons,
188               i);
189
190       buttonPanel.add(button);
191     }
192
193     buttonPanel.add(makeButton("B", "B", upperCaseButtons, 20));
194     buttonPanel.add(makeButton("Z", "Z", upperCaseButtons, 21));
195     buttonPanel.add(makeButton("X", "X", upperCaseButtons, 22));
196     buttonPanel.add(makeButton("Gap", "-", upperCaseButtons, 23));
197
198     if (!caseSensitive)
199     {
200       gridLayout.setRows(6);
201       gridLayout.setColumns(4);
202     }
203     else
204     {
205       gridLayout.setRows(7);
206       int cols = 7;
207       gridLayout.setColumns(cols + 1);
208
209       if (lowerCaseButtons == null)
210       {
211         lowerCaseButtons = new Vector();
212       }
213
214       for (int i = 0; i < 20; i++)
215       {
216         int row = i / cols + 1;
217         int index = (row * cols) + i;
218         button = makeButton(ResidueProperties.aa[i].toLowerCase(),
219                 ResidueProperties.aa[i].toLowerCase(), lowerCaseButtons, i);
220
221         buttonPanel.add(button, index);
222       }
223     }
224
225     if (caseSensitive)
226     {
227       buttonPanel.add(makeButton("b", "b", lowerCaseButtons, 20));
228       buttonPanel.add(makeButton("z", "z", lowerCaseButtons, 21));
229       buttonPanel.add(makeButton("x", "x", lowerCaseButtons, 22));
230     }
231
232     // JAL-1360 widen the frame dynamically to accommodate case-sensitive AA codes
233     if (this.frame != null) {
234         int newWidth = caseSensitive ? MY_FRAME_WIDTH_CASE_SENSITIVE : MY_FRAME_WIDTH;
235         this.frame.setSize(newWidth, this.frame.getHeight());
236     }
237     
238     buttonPanel.validate();
239     validate();
240   }
241
242   /**
243    * DOCUMENT ME!
244    * 
245    * @param evt
246    *          DOCUMENT ME!
247    */
248   public void stateChanged(ChangeEvent evt)
249   {
250     if (selectedButtons != null)
251     {
252       JButton button = null;
253       for (int i = 0; i < selectedButtons.size(); i++)
254       {
255         button = (JButton) selectedButtons.elementAt(i);
256         button.setBackground(colorChooser.getColor());
257         button.setForeground(button.getBackground().brighter().brighter()
258                 .brighter());
259       }
260       if (button == lcaseColour)
261       {
262         for (int i = 0; i < lowerCaseButtons.size(); i++)
263         {
264           button = (JButton) lowerCaseButtons.elementAt(i);
265           button.setBackground(colorChooser.getColor());
266           button.setForeground(button.getBackground().brighter().brighter()
267                   .brighter());
268         }
269       }
270     }
271   }
272
273   /**
274    * DOCUMENT ME!
275    * 
276    * @param e
277    *          DOCUMENT ME!
278    */
279   public void colourButtonPressed(MouseEvent e)
280   {
281     if (selectedButtons == null)
282     {
283       selectedButtons = new Vector();
284     }
285
286     JButton pressed = (JButton) e.getSource();
287
288     if (e.isShiftDown())
289     {
290       JButton start, end = (JButton) e.getSource();
291       if (selectedButtons.size() > 0)
292       {
293         start = (JButton) selectedButtons
294                 .elementAt(selectedButtons.size() - 1);
295       }
296       else
297       {
298         start = (JButton) e.getSource();
299       }
300
301       int startIndex = 0, endIndex = 0;
302       for (int b = 0; b < buttonPanel.getComponentCount(); b++)
303       {
304         if (buttonPanel.getComponent(b) == start)
305         {
306           startIndex = b;
307         }
308         if (buttonPanel.getComponent(b) == end)
309         {
310           endIndex = b;
311         }
312       }
313
314       if (startIndex > endIndex)
315       {
316         int temp = startIndex;
317         startIndex = endIndex;
318         endIndex = temp;
319       }
320
321       for (int b = startIndex; b <= endIndex; b++)
322       {
323         JButton button = (JButton) buttonPanel.getComponent(b);
324         if (!selectedButtons.contains(button))
325         {
326           button.setForeground(button.getBackground().brighter().brighter());
327           selectedButtons.add(button);
328         }
329       }
330     }
331     else if (!e.isControlDown())
332     {
333       for (int b = 0; b < selectedButtons.size(); b++)
334       {
335         JButton button = (JButton) selectedButtons.elementAt(b);
336         button.setForeground(button.getBackground().darker().darker());
337       }
338       selectedButtons.clear();
339       pressed.setForeground(pressed.getBackground().brighter().brighter());
340       selectedButtons.addElement(pressed);
341
342     }
343     else if (e.isControlDown())
344     {
345       if (selectedButtons.contains(pressed))
346       {
347         pressed.setForeground(pressed.getBackground().darker().darker());
348         selectedButtons.remove(pressed);
349       }
350       else
351       {
352         pressed.setForeground(pressed.getBackground().brighter().brighter());
353         selectedButtons.addElement(pressed);
354       }
355     }
356
357     if (selectedButtons.size() > 0)
358     {
359       colorChooser.setColor(((JButton) selectedButtons.elementAt(0))
360               .getBackground());
361     }
362   }
363
364   /**
365    * DOCUMENT ME!
366    * 
367    * @param label
368    *          DOCUMENT ME!
369    * @param aa
370    *          DOCUMENT ME!
371    */
372   JButton makeButton(String label, String aa, Vector caseSensitiveButtons,
373           int buttonIndex)
374   {
375     final JButton button;
376     Color col;
377
378     if (buttonIndex < caseSensitiveButtons.size())
379     {
380       button = (JButton) caseSensitiveButtons.elementAt(buttonIndex);
381       col = button.getBackground();
382     }
383     else
384     {
385       button = new JButton();
386       button.addMouseListener(new java.awt.event.MouseAdapter()
387       {
388         public void mouseClicked(MouseEvent e)
389         {
390           colourButtonPressed(e);
391         }
392       });
393
394       caseSensitiveButtons.addElement(button);
395
396       col = Color.white;
397       if (oldColourScheme != null)
398       {
399         try
400         {
401           col = oldColourScheme.findColour(aa.charAt(0), -1, null);
402         } catch (Exception ex)
403         {
404         }
405       }
406     }
407
408     if (caseSensitive.isSelected())
409     {
410       button.setMargin(new java.awt.Insets(2, 2, 2, 2));
411     }
412     else
413     {
414       button.setMargin(new java.awt.Insets(2, 14, 2, 14));
415     }
416
417     button.setOpaque(true);     // required for the next line to have effect
418     button.setBackground(col);
419     button.setText(label);
420     button.setForeground(col.darker().darker().darker());
421     button.setFont(new java.awt.Font("Verdana", Font.BOLD, 10));
422
423     return button;
424   }
425
426   /**
427    * DOCUMENT ME!
428    * 
429    * @param e
430    *          DOCUMENT ME!
431    */
432   protected void okButton_actionPerformed(ActionEvent e)
433   {
434     applyButton_actionPerformed(null);
435
436     try
437     {
438       frame.setClosed(true);
439     } catch (Exception ex)
440     {
441     }
442   }
443
444   /**
445    * DOCUMENT ME!
446    * 
447    * @param e
448    *          DOCUMENT ME!
449    */
450   protected void applyButton_actionPerformed(ActionEvent e)
451   {
452     UserColourScheme ucs = getSchemeFromButtons();
453     ucs.setName(schemeName.getText());
454
455     if (seqGroup != null)
456     {
457       seqGroup.cs = ucs;
458       ap.paintAlignment(true);
459     }
460     else if (ap != null)
461     {
462       ap.alignFrame.changeColour(ucs);
463     }
464     else if (jmol != null)
465     {
466       jmol.setJalviewColourScheme(ucs);
467     }
468   }
469
470   UserColourScheme getSchemeFromButtons()
471   {
472
473     Color[] newColours = new Color[24];
474
475     for (int i = 0; i < 24; i++)
476     {
477       JButton button = (JButton) upperCaseButtons.elementAt(i);
478       newColours[i] = button.getBackground();
479     }
480
481     UserColourScheme ucs = new UserColourScheme(newColours);
482
483     if (caseSensitive.isSelected())
484     {
485       newColours = new Color[23];
486       for (int i = 0; i < 23; i++)
487       {
488         JButton button = (JButton) lowerCaseButtons.elementAt(i);
489         newColours[i] = button.getBackground();
490       }
491       ucs.setLowerCaseColours(newColours);
492     }
493
494     if (ap != null)
495     {
496       ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
497     }
498
499     return ucs;
500   }
501
502   /**
503    * DOCUMENT ME!
504    * 
505    * @param e
506    *          DOCUMENT ME!
507    */
508   protected void loadbutton_actionPerformed(ActionEvent e)
509   {
510     upperCaseButtons = new Vector();
511     lowerCaseButtons = new Vector();
512
513     JalviewFileChooser chooser = new JalviewFileChooser(
514             jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
515             { "jc" }, new String[]
516             { "Jalview User Colours" }, "Jalview User Colours");
517     chooser.setFileView(new jalview.io.JalviewFileView());
518     chooser.setDialogTitle(MessageManager
519             .getString("label.load_colour_scheme"));
520     chooser.setToolTipText(MessageManager.getString("action.load"));
521
522     int value = chooser.showOpenDialog(this);
523
524     if (value == JalviewFileChooser.APPROVE_OPTION)
525     {
526       File choice = chooser.getSelectedFile();
527       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
528       String defaultColours = jalview.bin.Cache.getDefault(
529               "USER_DEFINED_COLOURS", choice.getPath());
530       if (defaultColours.indexOf(choice.getPath()) == -1)
531       {
532         defaultColours = defaultColours.concat("|")
533                 .concat(choice.getPath());
534       }
535
536       jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
537
538       UserColourScheme ucs = loadColours(choice.getAbsolutePath());
539       Color[] colors = ucs.getColours();
540       schemeName.setText(ucs.getName());
541
542       if (ucs.getLowerCaseColours() != null)
543       {
544         caseSensitive.setSelected(true);
545         lcaseColour.setEnabled(true);
546         resetButtonPanel(true);
547         for (int i = 0; i < lowerCaseButtons.size(); i++)
548         {
549           JButton button = (JButton) lowerCaseButtons.elementAt(i);
550           button.setBackground(ucs.getLowerCaseColours()[i]);
551         }
552
553       }
554       else
555       {
556         caseSensitive.setSelected(false);
557         lcaseColour.setEnabled(false);
558         resetButtonPanel(false);
559       }
560
561       for (int i = 0; i < upperCaseButtons.size(); i++)
562       {
563         JButton button = (JButton) upperCaseButtons.elementAt(i);
564         button.setBackground(colors[i]);
565       }
566
567     }
568   }
569
570   /**
571    * DOCUMENT ME!
572    * 
573    * @return DOCUMENT ME!
574    */
575   public static UserColourScheme loadDefaultColours()
576   {
577     UserColourScheme ret = null;
578
579     String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");
580     if (colours != null)
581     {
582       if (colours.indexOf("|") > -1)
583       {
584         colours = colours.substring(0, colours.indexOf("|"));
585       }
586
587       ret = loadColours(colours);
588     }
589
590     if (ret == null)
591     {
592       Color[] newColours = new Color[24];
593       for (int i = 0; i < 24; i++)
594       {
595         newColours[i] = Color.white;
596       }
597       ret = new UserColourScheme(newColours);
598     }
599
600     return ret;
601   }
602
603   /**
604    * DOCUMENT ME!
605    * 
606    * @param file
607    *          DOCUMENT ME!
608    * 
609    * @return DOCUMENT ME!
610    */
611   static UserColourScheme loadColours(String file)
612   {
613     UserColourScheme ucs = null;
614     Color[] newColours = null;
615     try
616     {
617       InputStreamReader in = new InputStreamReader(
618               new FileInputStream(file), "UTF-8");
619
620       jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
621
622       org.exolab.castor.xml.Unmarshaller unmar = new org.exolab.castor.xml.Unmarshaller(
623               jucs);
624       jucs = (jalview.schemabinding.version2.JalviewUserColours) unmar
625               .unmarshal(in);
626
627       newColours = new Color[24];
628
629       Color[] lowerCase = null;
630       boolean caseSensitive = false;
631
632       String name;
633       int index;
634       for (int i = 0; i < jucs.getColourCount(); i++)
635       {
636         name = jucs.getColour(i).getName();
637         if (ResidueProperties.aa3Hash.containsKey(name))
638         {
639           index = ((Integer) ResidueProperties.aa3Hash.get(name))
640                   .intValue();
641         }
642         else
643         {
644           index = ResidueProperties.aaIndex[name.charAt(0)];
645         }
646         if (index == -1)
647         {
648           continue;
649         }
650
651         if (name.toLowerCase().equals(name))
652         {
653           if (lowerCase == null)
654           {
655             lowerCase = new Color[23];
656           }
657           caseSensitive = true;
658           lowerCase[index] = new Color(Integer.parseInt(jucs.getColour(i)
659                   .getRGB(), 16));
660         }
661         else
662         {
663           newColours[index] = new Color(Integer.parseInt(jucs.getColour(i)
664                   .getRGB(), 16));
665         }
666       }
667
668       if (newColours != null)
669       {
670         ucs = new UserColourScheme(newColours);
671         ucs.setName(jucs.getSchemeName());
672         if (caseSensitive)
673         {
674           ucs.setLowerCaseColours(lowerCase);
675         }
676       }
677
678     } catch (Exception ex)
679     {
680       // Could be Archive Jalview format
681       try
682       {
683         InputStreamReader in = new InputStreamReader(new FileInputStream(
684                 file), "UTF-8");
685
686         jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
687
688         jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
689
690         newColours = new Color[jucs.getColourCount()];
691
692         for (int i = 0; i < 24; i++)
693         {
694           newColours[i] = new Color(Integer.parseInt(jucs.getColour(i)
695                   .getRGB(), 16));
696         }
697         if (newColours != null)
698         {
699           ucs = new UserColourScheme(newColours);
700           ucs.setName(jucs.getSchemeName());
701         }
702       } catch (Exception ex2)
703       {
704         ex2.printStackTrace();
705       }
706
707       if (newColours == null)
708       {
709         System.out.println("Error loading User ColourFile\n" + ex);
710       }
711     }
712
713     return ucs;
714   }
715
716   /**
717    * DOCUMENT ME!
718    * 
719    * @param e
720    *          DOCUMENT ME!
721    */
722   protected void savebutton_actionPerformed(ActionEvent e)
723   {
724     if (schemeName.getText().trim().length() < 1)
725     {
726       JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
727               .getString("label.user_colour_scheme_must_have_name"),
728               MessageManager.getString("label.no_name_colour_scheme"),
729               JOptionPane.WARNING_MESSAGE);
730       return;
731     }
732
733     if (userColourSchemes != null
734             && userColourSchemes.containsKey(schemeName.getText()))
735     {
736       int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
737               MessageManager.formatMessage(
738                       "label.colour_scheme_exists_overwrite", new String[]
739                       { schemeName.getText(), schemeName.getText() }),
740               MessageManager.getString("label.duplicate_scheme_name"),
741               JOptionPane.YES_NO_OPTION);
742       if (reply != JOptionPane.YES_OPTION)
743       {
744         return;
745       }
746
747       userColourSchemes.remove(schemeName.getText());
748     }
749     JalviewFileChooser chooser = new JalviewFileChooser(
750             jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
751             { "jc" }, new String[]
752             { "Jalview User Colours" }, "Jalview User Colours");
753
754     chooser.setFileView(new jalview.io.JalviewFileView());
755     chooser.setDialogTitle("Save colour scheme");
756     chooser.setToolTipText(MessageManager.getString("action.save"));
757
758     int value = chooser.showSaveDialog(this);
759
760     if (value == JalviewFileChooser.APPROVE_OPTION)
761     {
762       String choice = chooser.getSelectedFile().getPath();
763       String defaultColours = jalview.bin.Cache.getDefault(
764               "USER_DEFINED_COLOURS", choice);
765       if (defaultColours.indexOf(choice) == -1)
766       {
767         if (defaultColours.length() > 0)
768         {
769           defaultColours = defaultColours.concat("|");
770         }
771         defaultColours = defaultColours.concat(choice);
772       }
773
774       userColourSchemes.put(schemeName.getText(), getSchemeFromButtons());
775
776       ap.alignFrame.updateUserColourMenu();
777
778       jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
779
780       jalview.schemabinding.version2.JalviewUserColours ucs = new jalview.schemabinding.version2.JalviewUserColours();
781
782       ucs.setSchemeName(schemeName.getText());
783       try
784       {
785         PrintWriter out = new PrintWriter(new OutputStreamWriter(
786                 new FileOutputStream(choice), "UTF-8"));
787
788         for (int i = 0; i < buttonPanel.getComponentCount(); i++)
789         {
790           JButton button = (JButton) buttonPanel.getComponent(i);
791           jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
792           col.setName(button.getText());
793           col.setRGB(jalview.util.Format.getHexString(button
794                   .getBackground()));
795           ucs.addColour(col);
796         }
797
798         ucs.marshal(out);
799         out.close();
800       } catch (Exception ex)
801       {
802         ex.printStackTrace();
803       }
804     }
805   }
806
807   /**
808    * DOCUMENT ME!
809    * 
810    * @param e
811    *          DOCUMENT ME!
812    */
813   protected void cancelButton_actionPerformed(ActionEvent e)
814   {
815     if (ap != null)
816     {
817       if (seqGroup != null)
818       {
819         seqGroup.cs = oldColourScheme;
820       }
821       else if (ap != null)
822       {
823         ap.av.setGlobalColourScheme(oldColourScheme);
824       }
825       ap.paintAlignment(true);
826     }
827
828     if (jmol != null)
829     {
830       jmol.setJalviewColourScheme(oldColourScheme);
831     }
832
833     try
834     {
835       frame.setClosed(true);
836     } catch (Exception ex)
837     {
838     }
839   }
840
841   static Hashtable userColourSchemes;
842
843   public static Hashtable getUserColourSchemes()
844   {
845     return userColourSchemes;
846   }
847
848   public static void initUserColourSchemes(String files)
849   {
850     userColourSchemes = new Hashtable();
851
852     if (files == null || files.length() == 0)
853     {
854       return;
855     }
856
857     // In case colours can't be loaded, we'll remove them
858     // from the default list here.
859     StringBuffer coloursFound = new StringBuffer();
860     StringTokenizer st = new StringTokenizer(files, "|");
861     while (st.hasMoreElements())
862     {
863       String file = st.nextToken();
864       try
865       {
866         UserColourScheme ucs = loadColours(file);
867         if (ucs != null)
868         {
869           if (coloursFound.length() > 0)
870           {
871             coloursFound.append("|");
872           }
873           coloursFound.append(file);
874           userColourSchemes.put(ucs.getName(), ucs);
875         }
876       } catch (Exception ex)
877       {
878         System.out.println("Error loading User ColourFile\n" + ex);
879       }
880     }
881     if (!files.equals(coloursFound.toString()))
882     {
883       if (coloursFound.toString().length() > 1)
884       {
885         jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",
886                 coloursFound.toString());
887       }
888       else
889       {
890         jalview.bin.Cache.applicationProperties
891                 .remove("USER_DEFINED_COLOURS");
892       }
893     }
894   }
895
896   public static void removeColourFromDefaults(String target)
897   {
898     // The only way to find colours by name is to load them in
899     // In case colours can't be loaded, we'll remove them
900     // from the default list here.
901
902     userColourSchemes = new Hashtable();
903
904     StringBuffer coloursFound = new StringBuffer();
905     StringTokenizer st = new StringTokenizer(
906             jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");
907
908     while (st.hasMoreElements())
909     {
910       String file = st.nextToken();
911       try
912       {
913         UserColourScheme ucs = loadColours(file);
914         if (ucs != null && !ucs.getName().equals(target))
915         {
916           if (coloursFound.length() > 0)
917           {
918             coloursFound.append("|");
919           }
920           coloursFound.append(file);
921           userColourSchemes.put(ucs.getName(), ucs);
922         }
923       } catch (Exception ex)
924       {
925         System.out.println("Error loading User ColourFile\n" + ex);
926       }
927     }
928
929     if (coloursFound.toString().length() > 1)
930     {
931       jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",
932               coloursFound.toString());
933     }
934     else
935     {
936       jalview.bin.Cache.applicationProperties
937               .remove("USER_DEFINED_COLOURS");
938     }
939
940   }
941
942   public void caseSensitive_actionPerformed(ActionEvent e)
943   {
944     resetButtonPanel(caseSensitive.isSelected());
945     lcaseColour.setEnabled(caseSensitive.isSelected());
946   }
947
948   public void lcaseColour_actionPerformed(ActionEvent e)
949   {
950     if (selectedButtons == null)
951     {
952       selectedButtons = new Vector();
953     }
954     else
955     {
956       selectedButtons.clear();
957     }
958     selectedButtons.add(lcaseColour);
959   }
960
961 }