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