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