(JAL-985,JAL-986) preference widgets for settings
[jalview.git] / src / jalview / gui / Preferences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.gui;
19
20 import java.util.*;
21
22 import java.awt.*;
23 import java.awt.event.*;
24
25 import javax.swing.*;
26
27 import jalview.bin.*;
28 import jalview.io.*;
29 import jalview.jbgui.*;
30 import jalview.schemes.*;
31 import jalview.ws.EnfinEnvision2OneWay;
32
33 /**
34  * DOCUMENT ME!
35  * 
36  * @author $author$
37  * @version $Revision$
38  */
39 public class Preferences extends GPreferences
40 {
41
42   /**
43    * Holds name and link separated with | character. Sequence ID must be
44    * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
45    */
46   public static Vector sequenceURLLinks;
47
48   /**
49    * Holds name and link separated with | character. Sequence IDS and Sequences
50    * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and
51    * $SEQUENCES$ or $SEQUENCES=/.possible | chars ./=$ and separation character
52    * for first and second token specified after a pipe character at end |,|.
53    * (TODO: proper escape for using | to separate ids or sequences
54    */
55
56   public static Vector groupURLLinks;
57   static
58   {
59     String string = Cache
60             .getDefault(
61                     "SEQUENCE_LINKS",
62                     "SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
63     sequenceURLLinks = new Vector();
64
65     try
66     {
67       StringTokenizer st = new StringTokenizer(string, "|");
68       while (st.hasMoreElements())
69       {
70         String name = st.nextToken();
71         String url = st.nextToken();
72         // check for '|' within a regex
73         int rxstart = url.indexOf("$SEQUENCE_ID$");
74         while (rxstart == -1 && url.indexOf("/=$") == -1)
75         {
76           url = url + "|" + st.nextToken();
77         }
78         sequenceURLLinks.addElement(name + "|" + url);
79       }
80     } catch (Exception ex)
81     {
82       System.out.println(ex + "\nError parsing sequence links");
83     }
84     /**
85      * TODO: reformulate groupURL encoding so two or more can be stored in the
86      * .properties file as '|' separated strings
87      */
88
89     groupURLLinks = new Vector();
90     // groupURLLinks.addElement("UNIPROT|EnVision2|http://www.ebi.ac.uk/enfin-srv/envision2/pages/linkin.jsf?tool=Jalview&workflow=Default&datasetName=JalviewIDs$DATASETID$&input=$SEQUENCEIDS$&inputType=0|,");
91     // groupURLLinks.addElement("Seqs|EnVision2|http://www.ebi.ac.uk/enfin-srv/envision2/pages/linkin.jsf?tool=Jalview&workflow=Default&datasetName=JalviewSeqs$DATASETID$&input=$SEQUENCES=/([A-Za-z]+)+/=$&inputType=1|,");
92
93   }
94
95   Vector nameLinks, urlLinks;
96
97   JInternalFrame frame;
98
99   DasSourceBrowser dasSource;
100
101   private WsPreferences wsPrefs;
102
103   /**
104    * Creates a new Preferences object.
105    */
106   public Preferences()
107   {
108
109     frame = new JInternalFrame();
110     frame.setContentPane(this);
111     dasSource = new DasSourceBrowser();
112     dasPanel.add(dasSource, BorderLayout.CENTER);
113     wsPrefs = new WsPreferences();
114     wsPanel.add(wsPrefs, BorderLayout.CENTER);
115     int width = 500, height = 420;
116     if (new jalview.util.Platform().isAMac())
117     {
118       width = 570;
119       height = 460;
120     }
121
122     Desktop.addInternalFrame(frame, "Preferences", width, height);
123     frame.setMinimumSize(new Dimension(width, height));
124
125     seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
126     rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
127     fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
128     annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
129
130     conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
131     quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
132     identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
133     openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
134     showUnconserved
135             .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
136     showNpTooltip.setSelected(Cache
137             .getDefault("SHOW_NPFEATS_TOOLTIP", true));
138     showDbRefTooltip.setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP",
139             true));
140     sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
141     for (int i = ColourSchemeProperty.FIRST_COLOUR; i <= ColourSchemeProperty.LAST_COLOUR; i++)
142     {
143       colour.addItem(ColourSchemeProperty.getColourName(i));
144     }
145
146     String string = Cache.getDefault("DEFAULT_COLOUR", "None");
147
148     colour.setSelectedItem(string);
149
150     /**
151      * default min-max colours for annotation shading
152      */
153     minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
154     maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
155
156     String[] fonts = java.awt.GraphicsEnvironment
157             .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
158
159     for (int i = 0; i < fonts.length; i++)
160     {
161       fontNameCB.addItem(fonts[i]);
162     }
163
164     for (int i = 1; i < 31; i++)
165     {
166       fontSizeCB.addItem(i + "");
167     }
168
169     fontStyleCB.addItem("plain");
170     fontStyleCB.addItem("bold");
171     fontStyleCB.addItem("italic");
172
173     fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
174     fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
175     fontStyleCB.setSelectedItem(Cache.getDefault("FONT_STYLE", Font.PLAIN
176             + ""));
177
178     smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", false));
179
180     idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
181
182     wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
183
184     gapSymbolCB.addItem("-");
185     gapSymbolCB.addItem(".");
186
187     gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
188
189     startupCheckbox
190             .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
191     startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
192             Cache.getDefault("www.jalview.org","http://www.jalview.org")+"/examples/exampleFile_2_3.jar"));
193
194     sortby.addItem("No sort");
195     sortby.addItem("Id");
196     sortby.addItem("Pairwise Identity");
197     sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
198
199     epsRendering.addItem("Prompt each time");
200     epsRendering.addItem("Lineart");
201     epsRendering.addItem("Text");
202     epsRendering.setSelectedItem(Cache.getDefault("EPS_RENDERING",
203             "Prompt each time"));
204     autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
205     userIdWidth.setEnabled(!autoIdWidth.isSelected());
206     userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
207     Integer wi = Cache.getIntegerProperty("FIGURE_USERIDWIDTH");
208     userIdWidth.setText(wi == null ? "" : wi.toString());
209     blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
210     clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
211     fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
212     msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
213     pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
214     pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
215     pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
216
217     modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
218
219     autoCalculateConsCheck.setSelected(Cache.getDefault(
220             "AUTO_CALC_CONSENSUS", true));
221     showGroupConsensus.setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS",
222             false));
223     showGroupConservation.setSelected(Cache.getDefault(
224             "SHOW_GROUP_CONSERVATION", false));
225     showConsensHistogram.setSelected(Cache.getDefault(
226             "SHOW_CONSENSUS_HISTOGRAM", true));
227     showConsensLogo.setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO",
228             false));
229
230     padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
231
232     /***************************************************************************
233      * Set up Connections
234      */
235     nameLinks = new Vector();
236     urlLinks = new Vector();
237     for (int i = 0; i < sequenceURLLinks.size(); i++)
238     {
239       String link = sequenceURLLinks.elementAt(i).toString();
240       nameLinks.addElement(link.substring(0, link.indexOf("|")));
241       urlLinks.addElement(link.substring(link.indexOf("|") + 1));
242     }
243
244     updateLinkData();
245
246     useProxy.setSelected(Cache.getDefault("USE_PROXY", false));
247     proxyServerTB.setEnabled(useProxy.isSelected());
248     proxyPortTB.setEnabled(useProxy.isSelected());
249     proxyServerTB.setText(Cache.getDefault("PROXY_SERVER", ""));
250     proxyPortTB.setText(Cache.getDefault("PROXY_PORT", ""));
251
252     defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
253
254     usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
255     questionnaire
256             .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null); // note
257                                                                          // antisense
258                                                                          // here
259     versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true)); // default
260                                                                        // is
261                                                                        // true
262     annotations_actionPerformed(null); // update the display of the annotation
263                                        // settings
264     try
265     {
266       jbInit();
267     } catch (Exception ex)
268     {
269       ex.printStackTrace();
270     }
271
272   }
273
274   /**
275    * DOCUMENT ME!
276    * 
277    * @param e
278    *          DOCUMENT ME!
279    */
280   public void ok_actionPerformed(ActionEvent e)
281   {
282
283     Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
284             Boolean.toString(seqLimit.isSelected()));
285     Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
286             Boolean.toString(rightAlign.isSelected()));
287     Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
288             Boolean.toString(fullScreen.isSelected()));
289     Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
290             Boolean.toString(openoverv.isSelected()));
291     Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
292             Boolean.toString(annotations.isSelected()));
293     Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
294             Boolean.toString(conservation.isSelected()));
295     Cache.applicationProperties.setProperty("SHOW_QUALITY",
296             Boolean.toString(quality.isSelected()));
297     Cache.applicationProperties.setProperty("SHOW_IDENTITY",
298             Boolean.toString(identity.isSelected()));
299
300     Cache.applicationProperties.setProperty("DEFAULT_COLOUR", colour
301             .getSelectedItem().toString());
302     Cache.applicationProperties.setProperty("GAP_SYMBOL", gapSymbolCB
303             .getSelectedItem().toString());
304
305     Cache.applicationProperties.setProperty("FONT_NAME", fontNameCB
306             .getSelectedItem().toString());
307     Cache.applicationProperties.setProperty("FONT_STYLE", fontStyleCB
308             .getSelectedItem().toString());
309     Cache.applicationProperties.setProperty("FONT_SIZE", fontSizeCB
310             .getSelectedItem().toString());
311
312     Cache.applicationProperties.setProperty("ID_ITALICS",
313             Boolean.toString(idItalics.isSelected()));
314     Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
315             Boolean.toString(showUnconserved.isSelected()));
316     Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
317             Boolean.toString(showGroupConsensus.isSelected()));
318     Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
319             Boolean.toString(showGroupConservation.isSelected()));
320     Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
321             Boolean.toString(showConsensHistogram.isSelected()));
322     Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
323             Boolean.toString(showConsensLogo.isSelected()));
324     Cache.applicationProperties.setProperty("ANTI_ALIAS",
325             Boolean.toString(smoothFont.isSelected()));
326     Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
327             Boolean.toString(showNpTooltip.isSelected()));
328     Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
329             Boolean.toString(showDbRefTooltip.isSelected()));
330
331     Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
332             Boolean.toString(wrap.isSelected()));
333
334     Cache.applicationProperties.setProperty("STARTUP_FILE",
335             startupFileTextfield.getText());
336     Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
337             Boolean.toString(startupCheckbox.isSelected()));
338
339     Cache.applicationProperties.setProperty("SORT_ALIGNMENT", sortby
340             .getSelectedItem().toString());
341
342     Cache.setColourProperty("ANNOTATIONCOLOUR_MIN", minColour.getBackground());
343     Cache.setColourProperty("ANNOTATIONCOLOUR_MAX", maxColour.getBackground());
344     
345     if (epsRendering.getSelectedItem().equals("Prompt each time"))
346     {
347       Cache.applicationProperties.remove("EPS_RENDERING");
348     }
349     else
350     {
351       Cache.applicationProperties.setProperty("EPS_RENDERING", epsRendering
352               .getSelectedItem().toString());
353     }
354
355     if (defaultBrowser.getText().trim().length() < 1)
356     {
357       Cache.applicationProperties.remove("DEFAULT_BROWSER");
358     }
359     else
360     {
361       Cache.applicationProperties.setProperty("DEFAULT_BROWSER",
362               defaultBrowser.getText());
363     }
364
365     jalview.util.BrowserLauncher.resetBrowser();
366
367     if (nameLinks.size() > 0)
368     {
369       StringBuffer links = new StringBuffer();
370       sequenceURLLinks = new Vector();
371       for (int i = 0; i < nameLinks.size(); i++)
372       {
373         sequenceURLLinks.addElement(nameLinks.elementAt(i) + "|"
374                 + urlLinks.elementAt(i));
375         links.append(sequenceURLLinks.elementAt(i).toString());
376         links.append("|");
377       }
378       // remove last "|"
379       links.setLength(links.length() - 1);
380       Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
381               links.toString());
382     }
383     else
384     {
385       Cache.applicationProperties.remove("SEQUENCE_LINKS");
386     }
387
388     Cache.applicationProperties.setProperty("USE_PROXY",
389             Boolean.toString(useProxy.isSelected()));
390
391     if (proxyServerTB.getText().trim().length() < 1)
392     {
393       Cache.applicationProperties.remove("PROXY_SERVER");
394     }
395     else
396     {
397       Cache.applicationProperties.setProperty("PROXY_SERVER",
398               proxyServerTB.getText());
399     }
400
401     if (proxyPortTB.getText().trim().length() < 1)
402     {
403       Cache.applicationProperties.remove("PROXY_PORT");
404     }
405     else
406     {
407       Cache.applicationProperties.setProperty("PROXY_PORT",
408               proxyPortTB.getText());
409     }
410
411     if (useProxy.isSelected())
412     {
413       System.setProperty("http.proxyHost", proxyServerTB.getText());
414       System.setProperty("http.proxyPort", proxyPortTB.getText());
415     }
416     else
417     {
418       System.setProperty("http.proxyHost", "");
419       System.setProperty("http.proxyPort", "");
420     }
421     Cache.setProperty("VERSION_CHECK",
422             Boolean.toString(versioncheck.isSelected()));
423     if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
424     {
425       // default is false - we only set this if the user has actively agreed
426       Cache.setProperty("USAGESTATS",
427               Boolean.toString(usagestats.isSelected()));
428     }
429     if (!questionnaire.isSelected())
430     {
431       Cache.setProperty("NOQUESTIONNAIRES", "true");
432     }
433     else
434     {
435       // special - made easy to edit a property file to disable questionnaires
436       // by just adding the given line
437       Cache.removeProperty("NOQUESTIONNAIRES");
438     }
439     Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
440             Boolean.toString(blcjv.isSelected()));
441     Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
442             Boolean.toString(clustaljv.isSelected()));
443     Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
444             Boolean.toString(fastajv.isSelected()));
445     Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
446             Boolean.toString(msfjv.isSelected()));
447     Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
448             Boolean.toString(pfamjv.isSelected()));
449     Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
450             Boolean.toString(pileupjv.isSelected()));
451     Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
452             Boolean.toString(pirjv.isSelected()));
453     Cache.applicationProperties.setProperty("PIR_MODELLER",
454             Boolean.toString(modellerOutput.isSelected()));
455     jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
456
457     Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
458             Boolean.toString(autoIdWidth.isSelected()));
459     userIdWidth_actionPerformed();
460     Cache.applicationProperties.setProperty("FIGURE_USERIDWIDTH",
461                 userIdWidth.getText());
462
463     Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
464             Boolean.toString(autoCalculateConsCheck.isSelected()));
465     Cache.applicationProperties.setProperty("SORT_BY_TREE",
466             Boolean.toString(sortByTree.isSelected()));
467     Cache.applicationProperties.setProperty("PAD_GAPS",
468             Boolean.toString(padGaps.isSelected()));
469
470     dasSource.saveProperties(Cache.applicationProperties);
471     wsPrefs.updateAndRefreshWsMenuConfig(false);
472     Cache.saveProperties();
473     try
474     {
475       frame.setClosed(true);
476     } catch (Exception ex)
477     {
478     }
479   }
480
481   /**
482    * DOCUMENT ME!
483    */
484   public void startupFileTextfield_mouseClicked()
485   {
486     JalviewFileChooser chooser = new JalviewFileChooser(
487             jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
488             new String[]
489             { "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc", "jar" },
490             new String[]
491             { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview" },
492             jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
493     chooser.setFileView(new JalviewFileView());
494     chooser.setDialogTitle("Select startup file");
495
496     int value = chooser.showOpenDialog(this);
497
498     if (value == JalviewFileChooser.APPROVE_OPTION)
499     {
500       jalview.bin.Cache.applicationProperties.setProperty(
501               "DEFAULT_FILE_FORMAT", chooser.getSelectedFormat());
502       startupFileTextfield.setText(chooser.getSelectedFile()
503               .getAbsolutePath());
504     }
505   }
506
507   /**
508    * DOCUMENT ME!
509    * 
510    * @param e
511    *          DOCUMENT ME!
512    */
513   public void cancel_actionPerformed(ActionEvent e)
514   {
515     try
516     {
517       wsPrefs.updateWsMenuConfig(true);
518       wsPrefs.refreshWs_actionPerformed(e);
519       frame.setClosed(true);
520     } catch (Exception ex)
521     {
522     }
523   }
524
525   /**
526    * DOCUMENT ME!
527    * 
528    * @param e
529    *          DOCUMENT ME!
530    */
531   public void annotations_actionPerformed(ActionEvent e)
532   {
533     conservation.setEnabled(annotations.isSelected());
534     quality.setEnabled(annotations.isSelected());
535     identity.setEnabled(annotations.isSelected());
536     showGroupConsensus.setEnabled(annotations.isSelected());
537     showGroupConservation.setEnabled(annotations.isSelected());
538     showConsensHistogram.setEnabled(annotations.isSelected()
539             && (identity.isSelected() || showGroupConsensus.isSelected()));
540     showConsensLogo.setEnabled(annotations.isSelected()
541             && (identity.isSelected() || showGroupConsensus.isSelected()));
542   }
543
544   public void newLink_actionPerformed(ActionEvent e)
545   {
546
547     GSequenceLink link = new GSequenceLink();
548     boolean valid = false;
549     while (!valid)
550     {
551       if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
552               "New sequence URL link", JOptionPane.OK_CANCEL_OPTION, -1,
553               null) == JOptionPane.OK_OPTION)
554       {
555         if (link.checkValid())
556         {
557           nameLinks.addElement(link.getName());
558           urlLinks.addElement(link.getURL());
559           updateLinkData();
560           valid = true;
561         }
562       }
563       else
564       {
565         break;
566       }
567     }
568   }
569
570   public void editLink_actionPerformed(ActionEvent e)
571   {
572     GSequenceLink link = new GSequenceLink();
573
574     int index = linkNameList.getSelectedIndex();
575     if (index == -1)
576     {
577       JOptionPane.showInternalMessageDialog(Desktop.desktop,
578               "No link selected!", "No link selected",
579               JOptionPane.WARNING_MESSAGE);
580       return;
581     }
582
583     link.setName(nameLinks.elementAt(index).toString());
584     link.setURL(urlLinks.elementAt(index).toString());
585
586     boolean valid = false;
587     while (!valid)
588     {
589
590       if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
591               "New sequence URL link", JOptionPane.OK_CANCEL_OPTION, -1,
592               null) == JOptionPane.OK_OPTION)
593       {
594         if (link.checkValid())
595         {
596           nameLinks.setElementAt(link.getName(), index);
597           urlLinks.setElementAt(link.getURL(), index);
598           updateLinkData();
599           valid = true;
600         }
601       }
602
603       else
604       {
605         break;
606       }
607     }
608   }
609
610   public void deleteLink_actionPerformed(ActionEvent e)
611   {
612     int index = linkNameList.getSelectedIndex();
613     if (index == -1)
614     {
615       JOptionPane.showInternalMessageDialog(Desktop.desktop,
616               "No link selected!", "No link selected",
617               JOptionPane.WARNING_MESSAGE);
618       return;
619     }
620     nameLinks.removeElementAt(index);
621     urlLinks.removeElementAt(index);
622     updateLinkData();
623   }
624
625   void updateLinkData()
626   {
627     linkNameList.setListData(nameLinks);
628     linkURLList.setListData(urlLinks);
629   }
630
631   public void defaultBrowser_mouseClicked(MouseEvent e)
632   {
633     JFileChooser chooser = new JFileChooser(".");
634     chooser.setDialogTitle("Select default web browser");
635
636     int value = chooser.showOpenDialog(this);
637
638     if (value == JFileChooser.APPROVE_OPTION)
639     {
640       defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
641     }
642
643   }
644
645   /*
646    * (non-Javadoc)
647    * 
648    * @see
649    * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
650    * .ActionEvent)
651    */
652   protected void showunconserved_actionPerformed(ActionEvent e)
653   {
654     // TODO Auto-generated method stub
655     super.showunconserved_actionPerformed(e);
656   }
657
658   private void jbInit() throws Exception
659   {
660   }
661
662   public static Collection getGroupURLLinks()
663   {
664     return groupURLLinks;
665   }
666   public void minColour_actionPerformed()
667   {
668     Color col = JColorChooser.showDialog(this,
669             "Select Colour for Minimum Value", minColour.getBackground());
670     if (col != null)
671     {
672       minColour.setBackground(col);
673     }
674     minColour.repaint();
675   }
676
677   public void maxColour_actionPerformed()
678   {
679     Color col = JColorChooser.showDialog(this,
680             "Select Colour for Maximum Value", maxColour.getBackground());
681     if (col != null)
682     {
683       maxColour.setBackground(col);
684     }
685     maxColour.repaint();
686   }
687
688   @Override
689   protected void userIdWidth_actionPerformed()
690   {
691     try
692     {
693       String val = userIdWidth.getText().trim();
694       if (val.length() > 0)
695       {
696         Integer iw = Integer.parseInt(val);
697         if (iw.intValue() < 12)
698         {
699           throw new NumberFormatException();
700         }
701         userIdWidth.setText(iw.toString());
702       }
703     } catch (NumberFormatException x)
704     {
705       JOptionPane
706               .showInternalMessageDialog(
707                       Desktop.desktop,
708                       "The user defined width for the\nannotation and sequence ID columns\nin exported figures must be\nat least 12 pixels wide.",
709                       "Invalid ID Column width",
710                       JOptionPane.WARNING_MESSAGE);
711       userIdWidth.setText("");
712     }
713   }
714
715   @Override
716   protected void autoIdWidth_actionPerformed()
717   {
718     userIdWidth.setEnabled(!autoIdWidth.isSelected());
719     userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
720   }
721
722 }