Correct colour for text when colour set
[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           final Color newColour = colorChooser.getColor();
254           for (int i = 0; i < selectedButtons.size(); i++)
255       {
256         button = (JButton) selectedButtons.elementAt(i);
257         button.setBackground(newColour);
258         button.setForeground(brighterThan(newColour));
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(newColour);
266           button.setForeground(brighterThan(button.getBackground()));
267         }
268       }
269     }
270   }
271
272   /**
273    * DOCUMENT ME!
274    * 
275    * @param e
276    *          DOCUMENT ME!
277    */
278   public void colourButtonPressed(MouseEvent e)
279   {
280     if (selectedButtons == null)
281     {
282       selectedButtons = new Vector();
283     }
284
285     JButton pressed = (JButton) e.getSource();
286
287     if (e.isShiftDown())
288     {
289       JButton start, end = (JButton) e.getSource();
290       if (selectedButtons.size() > 0)
291       {
292         start = (JButton) selectedButtons
293                 .elementAt(selectedButtons.size() - 1);
294       }
295       else
296       {
297         start = (JButton) e.getSource();
298       }
299
300       int startIndex = 0, endIndex = 0;
301       for (int b = 0; b < buttonPanel.getComponentCount(); b++)
302       {
303         if (buttonPanel.getComponent(b) == start)
304         {
305           startIndex = b;
306         }
307         if (buttonPanel.getComponent(b) == end)
308         {
309           endIndex = b;
310         }
311       }
312
313       if (startIndex > endIndex)
314       {
315         int temp = startIndex;
316         startIndex = endIndex;
317         endIndex = temp;
318       }
319
320       for (int b = startIndex; b <= endIndex; b++)
321       {
322         JButton button = (JButton) buttonPanel.getComponent(b);
323         if (!selectedButtons.contains(button))
324         {
325           button.setForeground(brighterThan(button.getBackground()));
326           selectedButtons.add(button);
327         }
328       }
329     }
330     else if (!e.isControlDown())
331     {
332       for (int b = 0; b < selectedButtons.size(); b++)
333       {
334         JButton button = (JButton) selectedButtons.elementAt(b);
335         button.setForeground(darkerThan(button.getBackground()));
336       }
337       selectedButtons.clear();
338       pressed.setForeground(brighterThan(pressed.getBackground()));
339       selectedButtons.addElement(pressed);
340
341     }
342     else if (e.isControlDown())
343     {
344       if (selectedButtons.contains(pressed))
345       {
346         pressed.setForeground(darkerThan(pressed.getBackground()));
347         selectedButtons.remove(pressed);
348       }
349       else
350       {
351         pressed.setForeground(brighterThan(pressed.getBackground()));
352         selectedButtons.addElement(pressed);
353       }
354     }
355
356     if (selectedButtons.size() > 0)
357     {
358       colorChooser.setColor(((JButton) selectedButtons.elementAt(0))
359               .getBackground());
360     }
361   }
362
363   /**
364    * DOCUMENT ME!
365    * 
366    * @param label
367    *          DOCUMENT ME!
368    * @param aa
369    *          DOCUMENT ME!
370    */
371   JButton makeButton(String label, String aa, Vector caseSensitiveButtons,
372           int buttonIndex)
373   {
374     final JButton button;
375     Color col;
376
377     if (buttonIndex < caseSensitiveButtons.size())
378     {
379       button = (JButton) caseSensitiveButtons.elementAt(buttonIndex);
380       col = button.getBackground();
381     }
382     else
383     {
384       button = new JButton();
385       button.addMouseListener(new java.awt.event.MouseAdapter()
386       {
387         public void mouseClicked(MouseEvent e)
388         {
389           colourButtonPressed(e);
390         }
391       });
392
393       caseSensitiveButtons.addElement(button);
394
395       col = Color.white;
396       if (oldColourScheme != null)
397       {
398         try
399         {
400           col = oldColourScheme.findColour(aa.charAt(0), -1, null);
401         } catch (Exception ex)
402         {
403         }
404       }
405     }
406
407     if (caseSensitive.isSelected())
408     {
409       button.setMargin(new java.awt.Insets(2, 2, 2, 2));
410     }
411     else
412     {
413       button.setMargin(new java.awt.Insets(2, 14, 2, 14));
414     }
415
416     button.setOpaque(true);     // required for the next line to have effect
417     button.setBackground(col);
418     button.setText(label);
419     button.setForeground(darkerThan(col));
420     button.setFont(new java.awt.Font("Verdana", Font.BOLD, 10));
421
422     return button;
423   }
424
425   /**
426    * Returns a colour three shades darker. 
427    * 
428    * We use darker text to indicate unselected buttons, lighter text for selected.
429    * @param col
430    * @return
431    */
432   public static Color darkerThan(Color col) {
433           return col.darker().darker().darker();
434   }
435
436   /**
437    * Returns a colour three shades brighter. 
438    * 
439    * We use darker text to indicate unselected buttons, lighter text for selected.
440    * @param col
441    * @return
442    */
443   public static Color brighterThan(Color col) {
444           return col.brighter().brighter().brighter();
445   }
446
447   /**
448    * DOCUMENT ME!
449    * 
450    * @param e
451    *          DOCUMENT ME!
452    */
453   protected void okButton_actionPerformed(ActionEvent e)
454   {
455     applyButton_actionPerformed(null);
456
457     try
458     {
459       frame.setClosed(true);
460     } catch (Exception ex)
461     {
462     }
463   }
464
465   /**
466    * DOCUMENT ME!
467    * 
468    * @param e
469    *          DOCUMENT ME!
470    */
471   protected void applyButton_actionPerformed(ActionEvent e)
472   {
473     UserColourScheme ucs = getSchemeFromButtons();
474     ucs.setName(schemeName.getText());
475
476     if (seqGroup != null)
477     {
478       seqGroup.cs = ucs;
479       ap.paintAlignment(true);
480     }
481     else if (ap != null)
482     {
483       ap.alignFrame.changeColour(ucs);
484     }
485     else if (jmol != null)
486     {
487       jmol.setJalviewColourScheme(ucs);
488     }
489   }
490
491   UserColourScheme getSchemeFromButtons()
492   {
493
494     Color[] newColours = new Color[24];
495
496     for (int i = 0; i < 24; i++)
497     {
498       JButton button = (JButton) upperCaseButtons.elementAt(i);
499       newColours[i] = button.getBackground();
500     }
501
502     UserColourScheme ucs = new UserColourScheme(newColours);
503
504     if (caseSensitive.isSelected())
505     {
506       newColours = new Color[23];
507       for (int i = 0; i < 23; i++)
508       {
509         JButton button = (JButton) lowerCaseButtons.elementAt(i);
510         newColours[i] = button.getBackground();
511       }
512       ucs.setLowerCaseColours(newColours);
513     }
514
515     if (ap != null)
516     {
517       ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
518     }
519
520     return ucs;
521   }
522
523   /**
524    * DOCUMENT ME!
525    * 
526    * @param e
527    *          DOCUMENT ME!
528    */
529   protected void loadbutton_actionPerformed(ActionEvent e)
530   {
531     upperCaseButtons = new Vector();
532     lowerCaseButtons = new Vector();
533
534     JalviewFileChooser chooser = new JalviewFileChooser(
535             jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
536             { "jc" }, new String[]
537             { "Jalview User Colours" }, "Jalview User Colours");
538     chooser.setFileView(new jalview.io.JalviewFileView());
539     chooser.setDialogTitle(MessageManager
540             .getString("label.load_colour_scheme"));
541     chooser.setToolTipText(MessageManager.getString("action.load"));
542
543     int value = chooser.showOpenDialog(this);
544
545     if (value == JalviewFileChooser.APPROVE_OPTION)
546     {
547       File choice = chooser.getSelectedFile();
548       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
549       String defaultColours = jalview.bin.Cache.getDefault(
550               "USER_DEFINED_COLOURS", choice.getPath());
551       if (defaultColours.indexOf(choice.getPath()) == -1)
552       {
553         defaultColours = defaultColours.concat("|")
554                 .concat(choice.getPath());
555       }
556
557       jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
558
559       UserColourScheme ucs = loadColours(choice.getAbsolutePath());
560       Color[] colors = ucs.getColours();
561       schemeName.setText(ucs.getName());
562
563       if (ucs.getLowerCaseColours() != null)
564       {
565         caseSensitive.setSelected(true);
566         lcaseColour.setEnabled(true);
567         resetButtonPanel(true);
568         for (int i = 0; i < lowerCaseButtons.size(); i++)
569         {
570           JButton button = (JButton) lowerCaseButtons.elementAt(i);
571           button.setBackground(ucs.getLowerCaseColours()[i]);
572         }
573
574       }
575       else
576       {
577         caseSensitive.setSelected(false);
578         lcaseColour.setEnabled(false);
579         resetButtonPanel(false);
580       }
581
582       for (int i = 0; i < upperCaseButtons.size(); i++)
583       {
584         JButton button = (JButton) upperCaseButtons.elementAt(i);
585         button.setBackground(colors[i]);
586       }
587
588     }
589   }
590
591   /**
592    * DOCUMENT ME!
593    * 
594    * @return DOCUMENT ME!
595    */
596   public static UserColourScheme loadDefaultColours()
597   {
598     UserColourScheme ret = null;
599
600     String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");
601     if (colours != null)
602     {
603       if (colours.indexOf("|") > -1)
604       {
605         colours = colours.substring(0, colours.indexOf("|"));
606       }
607
608       ret = loadColours(colours);
609     }
610
611     if (ret == null)
612     {
613       Color[] newColours = new Color[24];
614       for (int i = 0; i < 24; i++)
615       {
616         newColours[i] = Color.white;
617       }
618       ret = new UserColourScheme(newColours);
619     }
620
621     return ret;
622   }
623
624   /**
625    * DOCUMENT ME!
626    * 
627    * @param file
628    *          DOCUMENT ME!
629    * 
630    * @return DOCUMENT ME!
631    */
632   static UserColourScheme loadColours(String file)
633   {
634     UserColourScheme ucs = null;
635     Color[] newColours = null;
636     try
637     {
638       InputStreamReader in = new InputStreamReader(
639               new FileInputStream(file), "UTF-8");
640
641       jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
642
643       org.exolab.castor.xml.Unmarshaller unmar = new org.exolab.castor.xml.Unmarshaller(
644               jucs);
645       jucs = (jalview.schemabinding.version2.JalviewUserColours) unmar
646               .unmarshal(in);
647
648       newColours = new Color[24];
649
650       Color[] lowerCase = null;
651       boolean caseSensitive = false;
652
653       String name;
654       int index;
655       for (int i = 0; i < jucs.getColourCount(); i++)
656       {
657         name = jucs.getColour(i).getName();
658         if (ResidueProperties.aa3Hash.containsKey(name))
659         {
660           index = ((Integer) ResidueProperties.aa3Hash.get(name))
661                   .intValue();
662         }
663         else
664         {
665           index = ResidueProperties.aaIndex[name.charAt(0)];
666         }
667         if (index == -1)
668         {
669           continue;
670         }
671
672         if (name.toLowerCase().equals(name))
673         {
674           if (lowerCase == null)
675           {
676             lowerCase = new Color[23];
677           }
678           caseSensitive = true;
679           lowerCase[index] = new Color(Integer.parseInt(jucs.getColour(i)
680                   .getRGB(), 16));
681         }
682         else
683         {
684           newColours[index] = new Color(Integer.parseInt(jucs.getColour(i)
685                   .getRGB(), 16));
686         }
687       }
688
689       if (newColours != null)
690       {
691         ucs = new UserColourScheme(newColours);
692         ucs.setName(jucs.getSchemeName());
693         if (caseSensitive)
694         {
695           ucs.setLowerCaseColours(lowerCase);
696         }
697       }
698
699     } catch (Exception ex)
700     {
701       // Could be Archive Jalview format
702       try
703       {
704         InputStreamReader in = new InputStreamReader(new FileInputStream(
705                 file), "UTF-8");
706
707         jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
708
709         jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
710
711         newColours = new Color[jucs.getColourCount()];
712
713         for (int i = 0; i < 24; i++)
714         {
715           newColours[i] = new Color(Integer.parseInt(jucs.getColour(i)
716                   .getRGB(), 16));
717         }
718         if (newColours != null)
719         {
720           ucs = new UserColourScheme(newColours);
721           ucs.setName(jucs.getSchemeName());
722         }
723       } catch (Exception ex2)
724       {
725         ex2.printStackTrace();
726       }
727
728       if (newColours == null)
729       {
730         System.out.println("Error loading User ColourFile\n" + ex);
731       }
732     }
733
734     return ucs;
735   }
736
737   /**
738    * DOCUMENT ME!
739    * 
740    * @param e
741    *          DOCUMENT ME!
742    */
743   protected void savebutton_actionPerformed(ActionEvent e)
744   {
745     if (schemeName.getText().trim().length() < 1)
746     {
747       JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
748               .getString("label.user_colour_scheme_must_have_name"),
749               MessageManager.getString("label.no_name_colour_scheme"),
750               JOptionPane.WARNING_MESSAGE);
751       return;
752     }
753
754     if (userColourSchemes != null
755             && userColourSchemes.containsKey(schemeName.getText()))
756     {
757       int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
758               MessageManager.formatMessage(
759                       "label.colour_scheme_exists_overwrite", new String[]
760                       { schemeName.getText(), schemeName.getText() }),
761               MessageManager.getString("label.duplicate_scheme_name"),
762               JOptionPane.YES_NO_OPTION);
763       if (reply != JOptionPane.YES_OPTION)
764       {
765         return;
766       }
767
768       userColourSchemes.remove(schemeName.getText());
769     }
770     JalviewFileChooser chooser = new JalviewFileChooser(
771             jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
772             { "jc" }, new String[]
773             { "Jalview User Colours" }, "Jalview User Colours");
774
775     chooser.setFileView(new jalview.io.JalviewFileView());
776     chooser.setDialogTitle("Save colour scheme");
777     chooser.setToolTipText(MessageManager.getString("action.save"));
778
779     int value = chooser.showSaveDialog(this);
780
781     if (value == JalviewFileChooser.APPROVE_OPTION)
782     {
783       String choice = chooser.getSelectedFile().getPath();
784       String defaultColours = jalview.bin.Cache.getDefault(
785               "USER_DEFINED_COLOURS", choice);
786       if (defaultColours.indexOf(choice) == -1)
787       {
788         if (defaultColours.length() > 0)
789         {
790           defaultColours = defaultColours.concat("|");
791         }
792         defaultColours = defaultColours.concat(choice);
793       }
794
795       userColourSchemes.put(schemeName.getText(), getSchemeFromButtons());
796
797       ap.alignFrame.updateUserColourMenu();
798
799       jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
800
801       jalview.schemabinding.version2.JalviewUserColours ucs = new jalview.schemabinding.version2.JalviewUserColours();
802
803       ucs.setSchemeName(schemeName.getText());
804       try
805       {
806         PrintWriter out = new PrintWriter(new OutputStreamWriter(
807                 new FileOutputStream(choice), "UTF-8"));
808
809         for (int i = 0; i < buttonPanel.getComponentCount(); i++)
810         {
811           JButton button = (JButton) buttonPanel.getComponent(i);
812           jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
813           col.setName(button.getText());
814           col.setRGB(jalview.util.Format.getHexString(button
815                   .getBackground()));
816           ucs.addColour(col);
817         }
818
819         ucs.marshal(out);
820         out.close();
821       } catch (Exception ex)
822       {
823         ex.printStackTrace();
824       }
825     }
826   }
827
828   /**
829    * DOCUMENT ME!
830    * 
831    * @param e
832    *          DOCUMENT ME!
833    */
834   protected void cancelButton_actionPerformed(ActionEvent e)
835   {
836     if (ap != null)
837     {
838       if (seqGroup != null)
839       {
840         seqGroup.cs = oldColourScheme;
841       }
842       else if (ap != null)
843       {
844         ap.av.setGlobalColourScheme(oldColourScheme);
845       }
846       ap.paintAlignment(true);
847     }
848
849     if (jmol != null)
850     {
851       jmol.setJalviewColourScheme(oldColourScheme);
852     }
853
854     try
855     {
856       frame.setClosed(true);
857     } catch (Exception ex)
858     {
859     }
860   }
861
862   static Hashtable userColourSchemes;
863
864   public static Hashtable getUserColourSchemes()
865   {
866     return userColourSchemes;
867   }
868
869   public static void initUserColourSchemes(String files)
870   {
871     userColourSchemes = new Hashtable();
872
873     if (files == null || files.length() == 0)
874     {
875       return;
876     }
877
878     // In case colours can't be loaded, we'll remove them
879     // from the default list here.
880     StringBuffer coloursFound = new StringBuffer();
881     StringTokenizer st = new StringTokenizer(files, "|");
882     while (st.hasMoreElements())
883     {
884       String file = st.nextToken();
885       try
886       {
887         UserColourScheme ucs = loadColours(file);
888         if (ucs != null)
889         {
890           if (coloursFound.length() > 0)
891           {
892             coloursFound.append("|");
893           }
894           coloursFound.append(file);
895           userColourSchemes.put(ucs.getName(), ucs);
896         }
897       } catch (Exception ex)
898       {
899         System.out.println("Error loading User ColourFile\n" + ex);
900       }
901     }
902     if (!files.equals(coloursFound.toString()))
903     {
904       if (coloursFound.toString().length() > 1)
905       {
906         jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",
907                 coloursFound.toString());
908       }
909       else
910       {
911         jalview.bin.Cache.applicationProperties
912                 .remove("USER_DEFINED_COLOURS");
913       }
914     }
915   }
916
917   public static void removeColourFromDefaults(String target)
918   {
919     // The only way to find colours by name is to load them in
920     // In case colours can't be loaded, we'll remove them
921     // from the default list here.
922
923     userColourSchemes = new Hashtable();
924
925     StringBuffer coloursFound = new StringBuffer();
926     StringTokenizer st = new StringTokenizer(
927             jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");
928
929     while (st.hasMoreElements())
930     {
931       String file = st.nextToken();
932       try
933       {
934         UserColourScheme ucs = loadColours(file);
935         if (ucs != null && !ucs.getName().equals(target))
936         {
937           if (coloursFound.length() > 0)
938           {
939             coloursFound.append("|");
940           }
941           coloursFound.append(file);
942           userColourSchemes.put(ucs.getName(), ucs);
943         }
944       } catch (Exception ex)
945       {
946         System.out.println("Error loading User ColourFile\n" + ex);
947       }
948     }
949
950     if (coloursFound.toString().length() > 1)
951     {
952       jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",
953               coloursFound.toString());
954     }
955     else
956     {
957       jalview.bin.Cache.applicationProperties
958               .remove("USER_DEFINED_COLOURS");
959     }
960
961   }
962
963   public void caseSensitive_actionPerformed(ActionEvent e)
964   {
965     resetButtonPanel(caseSensitive.isSelected());
966     lcaseColour.setEnabled(caseSensitive.isSelected());
967   }
968
969   public void lcaseColour_actionPerformed(ActionEvent e)
970   {
971     if (selectedButtons == null)
972     {
973       selectedButtons = new Vector();
974     }
975     else
976     {
977       selectedButtons.clear();
978     }
979     selectedButtons.add(lcaseColour);
980   }
981
982 }