Merge branch 'develop' into alpha/JAL-3362_Jalview_212_alpha
[jalview.git] / src / jalview / jbgui / GPreferences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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.jbgui;
22
23 import jalview.bin.Cache;
24 import jalview.fts.core.FTSDataColumnPreferences;
25 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
26 import jalview.fts.service.pdb.PDBFTSRestClient;
27 import jalview.gui.Desktop;
28 import jalview.gui.JalviewBooleanRadioButtons;
29 import jalview.gui.JvOptionPane;
30 import jalview.gui.JvSwingUtils;
31 import jalview.gui.StructureViewer.ViewerType;
32 import jalview.io.BackupFilenameParts;
33 import jalview.io.BackupFiles;
34 import jalview.io.BackupFilesPresetEntry;
35 import jalview.io.IntKeyStringValueEntry;
36 import jalview.util.MessageManager;
37 import jalview.util.Platform;
38
39 import java.awt.BorderLayout;
40 import java.awt.Color;
41 import java.awt.Component;
42 import java.awt.Dimension;
43 import java.awt.FlowLayout;
44 import java.awt.Font;
45 import java.awt.GridBagConstraints;
46 import java.awt.GridBagLayout;
47 import java.awt.GridLayout;
48 import java.awt.Insets;
49 import java.awt.Rectangle;
50 import java.awt.event.ActionEvent;
51 import java.awt.event.ActionListener;
52 import java.awt.event.KeyEvent;
53 import java.awt.event.KeyListener;
54 import java.awt.event.MouseAdapter;
55 import java.awt.event.MouseEvent;
56 import java.util.Arrays;
57 import java.util.List;
58
59 import javax.swing.AbstractButton;
60 import javax.swing.AbstractCellEditor;
61 import javax.swing.BorderFactory;
62 import javax.swing.BoxLayout;
63 import javax.swing.ButtonGroup;
64 import javax.swing.DefaultListCellRenderer;
65 import javax.swing.JButton;
66 import javax.swing.JCheckBox;
67 import javax.swing.JComboBox;
68 import javax.swing.JComponent;
69 import javax.swing.JFileChooser;
70 import javax.swing.JLabel;
71 import javax.swing.JPanel;
72 import javax.swing.JRadioButton;
73 import javax.swing.JScrollPane;
74 import javax.swing.JSpinner;
75 import javax.swing.JTabbedPane;
76 import javax.swing.JTable;
77 import javax.swing.JTextArea;
78 import javax.swing.JTextField;
79 import javax.swing.ListSelectionModel;
80 import javax.swing.SpinnerModel;
81 import javax.swing.SpinnerNumberModel;
82 import javax.swing.SwingConstants;
83 import javax.swing.border.Border;
84 import javax.swing.border.EmptyBorder;
85 import javax.swing.border.EtchedBorder;
86 import javax.swing.border.TitledBorder;
87 import javax.swing.event.ChangeEvent;
88 import javax.swing.event.ChangeListener;
89 import javax.swing.table.TableCellEditor;
90 import javax.swing.table.TableCellRenderer;
91
92 import net.miginfocom.swing.MigLayout;
93
94 /**
95  * Base class for the Preferences panel.
96  * 
97  * @author $author$
98  * @version $Revision$
99  */
100 public class GPreferences extends JPanel
101 {
102   private static final Font LABEL_FONT = JvSwingUtils.getLabelFont();
103
104   private static final Font LABEL_FONT_ITALIC = JvSwingUtils
105           .getLabelFont(false, true);
106
107   private static final Font LABEL_FONT_BOLD = JvSwingUtils
108           .getLabelFont(true, false);
109
110   /*
111    * Visual tab components
112    */
113   protected JCheckBox fullScreen = new JCheckBox();
114
115   protected JCheckBox openoverv = new JCheckBox();
116
117   protected JCheckBox seqLimit = new JCheckBox();
118
119   protected JCheckBox rightAlign = new JCheckBox();
120
121   protected JComboBox<String> fontSizeCB = new JComboBox<>();
122
123   protected JComboBox<String> fontStyleCB = new JComboBox<>();
124
125   protected JComboBox<String> fontNameCB = new JComboBox<>();
126
127   protected JCheckBox showOccupancy = new JCheckBox();
128
129   protected JCheckBox showUnconserved = new JCheckBox();
130
131   protected JCheckBox idItalics = new JCheckBox();
132
133   protected JCheckBox smoothFont = new JCheckBox();
134
135   protected JCheckBox scaleProteinToCdna = new JCheckBox();
136
137   protected JComboBox<String> gapSymbolCB = new JComboBox<>();
138
139   protected JCheckBox wrap = new JCheckBox();
140
141   protected JComboBox<String> sortby = new JComboBox<>();
142
143   protected JComboBox<String> sortAnnBy = new JComboBox<>();
144
145   protected JComboBox<String> sortAutocalc = new JComboBox<>();
146
147   protected JCheckBox startupCheckbox = new JCheckBox();
148
149   protected JTextField startupFileTextfield = new JTextField();
150
151   // below are in the 'second column'
152   protected JCheckBox annotations = new JCheckBox();
153
154   protected JCheckBox quality = new JCheckBox();
155
156   protected JCheckBox conservation = new JCheckBox();
157
158   protected JCheckBox identity = new JCheckBox();
159
160   protected JCheckBox showGroupConsensus = new JCheckBox();
161
162   protected JCheckBox showGroupConservation = new JCheckBox();
163
164   protected JCheckBox showConsensHistogram = new JCheckBox();
165
166   protected JCheckBox showConsensLogo = new JCheckBox();
167
168   protected JCheckBox showInformationHistogram = new JCheckBox();
169
170   protected JCheckBox showHMMLogo = new JCheckBox();
171
172   protected JCheckBox showDbRefTooltip = new JCheckBox();
173
174   protected JCheckBox showNpTooltip = new JCheckBox();
175
176
177   /*
178    * Structure tab and components
179    */
180   protected JPanel structureTab;
181
182   protected JCheckBox structFromPdb = new JCheckBox();
183
184   protected JCheckBox useRnaView = new JCheckBox();
185
186   protected JCheckBox addSecondaryStructure = new JCheckBox();
187
188   protected JCheckBox addTempFactor = new JCheckBox();
189
190   protected JComboBox<String> structViewer = new JComboBox<>();
191
192   protected JTextField chimeraPath = new JTextField();
193
194   protected ButtonGroup mappingMethod = new ButtonGroup();
195
196   protected JRadioButton siftsMapping = new JRadioButton();
197
198   protected JRadioButton nwMapping = new JRadioButton();
199
200   /*
201    * Colours tab components
202    */
203   protected JPanel minColour = new JPanel();
204
205   protected JPanel maxColour = new JPanel();
206
207   protected JComboBox<String> protColour = new JComboBox<>();
208
209   protected JComboBox<String> nucColour = new JComboBox<>();
210
211   /*
212    * Overview tab components
213    */
214   protected JPanel gapColour = new JPanel();
215
216   protected JPanel hiddenColour = new JPanel();
217
218   protected JCheckBox useLegacyGap;
219
220   protected JCheckBox showHiddenAtStart;
221
222   protected JLabel gapLabel;
223
224   /*
225    * Connections tab components
226    */
227   protected JTable linkUrlTable = new JTable();
228
229   protected JButton editLink = new JButton();
230
231   protected JButton deleteLink = new JButton();
232
233   protected JTextField filterTB = new JTextField();
234
235   protected JButton doReset = new JButton();
236
237   protected JButton userOnly = new JButton();
238
239   protected JLabel portLabel = new JLabel();
240
241   protected JLabel serverLabel = new JLabel();
242
243   protected JTextField proxyServerTB = new JTextField();
244
245   protected JTextField proxyPortTB = new JTextField();
246
247   protected JTextField defaultBrowser = new JTextField();
248
249   protected JCheckBox useProxy = new JCheckBox();
250
251   protected JCheckBox usagestats = new JCheckBox();
252
253   protected JCheckBox questionnaire = new JCheckBox();
254
255   protected JCheckBox versioncheck = new JCheckBox();
256
257   /*
258    * Output tab components
259    */
260   protected JComboBox<Object> epsRendering = new JComboBox<>();
261
262   protected JLabel userIdWidthlabel = new JLabel();
263
264   protected JCheckBox autoIdWidth = new JCheckBox();
265
266   protected JTextField userIdWidth = new JTextField();
267
268   protected JCheckBox blcjv = new JCheckBox();
269
270   protected JCheckBox pileupjv = new JCheckBox();
271
272   protected JCheckBox clustaljv = new JCheckBox();
273
274   protected JCheckBox msfjv = new JCheckBox();
275
276   protected JCheckBox fastajv = new JCheckBox();
277
278   protected JCheckBox pfamjv = new JCheckBox();
279
280   protected JCheckBox pirjv = new JCheckBox();
281
282   protected JCheckBox modellerOutput = new JCheckBox();
283
284   protected JCheckBox embbedBioJSON = new JCheckBox();
285
286   /*
287    * Editing tab components
288    */
289   protected JCheckBox autoCalculateConsCheck = new JCheckBox();
290
291   protected JCheckBox padGaps = new JCheckBox();
292
293   protected JCheckBox sortByTree = new JCheckBox();
294
295   /*
296    * hmmer tab and components
297    */
298   protected JPanel hmmerTab;
299
300   protected JCheckBox hmmrTrimTermini;
301
302   protected AbstractButton hmmerBackgroundUniprot;
303
304   protected AbstractButton hmmerBackgroundAlignment;
305
306   protected JTextField hmmerSequenceCount;
307
308   protected JTextField hmmerPath;
309
310   protected JTextField cygwinPath;
311
312   /*
313    * Web Services tab
314    */
315   protected JPanel wsTab = new JPanel();
316
317   /*
318    * Backups tab components
319    * a lot of these are member variables instead of local variables only so that they
320    * can be enabled/disabled easily in one go
321    */
322
323   protected JCheckBox enableBackupFiles = new JCheckBox();
324
325   protected JPanel presetsPanel = new JPanel();
326
327   protected JLabel presetsComboLabel = new JLabel();
328
329   protected JCheckBox customiseCheckbox = new JCheckBox();
330
331   protected JButton revertButton = new JButton();
332
333   protected JComboBox<Object> backupfilesPresetsCombo = new JComboBox<>();
334
335   private int backupfilesPresetsComboLastSelected = 0;
336
337   protected JPanel suffixPanel = new JPanel();
338
339   protected JPanel keepfilesPanel = new JPanel();
340
341   protected JPanel exampleFilesPanel = new JPanel();
342
343   protected JTextField suffixTemplate = new JTextField(null, 8);
344
345   protected JLabel suffixTemplateLabel = new JLabel();
346
347   protected JLabel suffixDigitsLabel = new JLabel();
348
349   protected JSpinner suffixDigitsSpinner = new JSpinner();
350
351   protected JalviewBooleanRadioButtons suffixReverse = new JalviewBooleanRadioButtons();
352
353   protected JalviewBooleanRadioButtons backupfilesKeepAll = new JalviewBooleanRadioButtons();
354
355   public JSpinner backupfilesRollMaxSpinner = new JSpinner();
356
357   protected JLabel oldBackupFilesLabel = new JLabel();
358
359   protected JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons();
360
361   protected JTextArea backupfilesExampleLabel = new JTextArea();
362
363   /**
364    * Creates a new GPreferences object.
365    */
366   public GPreferences()
367   {
368     try
369     {
370       jbInit();
371     } catch (Exception ex)
372     {
373       ex.printStackTrace();
374     }
375   }
376
377   /**
378    * Construct the panel and its tabbed sub-panels.
379    * 
380    * @throws Exception
381    */
382   private void jbInit() throws Exception
383   {
384     final JTabbedPane tabbedPane = new JTabbedPane();
385     this.setLayout(new BorderLayout());
386     JPanel okCancelPanel = initOkCancelPanel();
387     this.add(tabbedPane, BorderLayout.CENTER);
388     this.add(okCancelPanel, BorderLayout.SOUTH);
389
390     tabbedPane.add(initVisualTab(),
391             MessageManager.getString("label.visual"));
392
393     tabbedPane.add(initColoursTab(),
394             MessageManager.getString("label.colours"));
395
396     tabbedPane.add(initOverviewTab(),
397             MessageManager.getString("label.overview"));
398
399     tabbedPane.add(initStructureTab(),
400             MessageManager.getString("label.structure"));
401
402     tabbedPane.add(initConnectionsTab(),
403             MessageManager.getString("label.connections"));
404
405     tabbedPane.add(initBackupsTab(),
406             MessageManager.getString("label.backups"));
407
408     tabbedPane.add(initLinksTab(),
409             MessageManager.getString("label.urllinks"));
410
411     tabbedPane.add(initOutputTab(),
412             MessageManager.getString("label.output"));
413
414     tabbedPane.add(initEditingTab(),
415             MessageManager.getString("label.editing"));
416
417     tabbedPane.add(initHMMERTab(), MessageManager.getString("label.hmmer"));
418
419     /*
420      * See WsPreferences for the real work of configuring this tab.
421      */
422     wsTab.setLayout(new BorderLayout());
423     tabbedPane.add(wsTab, MessageManager.getString("label.web_services"));
424
425     /*
426      * Handler to validate a tab before leaving it - currently only for
427      * Structure
428      */
429     tabbedPane.addChangeListener(new ChangeListener()
430     {
431       private Component lastTab;
432
433       @Override
434       public void stateChanged(ChangeEvent e)
435       {
436         if (lastTab == structureTab
437                 && tabbedPane.getSelectedComponent() != structureTab)
438         {
439           if (!validateStructure())
440           {
441             tabbedPane.setSelectedComponent(structureTab);
442             return;
443           }
444         }
445         lastTab = tabbedPane.getSelectedComponent();
446       }
447
448     });
449   }
450
451   /**
452    * Initialises the Editing tabbed panel.
453    * 
454    * @return
455    */
456   private JPanel initEditingTab()
457   {
458     JPanel editingTab = new JPanel();
459     editingTab.setLayout(null);
460     autoCalculateConsCheck.setFont(LABEL_FONT);
461     autoCalculateConsCheck.setText(
462             MessageManager.getString("label.autocalculate_consensus"));
463     autoCalculateConsCheck.setBounds(new Rectangle(21, 52, 209, 23));
464     padGaps.setFont(LABEL_FONT);
465     padGaps.setText(
466             MessageManager.getString("label.pad_gaps_when_editing"));
467     padGaps.setBounds(new Rectangle(22, 94, 168, 23));
468     sortByTree.setFont(LABEL_FONT);
469     sortByTree
470             .setText(MessageManager.getString("label.sort_with_new_tree"));
471     sortByTree.setToolTipText(MessageManager.getString(
472             "label.any_trees_calculated_or_loaded_alignment_automatically_sort"));
473     sortByTree.setBounds(new Rectangle(22, 136, 168, 23));
474     editingTab.add(autoCalculateConsCheck);
475     editingTab.add(padGaps);
476     editingTab.add(sortByTree);
477     return editingTab;
478   }
479
480   /**
481    * Initialises the hmmer tabbed panel
482    * 
483    * @return
484    */
485   private JPanel initHMMERTab()
486   {
487     hmmerTab = new JPanel();
488     hmmerTab.setLayout(new BoxLayout(hmmerTab, BoxLayout.Y_AXIS));
489     hmmerTab.setLayout(new MigLayout("flowy"));
490
491     /*
492      * path to hmmer binaries folder
493      */
494     JPanel installationPanel = new JPanel(new MigLayout("flowy"));
495     // new FlowLayout(FlowLayout.LEFT));
496     JvSwingUtils.createTitledBorder(installationPanel,
497             MessageManager.getString("label.installation"), true);
498     hmmerTab.add(installationPanel);
499     JLabel hmmerLocation = new JLabel(
500             MessageManager.getString("label.hmmer_location"));
501     hmmerLocation.setFont(LABEL_FONT);
502     final int pathFieldLength = 40;
503     hmmerPath = new JTextField(pathFieldLength);
504     hmmerPath.addMouseListener(new MouseAdapter()
505     {
506       @Override
507       public void mouseClicked(MouseEvent e)
508       {
509         if (e.getClickCount() == 2)
510         {
511           String chosen = openFileChooser(true);
512           if (chosen != null)
513           {
514             hmmerPath.setText(chosen);
515             validateHmmerPath();
516           }
517         }
518       }
519     });
520     installationPanel.add(hmmerLocation);
521     installationPanel.add(hmmerPath);
522
523     /*
524      * path to Cygwin binaries folder (for Windows)
525      */
526     if (Platform.isWindows())
527     {
528       JLabel cygwinLocation = new JLabel(
529               MessageManager.getString("label.cygwin_location"));
530       cygwinLocation.setFont(LABEL_FONT);
531       cygwinPath = new JTextField(pathFieldLength);
532       cygwinPath.addMouseListener(new MouseAdapter()
533       {
534         @Override
535         public void mouseClicked(MouseEvent e)
536         {
537           if (e.getClickCount() == 2)
538           {
539             String chosen = openFileChooser(true);
540             if (chosen != null)
541             {
542               cygwinPath.setText(chosen);
543               validateCygwinPath();
544             }
545           }
546         }
547       });
548       installationPanel.add(cygwinLocation);
549       installationPanel.add(cygwinPath);
550     }
551
552     /*
553      * preferences for hmmalign
554      */
555     JPanel alignOptionsPanel = new JPanel(new MigLayout());
556     // new FlowLayout(FlowLayout.LEFT));
557     JvSwingUtils.createTitledBorder(alignOptionsPanel,
558             MessageManager.getString("label.hmmalign_options"), true);
559     hmmerTab.add(alignOptionsPanel);
560     hmmrTrimTermini = new JCheckBox();
561     hmmrTrimTermini.setFont(LABEL_FONT);
562     hmmrTrimTermini.setText(MessageManager.getString("label.trim_termini"));
563     alignOptionsPanel.add(hmmrTrimTermini);
564
565     /*
566      * preferences for hmmsearch
567      */
568     JPanel searchOptions = new JPanel(new MigLayout());
569     // FlowLayout(FlowLayout.LEFT));
570     JvSwingUtils.createTitledBorder(searchOptions,
571             MessageManager.getString("label.hmmsearch_options"), true);
572     hmmerTab.add(searchOptions);
573     JLabel sequencesToKeep = new JLabel(
574             MessageManager.getString("label.no_of_sequences"));
575     sequencesToKeep.setFont(LABEL_FONT);
576     searchOptions.add(sequencesToKeep);
577     hmmerSequenceCount = new JTextField(5);
578     searchOptions.add(hmmerSequenceCount);
579
580     /*
581      * preferences for Information Content annotation
582      */
583     // JPanel dummy = new JPanel(new FlowLayout(FlowLayout.LEFT));
584     JPanel annotationOptions = new JPanel(new MigLayout("left"));
585     JvSwingUtils.createTitledBorder(annotationOptions,
586             MessageManager.getString("label.information_annotation"), true);
587     // dummy.add(annotationOptions);
588     hmmerTab.add(annotationOptions);
589     ButtonGroup backgroundOptions = new ButtonGroup();
590     hmmerBackgroundUniprot = new JRadioButton(
591             MessageManager.getString("label.freq_uniprot"));
592     hmmerBackgroundUniprot.setFont(LABEL_FONT);
593     hmmerBackgroundAlignment = new JRadioButton(
594             MessageManager.getString("label.freq_alignment"));
595     hmmerBackgroundAlignment.setFont(LABEL_FONT);
596     backgroundOptions.add(hmmerBackgroundUniprot);
597     backgroundOptions.add(hmmerBackgroundAlignment);
598     backgroundOptions.setSelected(hmmerBackgroundUniprot.getModel(), true);
599     // disable buttons for now as annotation only uses Uniprot background
600     hmmerBackgroundAlignment.setEnabled(false);
601     hmmerBackgroundUniprot.setEnabled(false);
602     annotationOptions.add(hmmerBackgroundUniprot, "wrap");
603     annotationOptions.add(hmmerBackgroundAlignment);
604
605     return hmmerTab;
606   }
607
608   /**
609    * Initialises the Output tabbed panel.
610    * 
611    * @return
612    */
613   private JPanel initOutputTab()
614   {
615     JPanel outputTab = new JPanel();
616     outputTab.setLayout(null);
617     JLabel epsLabel = new JLabel();
618     epsLabel.setFont(LABEL_FONT);
619     epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
620     epsLabel.setText(MessageManager.getString("label.eps_rendering_style"));
621     epsLabel.setBounds(new Rectangle(9, 31, 140, 24));
622     epsRendering.setFont(LABEL_FONT);
623     epsRendering.setBounds(new Rectangle(154, 34, 187, 21));
624     JLabel jLabel1 = new JLabel();
625     jLabel1.setFont(LABEL_FONT);
626     jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
627     jLabel1.setText(MessageManager.getString("label.append_start_end"));
628     jLabel1.setFont(LABEL_FONT);
629     fastajv.setFont(LABEL_FONT);
630     fastajv.setHorizontalAlignment(SwingConstants.LEFT);
631     clustaljv.setText(MessageManager.getString("label.clustal") + "     ");
632     blcjv.setText(MessageManager.getString("label.blc") + "     ");
633     fastajv.setText(MessageManager.getString("label.fasta") + "     ");
634     msfjv.setText(MessageManager.getString("label.msf") + "     ");
635     pfamjv.setText(MessageManager.getString("label.pfam") + "     ");
636     pileupjv.setText(MessageManager.getString("label.pileup") + "     ");
637     msfjv.setFont(LABEL_FONT);
638     msfjv.setHorizontalAlignment(SwingConstants.LEFT);
639     pirjv.setText(MessageManager.getString("label.pir") + "     ");
640     JPanel jPanel11 = new JPanel();
641     jPanel11.setFont(LABEL_FONT);
642     TitledBorder titledBorder2 = new TitledBorder(
643             MessageManager.getString("label.file_output"));
644     jPanel11.setBorder(titledBorder2);
645     jPanel11.setBounds(new Rectangle(30, 72, 196, 182));
646     GridLayout gridLayout3 = new GridLayout();
647     jPanel11.setLayout(gridLayout3);
648     gridLayout3.setRows(8);
649     blcjv.setFont(LABEL_FONT);
650     blcjv.setHorizontalAlignment(SwingConstants.LEFT);
651     clustaljv.setFont(LABEL_FONT);
652     clustaljv.setHorizontalAlignment(SwingConstants.LEFT);
653     pfamjv.setFont(LABEL_FONT);
654     pfamjv.setHorizontalAlignment(SwingConstants.LEFT);
655     pileupjv.setFont(LABEL_FONT);
656     pileupjv.setHorizontalAlignment(SwingConstants.LEFT);
657     pirjv.setFont(LABEL_FONT);
658     pirjv.setHorizontalAlignment(SwingConstants.LEFT);
659     autoIdWidth.setFont(LABEL_FONT);
660     autoIdWidth.setText(
661             MessageManager.getString("label.automatically_set_id_width"));
662     autoIdWidth.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager
663             .getString("label.adjusts_width_generated_eps_png")));
664     autoIdWidth.setBounds(new Rectangle(228, 96, 188, 23));
665     autoIdWidth.addActionListener(new ActionListener()
666     {
667
668       @Override
669       public void actionPerformed(ActionEvent e)
670       {
671         autoIdWidth_actionPerformed();
672       }
673     });
674     userIdWidthlabel.setFont(LABEL_FONT);
675     userIdWidthlabel.setText(
676             MessageManager.getString("label.figure_id_column_width"));
677     userIdWidth.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager
678             .getString("label.manually_specify_width_left_column")));
679     userIdWidthlabel.setToolTipText(
680             JvSwingUtils.wrapTooltip(true, MessageManager.getString(
681                     "label.manually_specify_width_left_column")));
682     userIdWidthlabel.setBounds(new Rectangle(236, 120, 168, 23));
683     userIdWidth.setFont(JvSwingUtils.getTextAreaFont());
684     userIdWidth.setText("");
685     userIdWidth.setBounds(new Rectangle(232, 144, 84, 23));
686     userIdWidth.addActionListener(new ActionListener()
687     {
688
689       @Override
690       public void actionPerformed(ActionEvent e)
691       {
692         userIdWidth_actionPerformed();
693       }
694     });
695     modellerOutput.setFont(LABEL_FONT);
696     modellerOutput
697             .setText(MessageManager.getString("label.use_modeller_output"));
698     modellerOutput.setBounds(new Rectangle(228, 226, 168, 23));
699     embbedBioJSON.setFont(LABEL_FONT);
700     embbedBioJSON.setText(MessageManager.getString("label.embbed_biojson"));
701     embbedBioJSON.setBounds(new Rectangle(228, 200, 250, 23));
702
703     jPanel11.add(jLabel1);
704     jPanel11.add(blcjv);
705     jPanel11.add(clustaljv);
706     jPanel11.add(fastajv);
707     jPanel11.add(msfjv);
708     jPanel11.add(pfamjv);
709     jPanel11.add(pileupjv);
710     jPanel11.add(pirjv);
711     outputTab.add(autoIdWidth);
712     outputTab.add(userIdWidth);
713     outputTab.add(userIdWidthlabel);
714     outputTab.add(modellerOutput);
715     outputTab.add(embbedBioJSON);
716     outputTab.add(epsLabel);
717     outputTab.add(epsRendering);
718     outputTab.add(jPanel11);
719     return outputTab;
720   }
721
722   /**
723    * Initialises the Connections tabbed panel.
724    * 
725    * @return
726    */
727   private JPanel initConnectionsTab()
728   {
729     JPanel connectTab = new JPanel();
730     connectTab.setLayout(new GridBagLayout());
731
732     // Label for browser text box
733     JLabel browserLabel = new JLabel();
734     browserLabel.setFont(LABEL_FONT);
735     browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
736     browserLabel.setText(
737             MessageManager.getString("label.default_browser_unix"));
738     defaultBrowser.setFont(LABEL_FONT);
739     defaultBrowser.setText("");
740     final String tooltip = JvSwingUtils.wrapTooltip(true,
741             MessageManager.getString("label.double_click_to_browse"));
742     defaultBrowser.setToolTipText(tooltip);
743     defaultBrowser.addMouseListener(new MouseAdapter()
744     {
745       @Override
746       public void mouseClicked(MouseEvent e)
747       {
748         if (e.getClickCount() > 1)
749         {
750           defaultBrowser_mouseClicked(e);
751         }
752       }
753     });
754
755     JPanel proxyPanel = initConnTabProxyPanel();
756     initConnTabCheckboxes();
757
758     // Add default Browser text box
759     connectTab.add(browserLabel,
760             new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
761                     GridBagConstraints.WEST, GridBagConstraints.NONE,
762                     new Insets(10, 0, 5, 5), 5, 1));
763     defaultBrowser.setFont(LABEL_FONT);
764     defaultBrowser.setText("");
765
766     connectTab.add(defaultBrowser, new GridBagConstraints(1, 0, 1, 1, 1.0,
767             0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
768             new Insets(10, 0, 5, 10), 30, 1));
769
770     // Add proxy server panel
771     connectTab.add(proxyPanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0,
772             GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
773             new Insets(10, 0, 5, 12), 4, 10));
774
775     // Add usage stats, version check and questionnaire checkboxes
776     connectTab.add(usagestats,
777             new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0,
778                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
779                     new Insets(0, 2, 5, 5), 70, 1));
780     connectTab.add(questionnaire,
781             new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0,
782                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
783                     new Insets(0, 2, 5, 10), 70, 1));
784     connectTab.add(versioncheck,
785             new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0,
786                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
787                     new Insets(0, 2, 5, 5), 70, 1));
788
789     versioncheck.setVisible(false);
790
791     // Add padding so the panel doesn't look ridiculous
792     JPanel spacePanel = new JPanel();
793     connectTab.add(spacePanel,
794             new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0,
795                     GridBagConstraints.WEST, GridBagConstraints.BOTH,
796                     new Insets(0, 0, 0, 5), 70, 1));
797
798     return connectTab;
799   }
800
801   /**
802    * Initialises the Links tabbed panel.
803    * 
804    * @return
805    */
806   private JPanel initLinksTab()
807   {
808     JPanel linkTab = new JPanel();
809     linkTab.setLayout(new GridBagLayout());
810
811     // Set up table for Url links
812     linkUrlTable.getTableHeader().setReorderingAllowed(false);
813     linkUrlTable.setFillsViewportHeight(true);
814     linkUrlTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
815     linkUrlTable.setAutoCreateRowSorter(true);
816     linkUrlTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
817
818     // adjust row height so radio buttons actually fit
819     // don't do this in the renderer, it causes the awt thread to activate
820     // constantly
821     JRadioButton temp = new JRadioButton();
822     linkUrlTable.setRowHeight(temp.getMinimumSize().height);
823
824     // Table in scrollpane so that the table is given a scrollbar
825     JScrollPane linkScrollPane = new JScrollPane(linkUrlTable);
826     linkScrollPane.setBorder(null);
827
828     // Panel for links functionality
829     JPanel linkPanel = new JPanel(new GridBagLayout());
830     linkPanel.setBorder(new TitledBorder(
831             MessageManager.getString("label.url_linkfrom_sequence_id")));
832
833     // Put the Url links panel together
834
835     // Buttons go at top right, resizing only resizes the blank space vertically
836     JPanel buttonPanel = initLinkTabUrlButtons();
837     GridBagConstraints linkConstraints1 = new GridBagConstraints();
838     linkConstraints1.insets = new Insets(0, 0, 5, 0);
839     linkConstraints1.gridx = 0;
840     linkConstraints1.gridy = 0;
841     linkConstraints1.weightx = 1.0;
842     linkConstraints1.fill = GridBagConstraints.HORIZONTAL;
843     linkTab.add(buttonPanel, linkConstraints1);
844
845     // Links table goes at top left, resizing resizes the table
846     GridBagConstraints linkConstraints2 = new GridBagConstraints();
847     linkConstraints2.insets = new Insets(0, 0, 5, 5);
848     linkConstraints2.gridx = 0;
849     linkConstraints2.gridy = 1;
850     linkConstraints2.weightx = 1.0;
851     linkConstraints2.weighty = 1.0;
852     linkConstraints2.fill = GridBagConstraints.BOTH;
853     linkTab.add(linkScrollPane, linkConstraints2);
854
855     // Filter box and buttons goes at bottom left, resizing resizes the text box
856     JPanel filterPanel = initLinkTabFilterPanel();
857     GridBagConstraints linkConstraints3 = new GridBagConstraints();
858     linkConstraints3.insets = new Insets(0, 0, 0, 5);
859     linkConstraints3.gridx = 0;
860     linkConstraints3.gridy = 2;
861     linkConstraints3.weightx = 1.0;
862     linkConstraints3.fill = GridBagConstraints.HORIZONTAL;
863     linkTab.add(filterPanel, linkConstraints3);
864
865     return linkTab;
866   }
867
868   private JPanel initLinkTabFilterPanel()
869   {
870     // Filter textbox and reset button
871     JLabel filterLabel = new JLabel(
872             MessageManager.getString("label.filter"));
873     filterLabel.setFont(LABEL_FONT);
874     filterLabel.setHorizontalAlignment(SwingConstants.RIGHT);
875     filterLabel.setHorizontalTextPosition(SwingConstants.LEADING);
876
877     filterTB.setFont(LABEL_FONT);
878     filterTB.setText("");
879
880     doReset.setText(MessageManager.getString("action.showall"));
881     userOnly.setText(MessageManager.getString("action.customfilter"));
882
883     // Panel for filter functionality
884     JPanel filterPanel = new JPanel(new GridBagLayout());
885     filterPanel.setBorder(new TitledBorder("Filter"));
886     GridBagConstraints gbc = new GridBagConstraints();
887     gbc.gridx = 0;
888     gbc.gridy = 0;
889     gbc.fill = GridBagConstraints.NONE;
890     gbc.anchor = GridBagConstraints.WEST;
891
892     filterPanel.add(filterLabel, gbc);
893
894     GridBagConstraints gbc1 = new GridBagConstraints();
895     gbc1.gridx = 1;
896     gbc1.gridwidth = 2;
897     gbc1.fill = GridBagConstraints.HORIZONTAL;
898     gbc1.anchor = GridBagConstraints.WEST;
899     gbc1.weightx = 1.0;
900     filterPanel.add(filterTB, gbc1);
901
902     GridBagConstraints gbc2 = new GridBagConstraints();
903     gbc2.gridx = 3;
904     gbc2.fill = GridBagConstraints.NONE;
905     gbc2.anchor = GridBagConstraints.WEST;
906     filterPanel.add(doReset, gbc2);
907
908     GridBagConstraints gbc3 = new GridBagConstraints();
909     gbc3.gridx = 4;
910     gbc3.fill = GridBagConstraints.NONE;
911     gbc3.anchor = GridBagConstraints.WEST;
912     filterPanel.add(userOnly, gbc3);
913
914     return filterPanel;
915   }
916
917   private JPanel initLinkTabUrlButtons()
918   {
919     // Buttons for new / edit / delete Url links
920     JButton newLink = new JButton();
921     newLink.setText(MessageManager.getString("action.new"));
922
923     editLink.setText(MessageManager.getString("action.edit"));
924
925     deleteLink.setText(MessageManager.getString("action.delete"));
926
927     // no current selection, so initially disable delete/edit buttons
928     editLink.setEnabled(false);
929     deleteLink.setEnabled(false);
930
931     newLink.addActionListener(new java.awt.event.ActionListener()
932     {
933       @Override
934       public void actionPerformed(ActionEvent e)
935       {
936         newLink_actionPerformed(e);
937       }
938     });
939
940     editLink.setText(MessageManager.getString("action.edit"));
941     editLink.addActionListener(new java.awt.event.ActionListener()
942     {
943       @Override
944       public void actionPerformed(ActionEvent e)
945       {
946         editLink_actionPerformed(e);
947       }
948     });
949
950     deleteLink.setText(MessageManager.getString("action.delete"));
951     deleteLink.addActionListener(new java.awt.event.ActionListener()
952     {
953       @Override
954       public void actionPerformed(ActionEvent e)
955       {
956         deleteLink_actionPerformed(e);
957       }
958     });
959
960     JPanel buttonPanel = new JPanel(new GridBagLayout());
961     buttonPanel.setBorder(new TitledBorder("Edit links"));
962     GridBagConstraints gbc = new GridBagConstraints();
963     gbc.gridx = 0;
964     gbc.gridy = 0;
965     gbc.fill = GridBagConstraints.NONE;
966     buttonPanel.add(newLink, gbc);
967
968     GridBagConstraints gbc1 = new GridBagConstraints();
969     gbc1.gridx = 1;
970     gbc1.gridy = 0;
971     gbc1.fill = GridBagConstraints.NONE;
972     buttonPanel.add(editLink, gbc1);
973
974     GridBagConstraints gbc2 = new GridBagConstraints();
975     gbc2.gridx = 2;
976     gbc2.gridy = 0;
977     gbc2.fill = GridBagConstraints.NONE;
978     buttonPanel.add(deleteLink, gbc2);
979
980     GridBagConstraints gbc3 = new GridBagConstraints();
981     gbc3.gridx = 3;
982     gbc3.gridy = 0;
983     gbc3.fill = GridBagConstraints.HORIZONTAL;
984     gbc3.weightx = 1.0;
985     JPanel spacePanel = new JPanel();
986     spacePanel.setBorder(null);
987     buttonPanel.add(spacePanel, gbc3);
988
989     return buttonPanel;
990   }
991
992   /**
993    * Initialises the proxy server panel in the Connections tab
994    * 
995    * @return the proxy server panel
996    */
997   private JPanel initConnTabProxyPanel()
998   {
999     // Label for server text box
1000     serverLabel.setText(MessageManager.getString("label.address"));
1001     serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1002     serverLabel.setFont(LABEL_FONT);
1003
1004     // Proxy server and port text boxes
1005     proxyServerTB.setFont(LABEL_FONT);
1006     proxyPortTB.setFont(LABEL_FONT);
1007
1008     // Label for Port text box
1009     portLabel.setFont(LABEL_FONT);
1010     portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1011     portLabel.setText(MessageManager.getString("label.port"));
1012
1013     // Use proxy server checkbox
1014     useProxy.setFont(LABEL_FONT);
1015     useProxy.setHorizontalAlignment(SwingConstants.RIGHT);
1016     useProxy.setHorizontalTextPosition(SwingConstants.LEADING);
1017     useProxy.setText(MessageManager.getString("label.use_proxy_server"));
1018     useProxy.addActionListener(new ActionListener()
1019     {
1020       @Override
1021       public void actionPerformed(ActionEvent e)
1022       {
1023         useProxy_actionPerformed();
1024       }
1025     });
1026
1027     // Make proxy server panel
1028     JPanel proxyPanel = new JPanel();
1029     TitledBorder titledBorder1 = new TitledBorder(
1030             MessageManager.getString("label.proxy_server"));
1031     proxyPanel.setBorder(titledBorder1);
1032     proxyPanel.setLayout(new GridBagLayout());
1033     proxyPanel.add(serverLabel,
1034             new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
1035                     GridBagConstraints.WEST, GridBagConstraints.NONE,
1036                     new Insets(0, 2, 2, 0), 5, 0));
1037     proxyPanel.add(portLabel,
1038             new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
1039                     GridBagConstraints.WEST, GridBagConstraints.NONE,
1040                     new Insets(0, 0, 2, 0), 11, 0));
1041     proxyPanel.add(useProxy,
1042             new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
1043                     GridBagConstraints.WEST, GridBagConstraints.NONE,
1044                     new Insets(0, 2, 5, 185), 2, -4));
1045     proxyPanel.add(proxyPortTB,
1046             new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0,
1047                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
1048                     new Insets(0, 2, 2, 2), 54, 1));
1049     proxyPanel.add(proxyServerTB,
1050             new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
1051                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
1052                     new Insets(0, 2, 2, 0), 263, 1));
1053
1054     return proxyPanel;
1055   }
1056
1057   /**
1058    * Initialises the checkboxes in the Connections tab
1059    */
1060   private void initConnTabCheckboxes()
1061   {
1062     // Usage stats checkbox label
1063     usagestats.setText(
1064             MessageManager.getString("label.send_usage_statistics"));
1065     usagestats.setFont(LABEL_FONT);
1066     usagestats.setHorizontalAlignment(SwingConstants.RIGHT);
1067     usagestats.setHorizontalTextPosition(SwingConstants.LEADING);
1068
1069     // Questionnaire checkbox label
1070     questionnaire.setText(
1071             MessageManager.getString("label.check_for_questionnaires"));
1072     questionnaire.setFont(LABEL_FONT);
1073     questionnaire.setHorizontalAlignment(SwingConstants.RIGHT);
1074     questionnaire.setHorizontalTextPosition(SwingConstants.LEADING);
1075
1076     // Check for latest version checkbox label
1077     versioncheck.setText(
1078             MessageManager.getString("label.check_for_latest_version"));
1079     versioncheck.setFont(LABEL_FONT);
1080     versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
1081     versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
1082   }
1083
1084   /**
1085    * Initialises the parent panel which contains the tabbed sections.
1086    * 
1087    * @return
1088    */
1089   private JPanel initOkCancelPanel()
1090   {
1091     JButton ok = new JButton();
1092     ok.setText(MessageManager.getString("action.ok"));
1093     ok.addActionListener(new ActionListener()
1094     {
1095       @Override
1096       public void actionPerformed(ActionEvent e)
1097       {
1098         ok_actionPerformed(e);
1099       }
1100     });
1101     JButton cancel = new JButton();
1102     cancel.setText(MessageManager.getString("action.cancel"));
1103     cancel.addActionListener(new ActionListener()
1104     {
1105       @Override
1106       public void actionPerformed(ActionEvent e)
1107       {
1108         cancel_actionPerformed(e);
1109       }
1110     });
1111     JPanel okCancelPanel = new JPanel();
1112     okCancelPanel.add(ok);
1113     okCancelPanel.add(cancel);
1114     return okCancelPanel;
1115   }
1116
1117   /**
1118    * Initialises the Colours tabbed panel.
1119    * 
1120    * @return
1121    */
1122   private JPanel initColoursTab()
1123   {
1124     JPanel coloursTab = new JPanel();
1125     coloursTab.setBorder(new TitledBorder(
1126             MessageManager.getString("action.open_new_alignment")));
1127     coloursTab.setLayout(new FlowLayout());
1128     JLabel mincolourLabel = new JLabel();
1129     mincolourLabel.setFont(LABEL_FONT);
1130     mincolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1131     mincolourLabel.setText(MessageManager.getString("label.min_colour"));
1132     minColour.setFont(LABEL_FONT);
1133     minColour.setBorder(BorderFactory.createEtchedBorder());
1134     minColour.setPreferredSize(new Dimension(40, 20));
1135     minColour.addMouseListener(new MouseAdapter()
1136     {
1137       @Override
1138       public void mousePressed(MouseEvent e)
1139       {
1140         minColour_actionPerformed(minColour);
1141       }
1142     });
1143     JLabel maxcolourLabel = new JLabel();
1144     maxcolourLabel.setFont(LABEL_FONT);
1145     maxcolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1146     maxcolourLabel.setText(MessageManager.getString("label.max_colour"));
1147     maxColour.setFont(LABEL_FONT);
1148     maxColour.setBorder(BorderFactory.createEtchedBorder());
1149     maxColour.setPreferredSize(new Dimension(40, 20));
1150     maxColour.addMouseListener(new MouseAdapter()
1151     {
1152       @Override
1153       public void mousePressed(MouseEvent e)
1154       {
1155         maxColour_actionPerformed(maxColour);
1156       }
1157     });
1158
1159     protColour.setFont(LABEL_FONT);
1160     protColour.setBounds(new Rectangle(172, 225, 155, 21));
1161     JLabel protColourLabel = new JLabel();
1162     protColourLabel.setFont(LABEL_FONT);
1163     protColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
1164     protColourLabel.setText(
1165             MessageManager.getString("label.prot_alignment_colour") + " ");
1166     GPreferences.addtoLayout(coloursTab,
1167             MessageManager
1168                     .getString("label.default_colour_scheme_for_alignment"),
1169             protColourLabel, protColour);
1170
1171     nucColour.setFont(LABEL_FONT);
1172     nucColour.setBounds(new Rectangle(172, 240, 155, 21));
1173     JLabel nucColourLabel = new JLabel();
1174     nucColourLabel.setFont(LABEL_FONT);
1175     nucColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
1176     nucColourLabel.setText(
1177             MessageManager.getString("label.nuc_alignment_colour") + " ");
1178     GPreferences.addtoLayout(coloursTab,
1179             MessageManager
1180                     .getString("label.default_colour_scheme_for_alignment"),
1181             nucColourLabel, nucColour);
1182
1183     JPanel annotationShding = new JPanel();
1184     annotationShding.setBorder(new TitledBorder(
1185             MessageManager.getString("label.annotation_shading_default")));
1186     annotationShding.setLayout(new GridLayout(1, 2));
1187     GPreferences.addtoLayout(annotationShding,
1188             MessageManager.getString(
1189                     "label.default_minimum_colour_annotation_shading"),
1190             mincolourLabel, minColour);
1191     GPreferences.addtoLayout(annotationShding,
1192             MessageManager.getString(
1193                     "label.default_maximum_colour_annotation_shading"),
1194             maxcolourLabel, maxColour);
1195     coloursTab.add(annotationShding); // , FlowLayout.LEFT);
1196     return coloursTab;
1197   }
1198
1199   /**
1200    * Initialises the Overview tabbed panel.
1201    * 
1202    * @return
1203    */
1204   private JPanel initOverviewTab()
1205   {
1206     JPanel overviewPanel = new JPanel();
1207     overviewPanel.setBorder(new TitledBorder(
1208             MessageManager.getString("label.overview_settings")));
1209
1210     gapColour.setFont(LABEL_FONT);
1211     // fixing the border colours stops apparent colour bleed from the panel
1212     gapColour.setBorder(
1213             BorderFactory.createEtchedBorder(Color.white, Color.lightGray));
1214     gapColour.setPreferredSize(new Dimension(40, 20));
1215     gapColour.addMouseListener(new MouseAdapter()
1216     {
1217       @Override
1218       public void mousePressed(MouseEvent e)
1219       {
1220         gapColour_actionPerformed(gapColour);
1221       }
1222     });
1223
1224     hiddenColour.setFont(LABEL_FONT);
1225     // fixing the border colours stops apparent colour bleed from the panel
1226     hiddenColour.setBorder(
1227             BorderFactory.createEtchedBorder(Color.white, Color.lightGray));
1228     hiddenColour.setPreferredSize(new Dimension(40, 20));
1229     hiddenColour.addMouseListener(new MouseAdapter()
1230     {
1231       @Override
1232       public void mousePressed(MouseEvent e)
1233       {
1234         hiddenColour_actionPerformed(hiddenColour);
1235       }
1236     });
1237
1238     useLegacyGap = new JCheckBox(
1239             MessageManager.getString("label.ov_legacy_gap"));
1240     useLegacyGap.setFont(LABEL_FONT);
1241     useLegacyGap.setHorizontalAlignment(SwingConstants.LEFT);
1242     useLegacyGap.setVerticalTextPosition(SwingConstants.TOP);
1243     gapLabel = new JLabel(MessageManager.getString("label.gap_colour"));
1244     gapLabel.setFont(LABEL_FONT);
1245     gapLabel.setHorizontalAlignment(SwingConstants.LEFT);
1246     gapLabel.setVerticalTextPosition(SwingConstants.TOP);
1247     showHiddenAtStart = new JCheckBox(
1248             MessageManager.getString("label.ov_show_hide_default"));
1249     showHiddenAtStart.setFont(LABEL_FONT);
1250     showHiddenAtStart.setHorizontalAlignment(SwingConstants.LEFT);
1251     showHiddenAtStart.setVerticalTextPosition(SwingConstants.TOP);
1252     JLabel hiddenLabel = new JLabel(
1253             MessageManager.getString("label.hidden_colour"));
1254     hiddenLabel.setFont(LABEL_FONT);
1255     hiddenLabel.setHorizontalAlignment(SwingConstants.LEFT);
1256     hiddenLabel.setVerticalTextPosition(SwingConstants.TOP);
1257
1258     useLegacyGap.addActionListener(new ActionListener()
1259     {
1260       @Override
1261       public void actionPerformed(ActionEvent e)
1262       {
1263         useLegacyGaps_actionPerformed(e);
1264       }
1265     });
1266
1267     overviewPanel.setLayout(new GridBagLayout());
1268     GridBagConstraints c1 = new GridBagConstraints();
1269
1270     c1.fill = GridBagConstraints.HORIZONTAL;
1271     c1.gridx = 0;
1272     c1.gridy = 0;
1273     c1.weightx = 1;
1274     c1.ipady = 20;
1275     c1.anchor = GridBagConstraints.FIRST_LINE_START;
1276     overviewPanel.add(useLegacyGap, c1);
1277
1278     GridBagConstraints c2 = new GridBagConstraints();
1279     c2.fill = GridBagConstraints.HORIZONTAL;
1280     c2.gridx = 1;
1281     c2.gridy = 0;
1282     c2.insets = new Insets(0, 15, 0, 10);
1283     overviewPanel.add(gapLabel, c2);
1284
1285     GridBagConstraints c3 = new GridBagConstraints();
1286     c3.fill = GridBagConstraints.HORIZONTAL;
1287     c3.gridx = 2;
1288     c3.gridy = 0;
1289     c3.insets = new Insets(0, 0, 0, 15);
1290     overviewPanel.add(gapColour, c3);
1291
1292     GridBagConstraints c4 = new GridBagConstraints();
1293     c4.fill = GridBagConstraints.HORIZONTAL;
1294     c4.gridx = 0;
1295     c4.gridy = 1;
1296     c4.weightx = 1;
1297     overviewPanel.add(showHiddenAtStart, c4);
1298
1299     GridBagConstraints c5 = new GridBagConstraints();
1300     c5.fill = GridBagConstraints.HORIZONTAL;
1301     c5.gridx = 1;
1302     c5.gridy = 1;
1303     c5.insets = new Insets(0, 15, 0, 10);
1304     overviewPanel.add(hiddenLabel, c5);
1305
1306     GridBagConstraints c6 = new GridBagConstraints();
1307     c6.fill = GridBagConstraints.HORIZONTAL;
1308     c6.gridx = 2;
1309     c6.gridy = 1;
1310     c6.insets = new Insets(0, 0, 0, 15);
1311     overviewPanel.add(hiddenColour, c6);
1312
1313     JButton resetButton = new JButton(
1314             MessageManager.getString("label.reset_to_defaults"));
1315
1316     resetButton.addActionListener(new ActionListener()
1317     {
1318       @Override
1319       public void actionPerformed(ActionEvent e)
1320       {
1321         resetOvDefaults_actionPerformed(e);
1322       }
1323     });
1324
1325     GridBagConstraints c7 = new GridBagConstraints();
1326     c7.fill = GridBagConstraints.NONE;
1327     c7.gridx = 0;
1328     c7.gridy = 2;
1329     c7.insets = new Insets(10, 0, 0, 0);
1330     c7.anchor = GridBagConstraints.WEST;
1331     overviewPanel.add(resetButton, c7);
1332
1333     // Add padding so the panel doesn't look ridiculous
1334     JPanel spacePanel = new JPanel();
1335     overviewPanel.add(spacePanel,
1336             new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0,
1337                     GridBagConstraints.WEST, GridBagConstraints.BOTH,
1338                     new Insets(0, 0, 0, 5), 0, 0));
1339
1340     return overviewPanel;
1341   }
1342
1343   /**
1344    * Initialises the Structure tabbed panel.
1345    * 
1346    * @return
1347    */
1348   private JPanel initStructureTab()
1349   {
1350     structureTab = new JPanel();
1351
1352     structureTab.setBorder(new TitledBorder(
1353             MessageManager.getString("label.structure_options")));
1354     structureTab.setLayout(null);
1355     final int width = 400;
1356     final int height = 22;
1357     final int lineSpacing = 25;
1358     int ypos = 15;
1359
1360     structFromPdb.setFont(LABEL_FONT);
1361     structFromPdb
1362             .setText(MessageManager.getString("label.struct_from_pdb"));
1363     structFromPdb.setBounds(new Rectangle(5, ypos, width, height));
1364     structFromPdb.addActionListener(new ActionListener()
1365     {
1366       @Override
1367       public void actionPerformed(ActionEvent e)
1368       {
1369         boolean selected = structFromPdb.isSelected();
1370         // enable other options only when the first is checked
1371         useRnaView.setEnabled(selected);
1372         addSecondaryStructure.setEnabled(selected);
1373         addTempFactor.setEnabled(selected);
1374       }
1375     });
1376     structureTab.add(structFromPdb);
1377
1378     // indent checkboxes that are conditional on the first one
1379     ypos += lineSpacing;
1380     useRnaView.setFont(LABEL_FONT);
1381     useRnaView.setText(MessageManager.getString("label.use_rnaview"));
1382     useRnaView.setBounds(new Rectangle(25, ypos, width, height));
1383     structureTab.add(useRnaView);
1384
1385     ypos += lineSpacing;
1386     addSecondaryStructure.setFont(LABEL_FONT);
1387     addSecondaryStructure
1388             .setText(MessageManager.getString("label.autoadd_secstr"));
1389     addSecondaryStructure.setBounds(new Rectangle(25, ypos, width, height));
1390     structureTab.add(addSecondaryStructure);
1391
1392     ypos += lineSpacing;
1393     addTempFactor.setFont(LABEL_FONT);
1394     addTempFactor.setText(MessageManager.getString("label.autoadd_temp"));
1395     addTempFactor.setBounds(new Rectangle(25, ypos, width, height));
1396     structureTab.add(addTempFactor);
1397
1398     ypos += lineSpacing;
1399     JLabel viewerLabel = new JLabel();
1400     viewerLabel.setFont(LABEL_FONT);
1401     viewerLabel.setHorizontalAlignment(SwingConstants.LEFT);
1402     viewerLabel.setText(MessageManager.getString("label.structure_viewer"));
1403     viewerLabel.setBounds(new Rectangle(10, ypos, 200, height));
1404     structureTab.add(viewerLabel);
1405
1406     structViewer.setFont(LABEL_FONT);
1407     structViewer.setBounds(new Rectangle(160, ypos, 120, height));
1408     structViewer.addItem(ViewerType.JMOL.name());
1409     structViewer.addItem(ViewerType.CHIMERA.name());
1410     structViewer.addActionListener(new ActionListener()
1411     {
1412       @Override
1413       public void actionPerformed(ActionEvent e)
1414       {
1415         structureViewer_actionPerformed(
1416                 (String) structViewer.getSelectedItem());
1417       }
1418     });
1419     structureTab.add(structViewer);
1420
1421     ypos += lineSpacing;
1422     JLabel pathLabel = new JLabel();
1423     pathLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
1424     pathLabel.setHorizontalAlignment(SwingConstants.LEFT);
1425     pathLabel.setText(MessageManager.getString("label.chimera_path"));
1426     pathLabel.setBounds(new Rectangle(10, ypos, 140, height));
1427     structureTab.add(pathLabel);
1428
1429     chimeraPath.setFont(LABEL_FONT);
1430     chimeraPath.setText("");
1431     final String tooltip = JvSwingUtils.wrapTooltip(true,
1432             MessageManager.getString("label.chimera_path_tip"));
1433     chimeraPath.setToolTipText(tooltip);
1434     chimeraPath.setBounds(new Rectangle(160, ypos, 300, height));
1435     chimeraPath.addMouseListener(new MouseAdapter()
1436     {
1437       @Override
1438       public void mouseClicked(MouseEvent e)
1439       {
1440         if (e.getClickCount() == 2)
1441         {
1442           String chosen = openFileChooser(false);
1443           if (chosen != null)
1444           {
1445             chimeraPath.setText(chosen);
1446           }
1447         }
1448       }
1449     });
1450     structureTab.add(chimeraPath);
1451
1452     ypos += lineSpacing;
1453     nwMapping.setFont(LABEL_FONT);
1454     nwMapping.setText(MessageManager.getString("label.nw_mapping"));
1455     siftsMapping.setFont(LABEL_FONT);
1456     siftsMapping.setText(MessageManager.getString("label.sifts_mapping"));
1457     mappingMethod.add(nwMapping);
1458     mappingMethod.add(siftsMapping);
1459     JPanel mappingPanel = new JPanel();
1460     mappingPanel.setFont(LABEL_FONT);
1461     TitledBorder mmTitledBorder = new TitledBorder(
1462             MessageManager.getString("label.mapping_method"));
1463     mmTitledBorder.setTitleFont(LABEL_FONT);
1464     mappingPanel.setBorder(mmTitledBorder);
1465     mappingPanel.setBounds(new Rectangle(10, ypos, 452, 45));
1466     // GridLayout mappingLayout = new GridLayout();
1467     mappingPanel.setLayout(new GridLayout());
1468     mappingPanel.add(nwMapping);
1469     mappingPanel.add(siftsMapping);
1470     structureTab.add(mappingPanel);
1471
1472     ypos += lineSpacing;
1473     ypos += lineSpacing;
1474     FTSDataColumnPreferences docFieldPref = new FTSDataColumnPreferences(
1475             PreferenceSource.PREFERENCES, PDBFTSRestClient.getInstance());
1476     docFieldPref.setBounds(new Rectangle(10, ypos, 450, 120));
1477     structureTab.add(docFieldPref);
1478
1479     return structureTab;
1480   }
1481
1482   /**
1483    * Action on choosing a structure viewer from combobox options.
1484    * 
1485    * @param selectedItem
1486    */
1487   protected void structureViewer_actionPerformed(String selectedItem)
1488   {
1489   }
1490
1491   /**
1492    * Show a dialog for the user to choose a file. Returns the chosen path, or
1493    * null on Cancel.
1494    * 
1495    * @return
1496    */
1497   protected String openFileChooser(boolean forFolder)
1498   {
1499     String choice = null;
1500     JFileChooser chooser = new JFileChooser();
1501     if (forFolder)
1502     {
1503       chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1504     }
1505
1506     // chooser.setFileView(new JalviewFileView());
1507     chooser.setDialogTitle(
1508             MessageManager.getString("label.open_local_file"));
1509     chooser.setToolTipText(MessageManager.getString("action.open"));
1510
1511     int value = chooser.showOpenDialog(this);
1512
1513     if (value == JFileChooser.APPROVE_OPTION)
1514     {
1515       choice = chooser.getSelectedFile().getPath();
1516     }
1517     return choice;
1518   }
1519
1520   protected boolean validateStructure()
1521   {
1522     return false;
1523   }
1524
1525   /**
1526    * Initialises the Visual tabbed panel.
1527    * 
1528    * @return
1529    */
1530   private JPanel initVisualTab()
1531   {
1532     JPanel visualTab = new JPanel();
1533     visualTab.setBorder(new TitledBorder(
1534             MessageManager.getString("action.open_new_alignment")));
1535     visualTab.setLayout(null);
1536     fullScreen.setFont(LABEL_FONT);
1537     fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);
1538     fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);
1539     fullScreen.setText(MessageManager.getString("label.maximize_window"));
1540     quality.setEnabled(false);
1541     quality.setFont(LABEL_FONT);
1542     quality.setHorizontalAlignment(SwingConstants.RIGHT);
1543     quality.setHorizontalTextPosition(SwingConstants.LEFT);
1544     quality.setSelected(true);
1545     quality.setText(MessageManager.getString("label.quality"));
1546     conservation.setEnabled(false);
1547     conservation.setFont(LABEL_FONT);
1548     conservation.setHorizontalAlignment(SwingConstants.RIGHT);
1549     conservation.setHorizontalTextPosition(SwingConstants.LEFT);
1550     conservation.setSelected(true);
1551     conservation.setText(MessageManager.getString("label.conservation"));
1552     identity.setEnabled(false);
1553     identity.setFont(LABEL_FONT);
1554     identity.setHorizontalAlignment(SwingConstants.RIGHT);
1555     identity.setHorizontalTextPosition(SwingConstants.LEFT);
1556     identity.setSelected(true);
1557     identity.setText(MessageManager.getString("label.consensus"));
1558     showOccupancy.setFont(LABEL_FONT);
1559     showOccupancy.setEnabled(false);
1560     showOccupancy.setHorizontalAlignment(SwingConstants.RIGHT);
1561     showOccupancy.setHorizontalTextPosition(SwingConstants.LEFT);
1562     showOccupancy.setSelected(true);
1563     showOccupancy.setText(MessageManager.getString("label.occupancy"));
1564
1565     JLabel showGroupbits = new JLabel();
1566     showGroupbits.setFont(LABEL_FONT);
1567     showGroupbits.setHorizontalAlignment(SwingConstants.RIGHT);
1568     showGroupbits.setHorizontalTextPosition(SwingConstants.LEFT);
1569     showGroupbits
1570             .setText(MessageManager.getString("action.show_group") + ":");
1571     JLabel showConsensbits = new JLabel();
1572     showConsensbits.setFont(LABEL_FONT);
1573     showConsensbits.setHorizontalAlignment(SwingConstants.RIGHT);
1574     showConsensbits.setHorizontalTextPosition(SwingConstants.LEFT);
1575     showConsensbits
1576             .setText(MessageManager.getString("label.consensus") + ":");
1577     showConsensHistogram.setEnabled(false);
1578     showConsensHistogram.setFont(LABEL_FONT);
1579     showConsensHistogram.setHorizontalAlignment(SwingConstants.RIGHT);
1580     showConsensHistogram.setHorizontalTextPosition(SwingConstants.LEFT);
1581     showConsensHistogram.setSelected(true);
1582     showConsensHistogram
1583             .setText(MessageManager.getString("label.histogram"));
1584     showConsensLogo.setEnabled(false);
1585     showConsensLogo.setFont(LABEL_FONT);
1586     showConsensLogo.setHorizontalAlignment(SwingConstants.RIGHT);
1587     showConsensLogo.setHorizontalTextPosition(SwingConstants.LEFT);
1588     showConsensLogo.setSelected(true);
1589     showConsensLogo.setText(MessageManager.getString("label.logo"));
1590     showGroupConsensus.setEnabled(false);
1591     showGroupConsensus.setFont(LABEL_FONT);
1592     showGroupConsensus.setHorizontalAlignment(SwingConstants.RIGHT);
1593     showGroupConsensus.setHorizontalTextPosition(SwingConstants.LEFT);
1594     showGroupConsensus.setSelected(true);
1595     showGroupConsensus.setText(MessageManager.getString("label.consensus"));
1596     showGroupConservation.setEnabled(false);
1597     showGroupConservation.setFont(LABEL_FONT);
1598     showGroupConservation.setHorizontalAlignment(SwingConstants.RIGHT);
1599     showGroupConservation.setHorizontalTextPosition(SwingConstants.LEFT);
1600     showGroupConservation.setSelected(true);
1601     showGroupConservation
1602             .setText(MessageManager.getString("label.conservation"));
1603     showNpTooltip.setEnabled(true);
1604     showNpTooltip.setFont(LABEL_FONT);
1605     showNpTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
1606     showNpTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
1607     showNpTooltip.setSelected(true);
1608     showNpTooltip.setText(
1609             MessageManager.getString("label.non_positional_features"));
1610     showDbRefTooltip.setEnabled(true);
1611     showDbRefTooltip.setFont(LABEL_FONT);
1612     showDbRefTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
1613     showDbRefTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
1614     showDbRefTooltip.setSelected(true);
1615     showDbRefTooltip
1616             .setText(MessageManager.getString("label.database_references"));
1617     annotations.setFont(LABEL_FONT);
1618     annotations.setHorizontalAlignment(SwingConstants.RIGHT);
1619     annotations.setHorizontalTextPosition(SwingConstants.LEFT);
1620     annotations.setSelected(true);
1621     annotations.setText(MessageManager.getString("label.show_annotations"));
1622     // annotations.setBounds(new Rectangle(169, 12, 200, 23));
1623     annotations.addActionListener(new ActionListener()
1624     {
1625       @Override
1626       public void actionPerformed(ActionEvent e)
1627       {
1628         annotations_actionPerformed(e);
1629       }
1630     });
1631     identity.addActionListener(new ActionListener()
1632     {
1633       @Override
1634       public void actionPerformed(ActionEvent e)
1635       {
1636         annotations_actionPerformed(e);
1637       }
1638     });
1639     showGroupConsensus.addActionListener(new ActionListener()
1640     {
1641       @Override
1642       public void actionPerformed(ActionEvent e)
1643       {
1644         annotations_actionPerformed(e);
1645       }
1646     });
1647     showUnconserved.setFont(LABEL_FONT);
1648     showUnconserved.setHorizontalAlignment(SwingConstants.RIGHT);
1649     showUnconserved.setHorizontalTextPosition(SwingConstants.LEFT);
1650     showUnconserved.setSelected(true);
1651     showUnconserved
1652             .setText(MessageManager.getString("action.show_unconserved"));
1653     showUnconserved.addActionListener(new ActionListener()
1654     {
1655       @Override
1656       public void actionPerformed(ActionEvent e)
1657       {
1658         showunconserved_actionPerformed(e);
1659       }
1660     });
1661
1662     // TODO these are not yet added to / action from Preferences
1663     // JCheckBox shareSelections = new JCheckBox();
1664     // shareSelections.setFont(verdana11);
1665     // shareSelections.setHorizontalAlignment(SwingConstants.RIGHT);
1666     // shareSelections.setHorizontalTextPosition(SwingConstants.LEFT);
1667     // shareSelections.setSelected(true);
1668     // shareSelections.setText(MessageManager
1669     // .getString("label.share_selection_across_views"));
1670     // JCheckBox followHighlight = new JCheckBox();
1671     // followHighlight.setFont(verdana11);
1672     // followHighlight.setHorizontalAlignment(SwingConstants.RIGHT);
1673     // followHighlight.setHorizontalTextPosition(SwingConstants.LEFT);
1674     // // showUnconserved.setBounds(new Rectangle(169, 40, 200, 23));
1675     // followHighlight.setSelected(true);
1676     // followHighlight.setText(MessageManager
1677     // .getString("label.scroll_highlighted_regions"));
1678
1679     seqLimit.setFont(LABEL_FONT);
1680     seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);
1681     seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);
1682     seqLimit.setText(MessageManager.getString("label.full_sequence_id"));
1683     smoothFont.setFont(LABEL_FONT);
1684     smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);
1685     smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);
1686     smoothFont.setText(MessageManager.getString("label.smooth_font"));
1687     scaleProteinToCdna.setFont(LABEL_FONT);
1688     scaleProteinToCdna.setHorizontalAlignment(SwingConstants.RIGHT);
1689     scaleProteinToCdna.setHorizontalTextPosition(SwingConstants.LEADING);
1690     scaleProteinToCdna.setText(
1691             MessageManager.getString("label.scale_protein_to_cdna"));
1692     scaleProteinToCdna.setToolTipText(
1693             MessageManager.getString("label.scale_protein_to_cdna_tip"));
1694     JLabel gapLabel = new JLabel();
1695     gapLabel.setFont(LABEL_FONT);
1696     gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1697     gapLabel.setText(MessageManager.getString("label.gap_symbol") + " ");
1698     JLabel fontLabel = new JLabel();
1699     fontLabel.setFont(LABEL_FONT);
1700     fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1701     fontLabel.setText(MessageManager.getString("label.font"));
1702     fontSizeCB.setFont(LABEL_FONT);
1703     fontSizeCB.setBounds(new Rectangle(320, 112, 65, 23));
1704     fontStyleCB.setFont(LABEL_FONT);
1705     fontStyleCB.setBounds(new Rectangle(382, 112, 80, 23));
1706     fontNameCB.setFont(LABEL_FONT);
1707     fontNameCB.setBounds(new Rectangle(172, 112, 147, 23));
1708     gapSymbolCB.setFont(LABEL_FONT);
1709     gapSymbolCB.setBounds(new Rectangle(172, 215, 69, 23));
1710     DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
1711     dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
1712     gapSymbolCB.setRenderer(dlcr);
1713
1714     startupCheckbox.setText(MessageManager.getString("action.open_file"));
1715     startupCheckbox.setFont(LABEL_FONT);
1716     startupCheckbox.setHorizontalAlignment(SwingConstants.RIGHT);
1717     startupCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
1718     startupCheckbox.setSelected(true);
1719     startupFileTextfield.setFont(LABEL_FONT);
1720     startupFileTextfield.setBounds(new Rectangle(172, 310, 330, 20));
1721     final String tooltip = JvSwingUtils.wrapTooltip(true,
1722             MessageManager.getString("label.double_click_to_browse"));
1723     startupFileTextfield.setToolTipText(tooltip);
1724     startupFileTextfield.addMouseListener(new MouseAdapter()
1725     {
1726       @Override
1727       public void mouseClicked(MouseEvent e)
1728       {
1729         if (e.getClickCount() > 1)
1730         {
1731           startupFileTextfield_mouseClicked();
1732         }
1733       }
1734     });
1735
1736     sortby.setFont(LABEL_FONT);
1737     sortby.setBounds(new Rectangle(172, 260, 155, 21));
1738     JLabel sortLabel = new JLabel();
1739     sortLabel.setFont(LABEL_FONT);
1740     sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1741     sortLabel.setText(MessageManager.getString("label.sort_by"));
1742     sortAnnBy.setFont(LABEL_FONT);
1743     sortAnnBy.setBounds(new Rectangle(172, 285, 110, 21));
1744     JLabel sortAnnLabel = new JLabel();
1745     sortAnnLabel.setFont(LABEL_FONT);
1746     sortAnnLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1747     sortAnnLabel.setText(MessageManager.getString("label.sort_ann_by"));
1748     sortAutocalc.setFont(LABEL_FONT);
1749     sortAutocalc.setBounds(new Rectangle(290, 285, 165, 21));
1750
1751     JPanel annsettingsPanel = new JPanel();
1752     annsettingsPanel.setBounds(new Rectangle(173, 13, 320, 96));
1753     annsettingsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
1754     annsettingsPanel.setBorder(new EtchedBorder());
1755     visualTab.add(annsettingsPanel);
1756     Border jb = new EmptyBorder(1, 1, 4, 5);
1757     annotations.setBorder(jb);
1758     showOccupancy.setBorder(jb);
1759     quality.setBorder(jb);
1760     conservation.setBorder(jb);
1761     identity.setBorder(jb);
1762     showConsensbits.setBorder(jb);
1763     showGroupbits.setBorder(jb);
1764     showGroupConsensus.setBorder(jb);
1765     showGroupConservation.setBorder(jb);
1766     showConsensHistogram.setBorder(jb);
1767     showConsensLogo.setBorder(jb);
1768
1769     JPanel autoAnnotSettings = new JPanel();
1770     annsettingsPanel.add(autoAnnotSettings);
1771     autoAnnotSettings.setLayout(new GridLayout(0, 2));
1772     autoAnnotSettings.add(annotations);
1773     autoAnnotSettings.add(quality);
1774     // second row of autoannotation box
1775     autoAnnotSettings = new JPanel();
1776     annsettingsPanel.add(autoAnnotSettings);
1777
1778     autoAnnotSettings.setLayout(new GridLayout(0, 3));
1779     autoAnnotSettings.add(conservation);
1780     autoAnnotSettings.add(identity);
1781     autoAnnotSettings.add(showOccupancy);
1782     autoAnnotSettings.add(showGroupbits);
1783     autoAnnotSettings.add(showGroupConservation);
1784     autoAnnotSettings.add(showGroupConsensus);
1785     autoAnnotSettings.add(showConsensbits);
1786     autoAnnotSettings.add(showConsensHistogram);
1787     autoAnnotSettings.add(showConsensLogo);
1788
1789     JPanel tooltipSettings = new JPanel();
1790     tooltipSettings.setBorder(new TitledBorder(
1791             MessageManager.getString("label.sequence_id_tooltip")));
1792     tooltipSettings.setBounds(173, 140, 220, 62);
1793     tooltipSettings.setLayout(new GridLayout(2, 1));
1794     tooltipSettings.add(showDbRefTooltip);
1795     tooltipSettings.add(showNpTooltip);
1796     visualTab.add(tooltipSettings);
1797
1798     wrap.setFont(LABEL_FONT);
1799     wrap.setHorizontalAlignment(SwingConstants.TRAILING);
1800     wrap.setHorizontalTextPosition(SwingConstants.LEADING);
1801     wrap.setText(MessageManager.getString("label.wrap_alignment"));
1802     rightAlign.setFont(LABEL_FONT);
1803     rightAlign.setForeground(Color.black);
1804     rightAlign.setHorizontalAlignment(SwingConstants.RIGHT);
1805     rightAlign.setHorizontalTextPosition(SwingConstants.LEFT);
1806     rightAlign.setText(MessageManager.getString("label.right_align_ids"));
1807     idItalics.setFont(LABEL_FONT_ITALIC);
1808     idItalics.setHorizontalAlignment(SwingConstants.RIGHT);
1809     idItalics.setHorizontalTextPosition(SwingConstants.LEADING);
1810     idItalics.setText(
1811             MessageManager.getString("label.sequence_name_italics"));
1812     openoverv.setFont(LABEL_FONT);
1813     openoverv.setActionCommand(
1814             MessageManager.getString("label.open_overview"));
1815     openoverv.setHorizontalAlignment(SwingConstants.RIGHT);
1816     openoverv.setHorizontalTextPosition(SwingConstants.LEFT);
1817     openoverv.setText(MessageManager.getString("label.open_overview"));
1818     JPanel jPanel2 = new JPanel();
1819     jPanel2.setBounds(new Rectangle(7, 17, 158, 310));
1820     jPanel2.setLayout(new GridLayout(14, 1));
1821     jPanel2.add(fullScreen);
1822     jPanel2.add(openoverv);
1823     jPanel2.add(seqLimit);
1824     jPanel2.add(rightAlign);
1825     jPanel2.add(fontLabel);
1826     jPanel2.add(showUnconserved);
1827     jPanel2.add(idItalics);
1828     jPanel2.add(smoothFont);
1829     jPanel2.add(scaleProteinToCdna);
1830     jPanel2.add(gapLabel);
1831     jPanel2.add(wrap);
1832     jPanel2.add(sortLabel);
1833     jPanel2.add(sortAnnLabel);
1834     jPanel2.add(startupCheckbox);
1835     visualTab.add(jPanel2);
1836     visualTab.add(startupFileTextfield);
1837     visualTab.add(sortby);
1838     visualTab.add(sortAnnBy);
1839     visualTab.add(sortAutocalc);
1840     visualTab.add(gapSymbolCB);
1841     visualTab.add(fontNameCB);
1842     visualTab.add(fontSizeCB);
1843     visualTab.add(fontStyleCB);
1844     return visualTab;
1845   }
1846
1847   /**
1848    * Load the saved Backups options EXCEPT "Enabled" and "Scheme"
1849    */
1850
1851   protected void loadLastSavedBackupsOptions()
1852   {
1853     BackupFilesPresetEntry savedPreset = BackupFilesPresetEntry
1854             .getSavedBackupEntry();
1855     enableBackupFiles
1856             .setSelected(Cache.getDefault(BackupFiles.ENABLED, true));
1857
1858     BackupFilesPresetEntry backupfilesCustomEntry = BackupFilesPresetEntry
1859             .createBackupFilesPresetEntry(Cache
1860                     .getDefault(BackupFilesPresetEntry.CUSTOMCONFIG, null));
1861     if (backupfilesCustomEntry == null)
1862     {
1863       backupfilesCustomEntry = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1864               .get(BackupFilesPresetEntry.BACKUPFILESSCHEMEDEFAULT);
1865     }
1866     BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
1867             BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM,
1868             backupfilesCustomEntry);
1869
1870     setComboIntStringKey(backupfilesPresetsCombo,
1871             Cache.getDefault(BackupFiles.NS + "_PRESET",
1872                     BackupFilesPresetEntry.BACKUPFILESSCHEMEDEFAULT));
1873
1874     backupsSetOptions(savedPreset);
1875
1876     backupsOptionsSetEnabled();
1877     updateBackupFilesExampleLabel();
1878   }
1879
1880   private boolean warnAboutSuffixReverseChange()
1881   {
1882     BackupFilesPresetEntry bfpe = BackupFilesPresetEntry
1883             .getSavedBackupEntry();
1884     boolean savedSuffixReverse = bfpe.reverse;
1885     int savedSuffixDigits = bfpe.digits;
1886     String savedSuffixTemplate = bfpe.suffix;
1887
1888     boolean nowSuffixReverse = suffixReverse.isSelected();
1889     int nowSuffixDigits = getSpinnerInt(suffixDigitsSpinner, 3);
1890     String nowSuffixTemplate = suffixTemplate.getText();
1891     return nowSuffixReverse != savedSuffixReverse
1892             && nowSuffixDigits == savedSuffixDigits
1893             && nowSuffixTemplate != null
1894             && nowSuffixTemplate.equals(savedSuffixTemplate);
1895   }
1896
1897   /**
1898    * Initialises the Backups tabbed panel.
1899    * 
1900    * @return
1901    */
1902   private JPanel initBackupsTab()
1903   {
1904     JPanel backupsTab = new JPanel();
1905     backupsTab.setBorder(new TitledBorder(
1906             MessageManager.getString("label.backup_files")));
1907     backupsTab.setLayout(new GridBagLayout());
1908
1909     GridBagConstraints gbc = new GridBagConstraints();
1910     gbc.weightx = 0.0;
1911     gbc.weighty = 0.0;
1912     gbc.anchor = GridBagConstraints.FIRST_LINE_START;
1913     gbc.fill = GridBagConstraints.NONE;
1914
1915     initBackupsTabPresetsPanel();
1916     initBackupsTabSuffixPanel();
1917     initBackupsTabKeepFilesPanel();
1918     initBackupsTabFilenameExamplesPanel();
1919
1920     enableBackupFiles.setFont(LABEL_FONT_BOLD);
1921     enableBackupFiles
1922             .setText(MessageManager.getString("label.enable_backupfiles"));
1923     enableBackupFiles.addActionListener(new ActionListener()
1924     {
1925       @Override
1926       public void actionPerformed(ActionEvent e)
1927       {
1928         // enable other options only when the first is checked
1929         backupsOptionsSetEnabled();
1930       }
1931     });
1932
1933
1934     // enable checkbox 1 col
1935     gbc.gridwidth = 1;
1936     gbc.gridheight = 1;
1937     gbc.gridx = 0;
1938     gbc.gridy = 0; // row 0
1939     backupsTab.add(enableBackupFiles, gbc);
1940
1941     // summary of scheme box (over two rows)
1942     gbc.gridx = 1;
1943     gbc.weightx = 0.0;
1944     gbc.gridheight = 2;
1945     gbc.anchor = GridBagConstraints.FIRST_LINE_END;
1946     gbc.fill = GridBagConstraints.BOTH;
1947     backupsTab.add(exampleFilesPanel, gbc);
1948     gbc.gridheight = 1;
1949     gbc.anchor = GridBagConstraints.FIRST_LINE_START;
1950     gbc.fill = GridBagConstraints.NONE;
1951
1952     // fill empty space on right
1953     gbc.gridx++;
1954     gbc.weightx = 1.0;
1955     backupsTab.add(new JPanel(), gbc);
1956
1957     // schemes box
1958     gbc.weightx = 0.0;
1959     gbc.gridx = 0;
1960     gbc.gridy++; // row 1
1961     backupsTab.add(presetsPanel, gbc);
1962
1963     // now using whole row
1964     gbc.gridwidth = 2;
1965     gbc.gridheight = 1;
1966     // keep files box
1967     gbc.gridx = 0;
1968     gbc.gridy++; // row 2
1969     backupsTab.add(keepfilesPanel, gbc);
1970
1971     // filename strategy box
1972     gbc.gridy++; // row 3
1973     backupsTab.add(suffixPanel, gbc);
1974
1975     // fill empty space
1976     gbc.gridy++; // row 4
1977     gbc.weighty = 1.0;
1978     backupsTab.add(new JPanel(), gbc);
1979
1980     backupsOptionsSetEnabled();
1981     return backupsTab;
1982   }
1983
1984   private JPanel initBackupsTabPresetsPanel()
1985   {
1986
1987     String title = MessageManager.getString("label.schemes");
1988
1989     presetsPanel.setLayout(new GridBagLayout());
1990
1991     GridBagConstraints gbc = new GridBagConstraints();
1992     gbc.weightx = 0.0;
1993     gbc.weighty = 0.0;
1994     gbc.anchor = GridBagConstraints.BASELINE_LEADING;
1995     gbc.fill = GridBagConstraints.NONE;
1996     gbc.gridwidth = 1;
1997     gbc.gridheight = 1;
1998
1999     // "Scheme: "
2000     gbc.gridx = 0;
2001     gbc.gridy = 0;
2002
2003     presetsComboLabel = new JLabel(title + ":");
2004     presetsPanel.add(presetsComboLabel, gbc);
2005
2006     List<Object> entries = Arrays
2007             .asList((Object[]) BackupFilesPresetEntry.backupfilesPresetEntries);
2008     List<String> tooltips = Arrays.asList(
2009             BackupFilesPresetEntry.backupfilesPresetEntryDescriptions);
2010     backupfilesPresetsCombo = JvSwingUtils.buildComboWithTooltips(entries,
2011             tooltips);
2012     /*
2013     for (int i = 0; i < BackupFilesPresetEntry.backupfilesPresetEntries.length; i++)
2014     {
2015       backupfilesPresetsCombo
2016               .addItem(BackupFilesPresetEntry.backupfilesPresetEntries[i]);
2017     }
2018     */
2019
2020     backupfilesPresetsCombo.addActionListener(new ActionListener()
2021     {
2022       @Override
2023       public void actionPerformed(ActionEvent e)
2024       {
2025         int key = getComboIntStringKey(backupfilesPresetsCombo);
2026         if (!customiseCheckbox.isSelected())
2027         {
2028           backupfilesPresetsComboLastSelected = key;
2029         }
2030         if (key == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
2031         {
2032           if (customiseCheckbox.isSelected())
2033           {
2034             // got here by clicking on customiseCheckbox so don't change the values
2035             backupfilesCustomOptionsSetEnabled();
2036           }
2037           else
2038           {
2039             backupsTabUpdatePresets();
2040             backupfilesCustomOptionsSetEnabled();
2041           }
2042         }
2043         else
2044         {
2045           customiseCheckbox.setSelected(false);
2046           backupsTabUpdatePresets();
2047           backupfilesCustomOptionsSetEnabled();
2048         }
2049       }
2050     });
2051
2052     // dropdown list of preset schemes
2053     gbc.gridx = 1;
2054     presetsPanel.add(backupfilesPresetsCombo, gbc);
2055
2056     revertButton.setText(MessageManager.getString("label.cancel_changes"));
2057     revertButton.setToolTipText(
2058             MessageManager.getString("label.cancel_changes_description"));
2059     revertButton.addActionListener(new ActionListener()
2060     {
2061       @Override
2062       public void actionPerformed(ActionEvent e)
2063       {
2064         backupsSetOptions(
2065                 BackupFilesPresetEntry.backupfilesPresetEntriesValues.get(
2066                         BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM));
2067         backupfilesCustomOptionsSetEnabled();
2068       }
2069
2070     });
2071     revertButton.setFont(LABEL_FONT);
2072
2073     customiseCheckbox.setFont(LABEL_FONT);
2074     customiseCheckbox.setText(MessageManager.getString("label.customise"));
2075     customiseCheckbox.addActionListener(new ActionListener()
2076     {
2077       @Override
2078       public void actionPerformed(ActionEvent e)
2079       {
2080         int currently = getComboIntStringKey(backupfilesPresetsCombo);
2081         if (customiseCheckbox.isSelected())
2082         {
2083           backupfilesPresetsComboLastSelected = currently;
2084           setComboIntStringKey(backupfilesPresetsCombo,
2085                   BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM);
2086         }
2087         else
2088         {
2089           setComboIntStringKey(backupfilesPresetsCombo,
2090                   backupfilesPresetsComboLastSelected);
2091
2092         }
2093         backupfilesCustomOptionsSetEnabled();
2094       }
2095     });
2096     customiseCheckbox.setToolTipText(
2097             MessageManager.getString("label.customise_description"));
2098
2099     // customise checkbox
2100     gbc.gridx = 0;
2101     gbc.gridy++;
2102     presetsPanel.add(customiseCheckbox, gbc);
2103
2104     // "Cancel changes" button (aligned with combo box above)
2105     gbc.gridx = 1;
2106     presetsPanel.add(revertButton, gbc);
2107
2108     return presetsPanel;
2109   }
2110
2111   private JPanel initBackupsTabFilenameExamplesPanel()
2112   {
2113     String title = MessageManager
2114             .getString("label.scheme_examples");
2115     TitledBorder tb = new TitledBorder(title);
2116     exampleFilesPanel.setBorder(tb);
2117     exampleFilesPanel.setLayout(new GridBagLayout());
2118
2119
2120     backupfilesExampleLabel.setEditable(false);
2121     backupfilesExampleLabel
2122             .setBackground(exampleFilesPanel.getBackground());
2123
2124     updateBackupFilesExampleLabel();
2125
2126     GridBagConstraints gbc = new GridBagConstraints();
2127     gbc.weightx = 1.0;
2128     gbc.weighty = 1.0;
2129     gbc.fill = GridBagConstraints.NONE;
2130     gbc.anchor = GridBagConstraints.FIRST_LINE_START;
2131
2132     exampleFilesPanel.add(backupfilesExampleLabel, gbc);
2133     return exampleFilesPanel;
2134   }
2135
2136   private void backupsTabUpdatePresets()
2137   {
2138     IntKeyStringValueEntry entry = (IntKeyStringValueEntry) backupfilesPresetsCombo
2139             .getSelectedItem();
2140     int key = entry.k;
2141     String value = entry.v;
2142
2143     if (BackupFilesPresetEntry.backupfilesPresetEntriesValues
2144             .containsKey(key))
2145     {
2146       backupsSetOptions(
2147               BackupFilesPresetEntry.backupfilesPresetEntriesValues
2148                       .get(key));
2149     }
2150     else
2151     {
2152       Cache.log.error(
2153               "Preset '" + value + "' [key:" + key + "] not implemented");
2154     }
2155
2156     // Custom options will now be enabled when the customiseCheckbox is checked
2157     // (performed above)
2158     // backupfilesCustomOptionsSetEnabled();
2159     updateBackupFilesExampleLabel();
2160   }
2161
2162   protected int getComboIntStringKey(
2163           JComboBox<Object> backupfilesPresetsCombo2)
2164   {
2165     IntKeyStringValueEntry e;
2166     try
2167     {
2168       e = (IntKeyStringValueEntry) backupfilesPresetsCombo2
2169               .getSelectedItem();
2170     } catch (Exception ex)
2171     {
2172       Cache.log.error(
2173               "Problem casting Combo entry to IntKeyStringValueEntry.");
2174       e = null;
2175     }
2176     return e != null ? e.k : 0;
2177   }
2178
2179   protected void setComboIntStringKey(
2180           JComboBox<Object> backupfilesPresetsCombo2,
2181           int key)
2182   {
2183     for (int i = 0; i < backupfilesPresetsCombo2.getItemCount(); i++)
2184     {
2185       IntKeyStringValueEntry e;
2186       try
2187       {
2188         e = (IntKeyStringValueEntry) backupfilesPresetsCombo2.getItemAt(i);
2189       } catch (Exception ex)
2190       {
2191         Cache.log.error(
2192                 "Problem casting Combo entry to IntKeyStringValueEntry. Skipping item. ");
2193         continue;
2194       }
2195       if (e.k == key)
2196       {
2197         backupfilesPresetsCombo2.setSelectedIndex(i);
2198         break;
2199       }
2200     }
2201     // backupsTabUpdatePresets();
2202   }
2203
2204   private JPanel initBackupsTabSuffixPanel()
2205   {
2206     suffixPanel.setBorder(new TitledBorder(
2207             MessageManager.getString("label.backup_filename_strategy")));
2208     suffixPanel.setLayout(new GridBagLayout());
2209
2210     suffixTemplateLabel
2211             .setText(MessageManager.getString("label.append_to_filename"));
2212     suffixTemplateLabel.setHorizontalAlignment(SwingConstants.LEFT);
2213     suffixTemplateLabel.setFont(LABEL_FONT);
2214
2215     final String tooltip = JvSwingUtils.wrapTooltip(true,
2216             MessageManager.getString("label.append_to_filename_tooltip"));
2217     suffixTemplate.setToolTipText(tooltip);
2218     suffixTemplate.addActionListener(new ActionListener()
2219     {
2220       @Override
2221       public void actionPerformed(ActionEvent e)
2222       {
2223         updateBackupFilesExampleLabel();
2224         backupfilesCustomOptionsSetEnabled();
2225         backupfilesRevertButtonSetEnabled(true);
2226       }
2227
2228     });
2229     suffixTemplate.addKeyListener(new KeyListener()
2230     {
2231       @Override
2232       public void keyReleased(KeyEvent e)
2233       {
2234         updateBackupFilesExampleLabel();
2235         backupfilesCustomOptionsSetEnabled();
2236         backupfilesRevertButtonSetEnabled(true);
2237       }
2238
2239       @Override
2240       public void keyPressed(KeyEvent e)
2241       {
2242       }
2243
2244       // disable use of ':' or '/' or '\'
2245       @Override
2246       public void keyTyped(KeyEvent e)
2247       {
2248         char c = e.getKeyChar();
2249         if (c == ':' || c == '/' || c == '\\')
2250         {
2251           // don't process ':' or '/' or '\'
2252           e.consume();
2253         }
2254       }
2255
2256     });
2257
2258     // digits spinner
2259     suffixDigitsLabel
2260             .setText(MessageManager.getString("label.index_digits"));
2261     suffixDigitsLabel.setHorizontalAlignment(SwingConstants.LEFT);
2262     suffixDigitsLabel.setFont(LABEL_FONT);
2263     ChangeListener c = new ChangeListener()
2264     {
2265       @Override
2266       public void stateChanged(ChangeEvent e)
2267       {
2268         backupfilesRevertButtonSetEnabled(true);
2269         updateBackupFilesExampleLabel();
2270       }
2271
2272     };
2273     setIntegerSpinner(suffixDigitsSpinner, BackupFilesPresetEntry.DIGITSMIN,
2274             BackupFilesPresetEntry.DIGITSMAX, 3, c);
2275
2276     suffixReverse.setLabels(MessageManager.getString("label.reverse_roll"),
2277             MessageManager.getString("label.increment_index"));
2278     suffixReverse.addActionListener(new ActionListener()
2279     {
2280       @Override
2281       public void actionPerformed(ActionEvent e)
2282       {
2283         boolean okay = true;
2284         if (warnAboutSuffixReverseChange())
2285         {
2286           // Warning popup
2287           okay = confirmSuffixReverseChange();
2288         }
2289         if (okay)
2290         {
2291           backupfilesRevertButtonSetEnabled(true);
2292           updateBackupFilesExampleLabel();
2293         }
2294         else
2295         {
2296           boolean savedSuffixReverse = BackupFilesPresetEntry
2297                   .getSavedBackupEntry().reverse;
2298           suffixReverse.setSelected(savedSuffixReverse);
2299         }
2300       }
2301     });
2302
2303     GridBagConstraints sgbc = new GridBagConstraints();
2304
2305     // first row (template text box)
2306     sgbc.anchor = GridBagConstraints.WEST;
2307     sgbc.gridx = 0;
2308     sgbc.gridy = 0;
2309     sgbc.gridwidth = 1;
2310     sgbc.gridheight = 1;
2311     sgbc.weightx = 1.0;
2312     sgbc.weighty = 0.0;
2313     sgbc.fill = GridBagConstraints.NONE;
2314     suffixPanel.add(suffixTemplateLabel, sgbc);
2315
2316     sgbc.gridx = 1;
2317     sgbc.fill = GridBagConstraints.HORIZONTAL;
2318     suffixPanel.add(suffixTemplate, sgbc);
2319
2320     // second row (number of digits spinner)
2321     sgbc.gridy = 1;
2322
2323     sgbc.gridx = 0;
2324     sgbc.fill = GridBagConstraints.NONE;
2325     suffixPanel.add(suffixDigitsLabel, sgbc);
2326
2327     sgbc.gridx = 1;
2328     sgbc.fill = GridBagConstraints.HORIZONTAL;
2329     suffixPanel.add(suffixDigitsSpinner, sgbc);
2330
2331     // third row (forward order radio selection)
2332     sgbc.gridx = 0;
2333     sgbc.gridy = 2;
2334     sgbc.gridwidth = GridBagConstraints.REMAINDER;
2335     sgbc.fill = GridBagConstraints.HORIZONTAL;
2336     suffixPanel.add(suffixReverse.getFalseButton(), sgbc);
2337
2338     // fourth row (reverse order radio selection)
2339     sgbc.gridy = 3;
2340     suffixPanel.add(suffixReverse.getTrueButton(), sgbc);
2341     return suffixPanel;
2342   }
2343
2344   private boolean confirmSuffixReverseChange()
2345   {
2346     boolean ret = false;
2347     String warningMessage = MessageManager
2348             .getString("label.warning_confirm_change_reverse");
2349     int confirm = JvOptionPane.showConfirmDialog(Desktop.desktop,
2350             warningMessage,
2351             MessageManager.getString("label.change_increment_decrement"),
2352             JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE);
2353
2354     ret = (confirm == JvOptionPane.YES_OPTION);
2355     return ret;
2356   }
2357
2358   private JPanel initBackupsTabKeepFilesPanel()
2359   {
2360     keepfilesPanel.setBorder(
2361             new TitledBorder(MessageManager.getString("label.keep_files")));
2362     keepfilesPanel.setLayout(new GridBagLayout());
2363
2364     backupfilesKeepAll.setLabels(
2365             MessageManager.getString("label.keep_all_backup_files"),
2366             MessageManager.getString(
2367                     "label.keep_only_this_number_of_backup_files"));
2368     backupfilesKeepAll.addTrueActionListener(new ActionListener()
2369     {
2370       @Override
2371       public void actionPerformed(ActionEvent e)
2372       {
2373         backupfilesRevertButtonSetEnabled(true);
2374         updateBackupFilesExampleLabel();
2375       }
2376     });
2377     backupfilesKeepAll.addActionListener(new ActionListener()
2378     {
2379       @Override
2380       public void actionPerformed(ActionEvent e)
2381       {
2382         backupfilesRevertButtonSetEnabled(true);
2383         keepRollMaxOptionsEnabled();
2384         updateBackupFilesExampleLabel();
2385       }
2386     });
2387
2388     ChangeListener c = new ChangeListener()
2389     {
2390       @Override
2391       public void stateChanged(ChangeEvent e)
2392       {
2393         backupfilesRevertButtonSetEnabled(true);
2394         updateBackupFilesExampleLabel();
2395       }
2396
2397     };
2398     setIntegerSpinner(backupfilesRollMaxSpinner,
2399             BackupFilesPresetEntry.ROLLMAXMIN,
2400             BackupFilesPresetEntry.ROLLMAXMAX, 4, true, c);
2401
2402     backupfilesConfirmDelete.setLabels(
2403             MessageManager.getString("label.always_ask"),
2404             MessageManager.getString("label.auto_delete"));
2405     backupfilesConfirmDelete.addActionListener(new ActionListener()
2406     {
2407       @Override
2408       public void actionPerformed(ActionEvent e)
2409       {
2410         backupfilesRevertButtonSetEnabled(true);
2411       }
2412     });
2413     // update the enabled section
2414     keepRollMaxOptionsEnabled();
2415
2416     GridBagConstraints kgbc = new GridBagConstraints();
2417
2418     // first row (template text box)
2419     kgbc.anchor = GridBagConstraints.WEST;
2420     kgbc.gridx = 0;
2421     kgbc.gridy = 0;
2422     kgbc.gridwidth = GridBagConstraints.REMAINDER;
2423     kgbc.gridheight = 1;
2424     kgbc.weightx = 1.0;
2425     kgbc.weighty = 0.0;
2426     kgbc.fill = GridBagConstraints.HORIZONTAL;
2427     keepfilesPanel.add(backupfilesKeepAll.getTrueButton(), kgbc);
2428
2429     // second row
2430     kgbc.gridy = 1;
2431
2432     kgbc.gridx = 0;
2433     kgbc.gridwidth = GridBagConstraints.RELATIVE;
2434     keepfilesPanel.add(backupfilesKeepAll.getFalseButton(), kgbc);
2435
2436     kgbc.gridx = 1;
2437     kgbc.gridwidth = GridBagConstraints.REMAINDER;
2438     keepfilesPanel.add(backupfilesRollMaxSpinner, kgbc);
2439
2440     // third row (indented)
2441     kgbc.gridy = 2;
2442     kgbc.insets = new Insets(0, 20, 0, 0);
2443
2444     kgbc.gridx = 0;
2445     kgbc.gridwidth = GridBagConstraints.REMAINDER;
2446     kgbc.fill = GridBagConstraints.HORIZONTAL;
2447     kgbc.weightx = 1.0;
2448
2449     JPanel jp = new JPanel();
2450     jp.setLayout(new FlowLayout());
2451     oldBackupFilesLabel
2452             .setText(MessageManager
2453                     .getString("label.autodelete_old_backup_files"));
2454     oldBackupFilesLabel.setFont(LABEL_FONT);
2455     oldBackupFilesLabel.setHorizontalAlignment(SwingConstants.LEFT);
2456     jp.add(oldBackupFilesLabel);
2457     jp.add(backupfilesConfirmDelete.getTrueButton());
2458     jp.add(backupfilesConfirmDelete.getFalseButton());
2459     keepfilesPanel.add(jp, kgbc);
2460
2461     return keepfilesPanel;
2462   }
2463
2464   protected void updateBackupFilesExampleLabel()
2465   {
2466     int exampleindex = 12;
2467     String base = MessageManager.getString("label.filename") + ".fa";
2468     if (base == null || base.length() == 0)
2469     {
2470       base = "file_name.fa";
2471     }
2472
2473     boolean reverse = suffixReverse.isSelected();
2474     boolean keepAll = backupfilesKeepAll.isSelected();
2475     int rollMax = 4;
2476     String suffix = suffixTemplate.getText();
2477     int digits = 3;
2478
2479     backupfilesExampleLabel.setFont(LABEL_FONT_ITALIC);
2480     if (suffix == null || suffix.length() == 0)
2481     {
2482       backupfilesExampleLabel
2483               .setText(MessageManager.getString("label.no_backup_files"));
2484       backupfilesExampleLabel.setFont(LABEL_FONT_BOLD);
2485       return;
2486     }
2487
2488     rollMax = getSpinnerInt(backupfilesRollMaxSpinner, 4);
2489     rollMax = rollMax < 1 ? 1 : rollMax;
2490
2491     if (suffix.indexOf(BackupFiles.NUM_PLACEHOLDER) == -1)
2492     {
2493       rollMax = 1;
2494     }
2495
2496     digits = getSpinnerInt(suffixDigitsSpinner, 3);
2497     digits = digits < 1 ? 1 : digits;
2498
2499     int lowersurround = 2;
2500     int uppersurround = 0;
2501     StringBuilder exampleSB = new StringBuilder();
2502     boolean firstLine = true;
2503     int lineNumber = 0;
2504     if (reverse)
2505     {
2506
2507       int min = 1;
2508       int max = keepAll ? exampleindex : rollMax;
2509       for (int index = min; index <= max; index++)
2510       {
2511         if (index == min + lowersurround && index < max - uppersurround - 1)
2512         {
2513           exampleSB.append("\n...");
2514           lineNumber++;
2515         }
2516         else if (index > min + lowersurround && index < max - uppersurround)
2517         {
2518           // nothing
2519         }
2520         else
2521         {
2522           if (firstLine)
2523           {
2524             firstLine = false;
2525           }
2526           else
2527           {
2528             exampleSB.append("\n");
2529             lineNumber++;
2530           }
2531           exampleSB.append(BackupFilenameParts.getBackupFilename(index,
2532                   base, suffix, digits));
2533           if (min == max)
2534           {
2535             // no extra text needed
2536           }
2537           else if (index == min)
2538           {
2539             String newest = MessageManager.getString("label.braced_newest");
2540             if (newest != null && newest.length() > 0)
2541             {
2542               exampleSB.append(" " + newest);
2543             }
2544           }
2545           else if (index == max)
2546           {
2547             String oldest = MessageManager.getString("label.braced_oldest");
2548             if (oldest != null && oldest.length() > 0)
2549             {
2550               exampleSB.append(" " + oldest);
2551             }
2552           }
2553         }
2554       }
2555     }
2556     else
2557     {
2558
2559       int min = (keepAll || exampleindex - rollMax < 0) ? 1
2560               : exampleindex - rollMax + 1;
2561       int max = exampleindex;
2562
2563       for (int index = min; index <= max; index++)
2564       {
2565
2566         if (index == min + lowersurround && index < max - uppersurround - 1)
2567         {
2568           exampleSB.append("\n...");
2569           lineNumber++;
2570         }
2571         else if (index > min + lowersurround && index < max - uppersurround)
2572         {
2573           // nothing
2574         }
2575         else
2576         {
2577           if (firstLine)
2578           {
2579             firstLine = false;
2580           }
2581           else
2582           {
2583             exampleSB.append("\n");
2584             lineNumber++;
2585           }
2586           exampleSB.append(BackupFilenameParts.getBackupFilename(index,
2587                   base, suffix, digits));
2588           if (min == max)
2589           {
2590             // no extra text needed
2591           }
2592           else if (index == min)
2593           {
2594             String oldest = MessageManager.getString("label.braced_oldest");
2595             if (oldest != null && oldest.length() > 0)
2596             {
2597               exampleSB.append(" " + oldest);
2598             }
2599           }
2600           else if (index == max)
2601           {
2602             String newest = MessageManager.getString("label.braced_newest");
2603             if (newest != null && newest.length() > 0)
2604             {
2605               exampleSB.append(" " + newest);
2606             }
2607           }
2608         }
2609       }
2610
2611     }
2612
2613     // add some extra empty lines to pad out the example files box. ugh, please tell
2614     // me how to do this better
2615     int remainingLines = lowersurround + uppersurround + 1 - lineNumber;
2616     if (remainingLines > 0)
2617     {
2618       for (int i = 0; i < remainingLines; i++)
2619       {
2620         exampleSB.append("\n ");
2621         lineNumber++;
2622       }
2623     }
2624
2625     backupfilesExampleLabel.setText(exampleSB.toString());
2626   }
2627
2628   protected void setIntegerSpinner(JSpinner s, int min, int max, int def,
2629           boolean useExistingVal, ChangeListener c)
2630   {
2631     int i = def;
2632     if (useExistingVal)
2633     {
2634       try
2635       {
2636         i = ((Integer) s.getValue()).intValue();
2637       } catch (Exception e)
2638       {
2639         Cache.log.error(
2640                 "Exception casting the initial value of s.getValue()");
2641       }
2642     }
2643
2644     setIntegerSpinner(s, min, max, i, c);
2645   }
2646
2647   protected void setIntegerSpinner(JSpinner s, int min, int max, int def,
2648           ChangeListener c)
2649   {
2650     // integer spinner for number of digits
2651     if (def > max)
2652     {
2653       max = def;
2654     }
2655     if (def < min)
2656     {
2657       def = min;
2658     }
2659     SpinnerModel sModel = new SpinnerNumberModel(def, min, max, 1);
2660     s.setModel(sModel);
2661
2662     s.addChangeListener(c);
2663
2664   }
2665
2666   protected static int getSpinnerInt(JSpinner s, int def)
2667   {
2668     int i = def;
2669     try
2670     {
2671       s.commitEdit();
2672       i = (Integer) s.getValue();
2673     } catch (Exception e)
2674     {
2675       Cache.log.error("Failed casting (Integer) JSpinner s.getValue()");
2676     }
2677     return i;
2678   }
2679
2680   private void keepRollMaxOptionsEnabled()
2681   {
2682     boolean enabled = backupfilesKeepAll.isEnabled()
2683             && !backupfilesKeepAll.isSelected();
2684     oldBackupFilesLabel.setEnabled(enabled);
2685     backupfilesRollMaxSpinner.setEnabled(enabled);
2686     backupfilesConfirmDelete.setEnabled(enabled);
2687   }
2688
2689   private void backupfilesKeepAllSetEnabled(boolean tryEnabled)
2690   {
2691     boolean enabled = tryEnabled && enableBackupFiles.isSelected()
2692             && customiseCheckbox.isSelected()
2693             && suffixTemplate.getText()
2694                     .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1;
2695     keepfilesPanel.setEnabled(enabled);
2696     backupfilesKeepAll.setEnabled(enabled);
2697     oldBackupFilesLabel.setEnabled(enabled);
2698     keepRollMaxOptionsEnabled();
2699   }
2700
2701   private void backupfilesSuffixTemplateDigitsSetEnabled()
2702   {
2703     boolean enabled = suffixTemplate.isEnabled() && suffixTemplate.getText()
2704             .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1;
2705     suffixDigitsLabel.setEnabled(enabled);
2706     suffixDigitsSpinner.setEnabled(enabled);
2707     suffixReverse.setEnabled(enabled);
2708   }
2709
2710   private void backupfilesSuffixTemplateSetEnabled(boolean tryEnabled)
2711   {
2712     boolean enabled = tryEnabled && enableBackupFiles.isSelected()
2713             && customiseCheckbox.isSelected();
2714     suffixPanel.setEnabled(enabled);
2715     suffixTemplateLabel.setEnabled(enabled);
2716     suffixTemplate.setEnabled(enabled);
2717     backupfilesSuffixTemplateDigitsSetEnabled();
2718   }
2719
2720   private void backupfilesRevertButtonSetEnabled(boolean tryEnabled)
2721   {
2722     boolean enabled = tryEnabled && enableBackupFiles.isSelected()
2723             && customiseCheckbox.isSelected() && backupfilesCustomChanged();
2724     revertButton.setEnabled(enabled);
2725   }
2726
2727   private boolean backupfilesCustomChanged()
2728   {
2729     BackupFilesPresetEntry custom = BackupFilesPresetEntry.backupfilesPresetEntriesValues
2730             .get(BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM);
2731     BackupFilesPresetEntry current = getBackupfilesCurrentEntry();
2732     return !custom.equals(current);
2733   }
2734
2735   protected BackupFilesPresetEntry getBackupfilesCurrentEntry()
2736   {
2737     String suffix = suffixTemplate.getText();
2738     int digits = getSpinnerInt(suffixDigitsSpinner, 3);
2739     boolean reverse = suffixReverse.isSelected();
2740     boolean keepAll = backupfilesKeepAll.isSelected();
2741     int rollMax = getSpinnerInt(backupfilesRollMaxSpinner, 3);
2742     boolean confirmDelete = backupfilesConfirmDelete.isSelected();
2743
2744     BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
2745             reverse, keepAll, rollMax, confirmDelete);
2746
2747     return bfpe;
2748   }
2749
2750   protected void backupfilesCustomOptionsSetEnabled()
2751   {
2752     boolean enabled = customiseCheckbox.isSelected();
2753
2754     backupfilesRevertButtonSetEnabled(enabled);
2755     backupfilesSuffixTemplateSetEnabled(enabled);
2756     backupfilesKeepAllSetEnabled(enabled);
2757   }
2758
2759   private void backupfilesSummarySetEnabled()
2760   {
2761     boolean enabled = enableBackupFiles.isSelected();
2762     backupfilesExampleLabel.setEnabled(enabled);
2763     exampleFilesPanel.setEnabled(enabled);
2764   }
2765
2766   private void backupfilesPresetsSetEnabled()
2767   {
2768     boolean enabled = enableBackupFiles.isSelected();
2769     presetsPanel.setEnabled(enabled);
2770     presetsComboLabel.setEnabled(enabled);
2771     backupfilesPresetsCombo.setEnabled(enabled);
2772     customiseCheckbox.setEnabled(enabled);
2773     revertButton.setEnabled(enabled);
2774   }
2775
2776   protected void backupsOptionsSetEnabled()
2777   {
2778     backupfilesPresetsSetEnabled();
2779     backupfilesSummarySetEnabled();
2780     backupfilesCustomOptionsSetEnabled();
2781   }
2782
2783   protected void backupsSetOptions(String suffix, int digits,
2784           boolean reverse, boolean keepAll, int rollMax,
2785           boolean confirmDelete)
2786   {
2787     suffixTemplate.setText(suffix);
2788     suffixDigitsSpinner.setValue(digits);
2789     suffixReverse.setSelected(reverse);
2790     backupfilesKeepAll.setSelected(keepAll);
2791     backupfilesRollMaxSpinner.setValue(rollMax);
2792     backupfilesConfirmDelete.setSelected(confirmDelete);
2793   }
2794
2795   protected void backupsSetOptions(BackupFilesPresetEntry p)
2796   {
2797     backupsSetOptions(p.suffix, p.digits, p.reverse, p.keepAll, p.rollMax,
2798             p.confirmDelete);
2799   }
2800
2801   protected void autoIdWidth_actionPerformed()
2802   {
2803     // TODO Auto-generated method stub
2804
2805   }
2806
2807   protected void userIdWidth_actionPerformed()
2808   {
2809     // TODO Auto-generated method stub
2810
2811   }
2812
2813   protected void maxColour_actionPerformed(JPanel panel)
2814   {
2815   }
2816
2817   protected void minColour_actionPerformed(JPanel panel)
2818   {
2819   }
2820
2821   protected void gapColour_actionPerformed(JPanel panel)
2822   {
2823   }
2824
2825   protected void hiddenColour_actionPerformed(JPanel panel)
2826   {
2827   }
2828
2829   protected void showunconserved_actionPerformed(ActionEvent e)
2830   {
2831     // TODO Auto-generated method stub
2832
2833   }
2834
2835   protected void useLegacyGaps_actionPerformed(ActionEvent e)
2836   {
2837   }
2838
2839   protected void resetOvDefaults_actionPerformed(ActionEvent e)
2840   {
2841   }
2842
2843   /**
2844    * DOCUMENT ME!
2845    * 
2846    * @param e
2847    *          DOCUMENT ME!
2848    */
2849   public void ok_actionPerformed(ActionEvent e)
2850   {
2851   }
2852
2853   /**
2854    * DOCUMENT ME!
2855    * 
2856    * @param e
2857    *          DOCUMENT ME!
2858    */
2859   public void cancel_actionPerformed(ActionEvent e)
2860   {
2861   }
2862
2863   /**
2864    * DOCUMENT ME!
2865    * 
2866    * @param e
2867    *          DOCUMENT ME!
2868    */
2869   public void annotations_actionPerformed(ActionEvent e)
2870   {
2871   }
2872
2873   /**
2874    * DOCUMENT ME!
2875    */
2876   public void startupFileTextfield_mouseClicked()
2877   {
2878   }
2879
2880   public void newLink_actionPerformed(ActionEvent e)
2881   {
2882
2883   }
2884
2885   public void editLink_actionPerformed(ActionEvent e)
2886   {
2887
2888   }
2889
2890   public void deleteLink_actionPerformed(ActionEvent e)
2891   {
2892
2893   }
2894
2895   public void defaultBrowser_mouseClicked(MouseEvent e)
2896   {
2897
2898   }
2899
2900   public void linkURLList_keyTyped(KeyEvent e)
2901   {
2902
2903   }
2904
2905   public void useProxy_actionPerformed()
2906   {
2907     boolean enabled = useProxy.isSelected();
2908     portLabel.setEnabled(enabled);
2909     serverLabel.setEnabled(enabled);
2910     proxyServerTB.setEnabled(enabled);
2911     proxyPortTB.setEnabled(enabled);
2912   }
2913
2914   /**
2915    * Customer renderer for JTable: supports column of radio buttons
2916    */
2917   public class RadioButtonRenderer extends JRadioButton
2918           implements TableCellRenderer
2919   {
2920     public RadioButtonRenderer()
2921     {
2922       setHorizontalAlignment(CENTER);
2923       setToolTipText(MessageManager.getString("label.urltooltip"));
2924     }
2925
2926     @Override
2927     public Component getTableCellRendererComponent(JTable table,
2928             Object value, boolean isSelected, boolean hasFocus, int row,
2929             int column)
2930     {
2931       setSelected((boolean) value);
2932
2933       // set colours to match rest of table
2934       if (isSelected)
2935       {
2936         setBackground(table.getSelectionBackground());
2937         setForeground(table.getSelectionForeground());
2938       }
2939       else
2940       {
2941         setBackground(table.getBackground());
2942         setForeground(table.getForeground());
2943       }
2944       return this;
2945     }
2946   }
2947
2948   /**
2949    * Customer cell editor for JTable: supports column of radio buttons in
2950    * conjunction with renderer
2951    */
2952   public class RadioButtonEditor extends AbstractCellEditor
2953           implements TableCellEditor
2954   {
2955     private JRadioButton button = new JRadioButton();
2956
2957     public RadioButtonEditor()
2958     {
2959       button.setHorizontalAlignment(SwingConstants.CENTER);
2960       this.button.addActionListener(new ActionListener()
2961       {
2962         @Override
2963         public void actionPerformed(ActionEvent e)
2964         {
2965           fireEditingStopped();
2966         }
2967       });
2968     }
2969
2970     @Override
2971     public Component getTableCellEditorComponent(JTable table, Object value,
2972             boolean isSelected, int row, int column)
2973     {
2974       button.setSelected((boolean) value);
2975       return button;
2976     }
2977
2978     @Override
2979     public Object getCellEditorValue()
2980     {
2981       return button.isSelected();
2982     }
2983
2984   }
2985
2986   protected void validateHmmerPath()
2987   {
2988   }
2989
2990   protected void validateCygwinPath()
2991   {
2992   }
2993
2994   /**
2995    * A helper method to add a panel containing a label and a component to a
2996    * panel
2997    * 
2998    * @param panel
2999    * @param tooltip
3000    * @param label
3001    * @param valBox
3002    */
3003   protected static void addtoLayout(JPanel panel, String tooltip,
3004           JComponent label, JComponent valBox)
3005   {
3006     JPanel laypanel = new JPanel(new GridLayout(1, 2));
3007     JPanel labPanel = new JPanel(new BorderLayout());
3008     JPanel valPanel = new JPanel();
3009     labPanel.setBounds(new Rectangle(7, 7, 158, 23));
3010     valPanel.setBounds(new Rectangle(172, 7, 270, 23));
3011     labPanel.add(label, BorderLayout.WEST);
3012     valPanel.add(valBox);
3013     laypanel.add(labPanel);
3014     laypanel.add(valPanel);
3015     valPanel.setToolTipText(tooltip);
3016     labPanel.setToolTipText(tooltip);
3017     valBox.setToolTipText(tooltip);
3018     panel.add(laypanel);
3019     panel.validate();
3020   }
3021 }
3022