JAL-3111 JAL-3280 hide the version check preference option in ‘Connections’ tab
[jalview.git] / src / jalview / jbgui / GPreferences.java
index 2081416..9f98ffa 100755 (executable)
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
- * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
  * Jalview is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- * 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
  * Jalview is distributed in the hope that it will be useful, but 
  * WITHOUT ANY WARRANTY; without even the implied warranty 
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
  * PURPOSE.  See the GNU General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 package jalview.jbgui;
 
+import jalview.bin.Cache;
+import jalview.fts.core.FTSDataColumnPreferences;
+import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
+import jalview.fts.service.pdb.PDBFTSRestClient;
+import jalview.gui.Desktop;
+import jalview.gui.JalviewBooleanRadioButtons;
+import jalview.gui.JvOptionPane;
 import jalview.gui.JvSwingUtils;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.border.*;
-import javax.swing.event.*;
+import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.BackupFilenameParts;
+import jalview.io.BackupFiles;
+import jalview.io.BackupFilesPresetEntry;
+import jalview.io.IntKeyStringValueEntry;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Insets;
 import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.AbstractCellEditor;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JSpinner;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.SpinnerModel;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
 
 /**
- * DOCUMENT ME!
+ * Base class for the Preferences panel.
  * 
  * @author $author$
  * @version $Revision$
  */
 public class GPreferences extends JPanel
 {
-  JTabbedPane tabbedPane = new JTabbedPane();
-
-  JButton ok = new JButton();
+  private static final Font LABEL_FONT = JvSwingUtils.getLabelFont();
 
-  JButton cancel = new JButton();
+  private static final Font LABEL_FONT_ITALIC = JvSwingUtils
+          .getLabelFont(false, true);
 
-  JPanel okCancelPanel = new JPanel();
+  private static final Font LABEL_FONT_BOLD = JvSwingUtils
+          .getLabelFont(true, false);
 
-  BorderLayout borderLayout1 = new BorderLayout();
+  /*
+   * Visual tab components
+   */
+  protected JCheckBox fullScreen = new JCheckBox();
 
-  protected JCheckBox quality = new JCheckBox();
+  protected JCheckBox openoverv = new JCheckBox();
 
-  JPanel visualTab = new JPanel();
-  JPanel visual2Tab = new JPanel();
+  protected JCheckBox seqLimit = new JCheckBox();
 
-  protected JCheckBox fullScreen = new JCheckBox();
+  protected JCheckBox rightAlign = new JCheckBox();
 
-  protected JCheckBox conservation = new JCheckBox();
+  protected JComboBox<String> fontSizeCB = new JComboBox<>();
 
-  protected JCheckBox identity = new JCheckBox();
+  protected JComboBox<String> fontStyleCB = new JComboBox<>();
 
-  protected JCheckBox annotations = new JCheckBox();
+  protected JComboBox<String> fontNameCB = new JComboBox<>();
 
-  protected JPanel minColour = new JPanel();
-  JLabel mincolourLabel = new JLabel();
+  protected JCheckBox showOccupancy = new JCheckBox();
 
-  protected JPanel maxColour = new JPanel();
-  JLabel maxcolourLabel = new JLabel();
+  protected JCheckBox showUnconserved = new JCheckBox();
 
-  JLabel gapLabel = new JLabel();
+  protected JCheckBox idItalics = new JCheckBox();
 
-  protected JComboBox colour = new JComboBox();
+  protected JCheckBox smoothFont = new JCheckBox();
 
-  JLabel colourLabel = new JLabel();
+  protected JCheckBox scaleProteinToCdna = new JCheckBox();
 
-  JLabel fontLabel = new JLabel();
+  protected JComboBox<String> gapSymbolCB = new JComboBox<>();
 
-  protected JComboBox fontSizeCB = new JComboBox();
+  protected JCheckBox wrap = new JCheckBox();
 
-  protected JComboBox fontStyleCB = new JComboBox();
+  protected JComboBox<String> sortby = new JComboBox<>();
 
-  protected JComboBox fontNameCB = new JComboBox();
+  protected JComboBox<String> sortAnnBy = new JComboBox<>();
 
-  protected JComboBox gapSymbolCB = new JComboBox();
+  protected JComboBox<String> sortAutocalc = new JComboBox<>();
 
   protected JCheckBox startupCheckbox = new JCheckBox();
 
   protected JTextField startupFileTextfield = new JTextField();
 
-  JPanel connectTab = new JPanel();
+  // below are in the 'second column'
+  protected JCheckBox annotations = new JCheckBox();
 
-  JLabel serverLabel = new JLabel();
+  protected JCheckBox quality = new JCheckBox();
 
-  protected JList linkURLList = new JList();
+  protected JCheckBox conservation = new JCheckBox();
 
-  protected JTextField proxyServerTB = new JTextField();
+  protected JCheckBox identity = new JCheckBox();
 
-  protected JTextField proxyPortTB = new JTextField();
+  protected JCheckBox showGroupConsensus = new JCheckBox();
+
+  protected JCheckBox showGroupConservation = new JCheckBox();
 
-  JLabel portLabel = new JLabel();
+  protected JCheckBox showConsensHistogram = new JCheckBox();
 
-  JLabel browserLabel = new JLabel();
+  protected JCheckBox showConsensLogo = new JCheckBox();
 
-  protected JTextField defaultBrowser = new JTextField();
+  protected JCheckBox showDbRefTooltip = new JCheckBox();
 
-  JButton newLink = new JButton();
+  protected JCheckBox showNpTooltip = new JCheckBox();
 
-  JButton editLink = new JButton();
+  /*
+   * Structure tab and components
+   */
+  protected JPanel structureTab;
 
-  JButton deleteLink = new JButton();
+  protected JCheckBox structFromPdb = new JCheckBox();
 
-  JScrollPane linkScrollPane = new JScrollPane();
+  protected JCheckBox useRnaView = new JCheckBox();
 
-  JPanel linkPanel = new JPanel();
+  protected JCheckBox addSecondaryStructure = new JCheckBox();
 
-  BorderLayout borderLayout2 = new BorderLayout();
+  protected JCheckBox addTempFactor = new JCheckBox();
 
-  JPanel editLinkButtons = new JPanel();
+  protected JComboBox<String> structViewer = new JComboBox<>();
 
-  GridLayout gridLayout1 = new GridLayout();
+  protected JTextField chimeraPath = new JTextField();
 
-  protected JList linkNameList = new JList();
+  protected ButtonGroup mappingMethod = new ButtonGroup();
 
-  JPanel linkPanel2 = new JPanel();
+  protected JRadioButton siftsMapping = new JRadioButton();
 
-  BorderLayout borderLayout3 = new BorderLayout();
+  protected JRadioButton nwMapping = new JRadioButton();
 
-  protected JCheckBox useProxy = new JCheckBox();
+  /*
+   * Colours tab components
+   */
+  protected JPanel minColour = new JPanel();
+
+  protected JPanel maxColour = new JPanel();
+
+  protected JComboBox<String> protColour = new JComboBox<>();
+
+  protected JComboBox<String> nucColour = new JComboBox<>();
+
+  /*
+   * Overview tab components
+   */
+  protected JPanel gapColour = new JPanel();
+
+  protected JPanel hiddenColour = new JPanel();
+
+  protected JCheckBox useLegacyGap;
+
+  protected JCheckBox showHiddenAtStart;
+
+  protected JLabel gapLabel;
 
-  JPanel jPanel1 = new JPanel();
+  /*
+   * Connections tab components
+   */
+  protected JTable linkUrlTable = new JTable();
 
-  TitledBorder titledBorder1 = new TitledBorder("Proxy Server");
+  protected JButton editLink = new JButton();
 
-  TitledBorder titledBorder2 = new TitledBorder("File Output");
+  protected JButton deleteLink = new JButton();
 
-  GridBagLayout gridBagLayout2 = new GridBagLayout();
+  protected JTextField filterTB = new JTextField();
 
-  GridBagLayout gridBagLayout1 = new GridBagLayout();
+  protected JButton doReset = new JButton();
 
-  GridBagLayout gridBagLayout3 = new GridBagLayout();
+  protected JButton userOnly = new JButton();
 
-  protected JComboBox sortby = new JComboBox();
+  protected JLabel portLabel = new JLabel();
 
-  JLabel sortLabel = new JLabel();
+  protected JLabel serverLabel = new JLabel();
 
-  JPanel jPanel2 = new JPanel();
-  JPanel visual2panel = new JPanel();
+  protected JTextField proxyServerTB = new JTextField();
 
-  GridLayout gridLayout2 = new GridLayout();
+  protected JTextField proxyPortTB = new JTextField();
 
-  GridLayout gridLayout4 = new GridLayout();
+  protected JTextField defaultBrowser = new JTextField();
 
-  JPanel annsettingsPanel = new JPanel();
+  protected JCheckBox useProxy = new JCheckBox();
 
-  JPanel autoAnnotSettings1 = new JPanel();
+  protected JCheckBox usagestats = new JCheckBox();
 
-  JPanel autoAnnotSettings2 = new JPanel();
+  protected JCheckBox questionnaire = new JCheckBox();
 
-  JPanel autoAnnotSettings3 = new JPanel();
+  protected JCheckBox versioncheck = new JCheckBox();
 
-  JPanel exportTab = new JPanel();
+  /*
+   * Output tab components
+   */
+  protected JComboBox<Object> epsRendering = new JComboBox<>();
 
-  JLabel epsLabel = new JLabel();
+  protected JLabel userIdWidthlabel = new JLabel();
 
-  protected JComboBox epsRendering = new JComboBox();
+  protected JCheckBox autoIdWidth = new JCheckBox();
 
-  JLabel jLabel1 = new JLabel();
+  protected JTextField userIdWidth = new JTextField();
 
   protected JCheckBox blcjv = new JCheckBox();
 
@@ -175,73 +267,71 @@ public class GPreferences extends JPanel
 
   protected JCheckBox pfamjv = new JCheckBox();
 
-  FlowLayout flowLayout1 = new FlowLayout();
-
   protected JCheckBox pirjv = new JCheckBox();
 
-  JPanel jPanel11 = new JPanel();
-
-  Font verdana11 = JvSwingUtils.getLabelFont();
-
-  protected JCheckBox seqLimit = new JCheckBox();
-
-  GridLayout gridLayout3 = new GridLayout();
-
-  protected JCheckBox smoothFont = new JCheckBox();
+  protected JCheckBox modellerOutput = new JCheckBox();
 
-  JPanel calcTab = new JPanel();
+  protected JCheckBox embbedBioJSON = new JCheckBox();
 
+  /*
+   * Editing tab components
+   */
   protected JCheckBox autoCalculateConsCheck = new JCheckBox();
 
   protected JCheckBox padGaps = new JCheckBox();
 
-  protected JCheckBox modellerOutput = new JCheckBox();
-
-  protected JPanel dasPanel = new JPanel();
+  protected JCheckBox sortByTree = new JCheckBox();
 
-  BorderLayout borderLayout4 = new BorderLayout();
+  /*
+   * Web Services tab
+   */
+  protected JPanel wsTab = new JPanel();
 
-  protected JPanel wsPanel = new JPanel();
+  /*
+   * Backups tab components
+   * a lot of these are member variables instead of local variables only so that they
+   * can be enabled/disabled easily in one go
+   */
 
-  BorderLayout borderLayout5 = new BorderLayout();
+  protected JCheckBox enableBackupFiles = new JCheckBox();
 
-  protected JCheckBox wrap = new JCheckBox();
+  protected JPanel presetsPanel = new JPanel();
 
-  protected JCheckBox rightAlign = new JCheckBox();
+  protected JLabel presetsComboLabel = new JLabel();
 
-  protected JCheckBox showUnconserved = new JCheckBox();
+  protected JCheckBox customiseCheckbox = new JCheckBox();
 
-  protected JCheckBox showDbRefTooltip = new JCheckBox();
+  protected JButton revertButton = new JButton();
 
-  protected JCheckBox showNpTooltip = new JCheckBox();
+  protected JComboBox<Object> backupfilesPresetsCombo = new JComboBox<>();
 
-  protected JCheckBox idItalics = new JCheckBox();
+  private int backupfilesPresetsComboLastSelected = 0;
 
-  protected JCheckBox openoverv = new JCheckBox();
+  protected JPanel suffixPanel = new JPanel();
 
-  protected JCheckBox usagestats = new JCheckBox();
+  protected JPanel keepfilesPanel = new JPanel();
 
-  protected JCheckBox questionnaire = new JCheckBox();
+  protected JPanel exampleFilesPanel = new JPanel();
 
-  protected JCheckBox versioncheck = new JCheckBox();
+  protected JTextField suffixTemplate = new JTextField(null, 8);
 
-  protected JLabel showGroupbits = new JLabel();
+  protected JLabel suffixTemplateLabel = new JLabel();
 
-  protected JLabel showConsensbits = new JLabel();
+  protected JLabel suffixDigitsLabel = new JLabel();
 
-  protected JCheckBox showConsensLogo = new JCheckBox();
+  protected JSpinner suffixDigitsSpinner = new JSpinner();
 
-  protected JCheckBox showConsensHistogram = new JCheckBox();
+  protected JalviewBooleanRadioButtons suffixReverse = new JalviewBooleanRadioButtons();
 
-  protected JCheckBox showGroupConsensus = new JCheckBox();
+  protected JalviewBooleanRadioButtons backupfilesKeepAll = new JalviewBooleanRadioButtons();
 
-  protected JCheckBox showGroupConservation = new JCheckBox();
+  public JSpinner backupfilesRollMaxSpinner = new JSpinner();
 
-  protected JCheckBox shareSelections = new JCheckBox();
+  protected JLabel oldBackupFilesLabel = new JLabel();
 
-  protected JCheckBox followHighlight = new JCheckBox();
+  protected JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons();
 
-  protected JCheckBox sortByTree= new JCheckBox();
+  protected JTextArea backupfilesExampleLabel = new JTextArea();
 
   /**
    * Creates a new GPreferences object.
@@ -258,207 +348,1236 @@ public class GPreferences extends JPanel
   }
 
   /**
-   * DOCUMENT ME!
+   * Construct the panel and its tabbed sub-panels.
    * 
    * @throws Exception
-   *           DOCUMENT ME!
    */
   private void jbInit() throws Exception
   {
-    this.setLayout(borderLayout1);
-    ok.setText("OK");
-    ok.addActionListener(new ActionListener()
+    final JTabbedPane tabbedPane = new JTabbedPane();
+    this.setLayout(new BorderLayout());
+    JPanel okCancelPanel = initOkCancelPanel();
+    this.add(tabbedPane, BorderLayout.CENTER);
+    this.add(okCancelPanel, BorderLayout.SOUTH);
+
+    tabbedPane.add(initVisualTab(),
+            MessageManager.getString("label.visual"));
+
+    tabbedPane.add(initColoursTab(),
+            MessageManager.getString("label.colours"));
+
+    tabbedPane.add(initOverviewTab(),
+            MessageManager.getString("label.overview"));
+
+    tabbedPane.add(initStructureTab(),
+            MessageManager.getString("label.structure"));
+
+    tabbedPane.add(initConnectionsTab(),
+            MessageManager.getString("label.connections"));
+
+    tabbedPane.add(initBackupsTab(),
+            MessageManager.getString("label.backups"));
+
+    tabbedPane.add(initLinksTab(),
+            MessageManager.getString("label.urllinks"));
+
+    tabbedPane.add(initOutputTab(),
+            MessageManager.getString("label.output"));
+
+    tabbedPane.add(initEditingTab(),
+            MessageManager.getString("label.editing"));
+
+    /*
+     * See WsPreferences for the real work of configuring this tab.
+     */
+    wsTab.setLayout(new BorderLayout());
+    tabbedPane.add(wsTab, MessageManager.getString("label.web_services"));
+
+    /*
+     * Handler to validate a tab before leaving it - currently only for
+     * Structure.
+     */
+    tabbedPane.addChangeListener(new ChangeListener()
     {
-      public void actionPerformed(ActionEvent e)
+      private Component lastTab;
+
+      @Override
+      public void stateChanged(ChangeEvent e)
       {
-        ok_actionPerformed(e);
+        if (lastTab == structureTab
+                && tabbedPane.getSelectedComponent() != structureTab)
+        {
+          if (!validateStructure())
+          {
+            tabbedPane.setSelectedComponent(structureTab);
+            return;
+          }
+        }
+        lastTab = tabbedPane.getSelectedComponent();
       }
+
     });
-    cancel.setText("Cancel");
-    cancel.addActionListener(new ActionListener()
+  }
+
+  /**
+   * Initialises the Editing tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initEditingTab()
+  {
+    JPanel editingTab = new JPanel();
+    editingTab.setLayout(null);
+    autoCalculateConsCheck.setFont(LABEL_FONT);
+    autoCalculateConsCheck.setText(
+            MessageManager.getString("label.autocalculate_consensus"));
+    autoCalculateConsCheck.setBounds(new Rectangle(21, 52, 209, 23));
+    padGaps.setFont(LABEL_FONT);
+    padGaps.setText(
+            MessageManager.getString("label.pad_gaps_when_editing"));
+    padGaps.setBounds(new Rectangle(22, 94, 168, 23));
+    sortByTree.setFont(LABEL_FONT);
+    sortByTree
+            .setText(MessageManager.getString("label.sort_with_new_tree"));
+    sortByTree.setToolTipText(MessageManager.getString(
+            "label.any_trees_calculated_or_loaded_alignment_automatically_sort"));
+    sortByTree.setBounds(new Rectangle(22, 136, 168, 23));
+    editingTab.add(autoCalculateConsCheck);
+    editingTab.add(padGaps);
+    editingTab.add(sortByTree);
+    return editingTab;
+  }
+
+  /**
+   * Initialises the Output tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initOutputTab()
+  {
+    JPanel outputTab = new JPanel();
+    outputTab.setLayout(null);
+    JLabel epsLabel = new JLabel();
+    epsLabel.setFont(LABEL_FONT);
+    epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    epsLabel.setText(MessageManager.getString("label.eps_rendering_style"));
+    epsLabel.setBounds(new Rectangle(9, 31, 140, 24));
+    epsRendering.setFont(LABEL_FONT);
+    epsRendering.setBounds(new Rectangle(154, 34, 187, 21));
+    JLabel jLabel1 = new JLabel();
+    jLabel1.setFont(LABEL_FONT);
+    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
+    jLabel1.setText(MessageManager.getString("label.append_start_end"));
+    jLabel1.setFont(LABEL_FONT);
+    fastajv.setFont(LABEL_FONT);
+    fastajv.setHorizontalAlignment(SwingConstants.LEFT);
+    clustaljv.setText(MessageManager.getString("label.clustal") + "     ");
+    blcjv.setText(MessageManager.getString("label.blc") + "     ");
+    fastajv.setText(MessageManager.getString("label.fasta") + "     ");
+    msfjv.setText(MessageManager.getString("label.msf") + "     ");
+    pfamjv.setText(MessageManager.getString("label.pfam") + "     ");
+    pileupjv.setText(MessageManager.getString("label.pileup") + "     ");
+    msfjv.setFont(LABEL_FONT);
+    msfjv.setHorizontalAlignment(SwingConstants.LEFT);
+    pirjv.setText(MessageManager.getString("label.pir") + "     ");
+    JPanel jPanel11 = new JPanel();
+    jPanel11.setFont(LABEL_FONT);
+    TitledBorder titledBorder2 = new TitledBorder(
+            MessageManager.getString("label.file_output"));
+    jPanel11.setBorder(titledBorder2);
+    jPanel11.setBounds(new Rectangle(30, 72, 196, 182));
+    GridLayout gridLayout3 = new GridLayout();
+    jPanel11.setLayout(gridLayout3);
+    gridLayout3.setRows(8);
+    blcjv.setFont(LABEL_FONT);
+    blcjv.setHorizontalAlignment(SwingConstants.LEFT);
+    clustaljv.setFont(LABEL_FONT);
+    clustaljv.setHorizontalAlignment(SwingConstants.LEFT);
+    pfamjv.setFont(LABEL_FONT);
+    pfamjv.setHorizontalAlignment(SwingConstants.LEFT);
+    pileupjv.setFont(LABEL_FONT);
+    pileupjv.setHorizontalAlignment(SwingConstants.LEFT);
+    pirjv.setFont(LABEL_FONT);
+    pirjv.setHorizontalAlignment(SwingConstants.LEFT);
+    autoIdWidth.setFont(LABEL_FONT);
+    autoIdWidth.setText(
+            MessageManager.getString("label.automatically_set_id_width"));
+    autoIdWidth.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager
+            .getString("label.adjusts_width_generated_eps_png")));
+    autoIdWidth.setBounds(new Rectangle(228, 96, 188, 23));
+    autoIdWidth.addActionListener(new ActionListener()
     {
+
+      @Override
       public void actionPerformed(ActionEvent e)
       {
-        cancel_actionPerformed(e);
+        autoIdWidth_actionPerformed();
       }
     });
-    quality.setEnabled(false);
-    quality.setFont(verdana11);
-    quality.setHorizontalAlignment(SwingConstants.RIGHT);
-    quality.setHorizontalTextPosition(SwingConstants.LEFT);
-    quality.setSelected(true);
-    quality.setText("Quality");
-    visualTab.setBorder(new TitledBorder("Open new alignment"));
-    visualTab.setLayout(null);
-    visual2Tab.setBorder(new TitledBorder("Open new alignment"));
-    visual2Tab.setLayout(new FlowLayout());
-    fullScreen.setFont(verdana11);
-    fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);
-    fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);
-    fullScreen.setText("Maximise Window");
-    conservation.setEnabled(false);
-    conservation.setFont(verdana11);
-    conservation.setHorizontalAlignment(SwingConstants.RIGHT);
-    conservation.setHorizontalTextPosition(SwingConstants.LEFT);
-    conservation.setSelected(true);
-    conservation.setText("Conservation");
-    identity.setEnabled(false);
-    identity.setFont(verdana11);
-    identity.setHorizontalAlignment(SwingConstants.RIGHT);
-    identity.setHorizontalTextPosition(SwingConstants.LEFT);
-    identity.setSelected(true);
-    identity.setText("Consensus");
-    showGroupbits.setFont(verdana11);
-    showGroupbits.setHorizontalAlignment(SwingConstants.RIGHT);
-    showGroupbits.setHorizontalTextPosition(SwingConstants.LEFT);
-    showGroupbits.setText("Show group:");
-    showConsensbits.setFont(verdana11);
-    showConsensbits.setHorizontalAlignment(SwingConstants.RIGHT);
-    showConsensbits.setHorizontalTextPosition(SwingConstants.LEFT);
-    showConsensbits.setText("Consensus:");
-    showConsensHistogram.setEnabled(false);
-    showConsensHistogram.setFont(verdana11);
-    showConsensHistogram.setHorizontalAlignment(SwingConstants.RIGHT);
-    showConsensHistogram.setHorizontalTextPosition(SwingConstants.LEFT);
-    showConsensHistogram.setSelected(true);
-    showConsensHistogram.setText("Histogram");
-    showConsensLogo.setEnabled(false);
-    showConsensLogo.setFont(verdana11);
-    showConsensLogo.setHorizontalAlignment(SwingConstants.RIGHT);
-    showConsensLogo.setHorizontalTextPosition(SwingConstants.LEFT);
-    showConsensLogo.setSelected(true);
-    showConsensLogo.setText("Logo");
-    showGroupConsensus.setEnabled(false);
-    showGroupConsensus.setFont(verdana11);
-    showGroupConsensus.setHorizontalAlignment(SwingConstants.RIGHT);
-    showGroupConsensus.setHorizontalTextPosition(SwingConstants.LEFT);
-    showGroupConsensus.setSelected(true);
-    showGroupConsensus.setText("Consensus");
-    showGroupConservation.setEnabled(false);
-    showGroupConservation.setFont(verdana11);
-    showGroupConservation.setHorizontalAlignment(SwingConstants.RIGHT);
-    showGroupConservation.setHorizontalTextPosition(SwingConstants.LEFT);
-    showGroupConservation.setSelected(true);
-    showGroupConservation.setText("Conservation");
-    showNpTooltip.setEnabled(true);
-    showNpTooltip.setFont(verdana11);
-    showNpTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
-    showNpTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
-    showNpTooltip.setSelected(true);
-    showNpTooltip.setText("Non-positional Features");
-    showDbRefTooltip.setEnabled(true);
-    showDbRefTooltip.setFont(verdana11);
-    showDbRefTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
-    showDbRefTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
-    showDbRefTooltip.setSelected(true);
-    showDbRefTooltip.setText("Database References");
-    annotations.setFont(verdana11);
-    annotations.setHorizontalAlignment(SwingConstants.RIGHT);
-    annotations.setHorizontalTextPosition(SwingConstants.LEADING);
-    annotations.setSelected(true);
-    annotations.setText("Show Annotations");
-    annotations.setBounds(new Rectangle(169, 12, 200, 23));
-    annotations.addActionListener(new ActionListener()
+    userIdWidthlabel.setFont(LABEL_FONT);
+    userIdWidthlabel.setText(
+            MessageManager.getString("label.figure_id_column_width"));
+    userIdWidth.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager
+            .getString("label.manually_specify_width_left_column")));
+    userIdWidthlabel.setToolTipText(
+            JvSwingUtils.wrapTooltip(true, MessageManager.getString(
+                    "label.manually_specify_width_left_column")));
+    userIdWidthlabel.setBounds(new Rectangle(236, 120, 168, 23));
+    userIdWidth.setFont(JvSwingUtils.getTextAreaFont());
+    userIdWidth.setText("");
+    userIdWidth.setBounds(new Rectangle(232, 144, 84, 23));
+    userIdWidth.addActionListener(new ActionListener()
     {
+
+      @Override
       public void actionPerformed(ActionEvent e)
       {
-        annotations_actionPerformed(e);
+        userIdWidth_actionPerformed();
       }
     });
-    identity.addActionListener(new ActionListener()
+    modellerOutput.setFont(LABEL_FONT);
+    modellerOutput
+            .setText(MessageManager.getString("label.use_modeller_output"));
+    modellerOutput.setBounds(new Rectangle(228, 226, 168, 23));
+    embbedBioJSON.setFont(LABEL_FONT);
+    embbedBioJSON.setText(MessageManager.getString("label.embbed_biojson"));
+    embbedBioJSON.setBounds(new Rectangle(228, 200, 250, 23));
+
+    jPanel11.add(jLabel1);
+    jPanel11.add(blcjv);
+    jPanel11.add(clustaljv);
+    jPanel11.add(fastajv);
+    jPanel11.add(msfjv);
+    jPanel11.add(pfamjv);
+    jPanel11.add(pileupjv);
+    jPanel11.add(pirjv);
+    outputTab.add(autoIdWidth);
+    outputTab.add(userIdWidth);
+    outputTab.add(userIdWidthlabel);
+    outputTab.add(modellerOutput);
+    outputTab.add(embbedBioJSON);
+    outputTab.add(epsLabel);
+    outputTab.add(epsRendering);
+    outputTab.add(jPanel11);
+    return outputTab;
+  }
+
+  /**
+   * Initialises the Connections tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initConnectionsTab()
+  {
+    JPanel connectTab = new JPanel();
+    connectTab.setLayout(new GridBagLayout());
+
+    // Label for browser text box
+    JLabel browserLabel = new JLabel();
+    browserLabel.setFont(LABEL_FONT);
+    browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
+    browserLabel.setText(
+            MessageManager.getString("label.default_browser_unix"));
+    defaultBrowser.setFont(LABEL_FONT);
+    defaultBrowser.setText("");
+    final String tooltip = JvSwingUtils.wrapTooltip(true,
+            MessageManager.getString("label.double_click_to_browse"));
+    defaultBrowser.setToolTipText(tooltip);
+    defaultBrowser.addMouseListener(new MouseAdapter()
     {
-      public void actionPerformed(ActionEvent e)
+      @Override
+      public void mouseClicked(MouseEvent e)
       {
-        annotations_actionPerformed(e);
+        if (e.getClickCount() > 1)
+        {
+          defaultBrowser_mouseClicked(e);
+        }
       }
     });
-    showGroupConsensus.addActionListener(new ActionListener()
+
+    JPanel proxyPanel = initConnTabProxyPanel();
+    initConnTabCheckboxes();
+
+    // Add default Browser text box
+    connectTab.add(browserLabel,
+            new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.NONE,
+                    new Insets(10, 0, 5, 5), 5, 1));
+    defaultBrowser.setFont(LABEL_FONT);
+    defaultBrowser.setText("");
+
+    connectTab.add(defaultBrowser, new GridBagConstraints(1, 0, 1, 1, 1.0,
+            0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
+            new Insets(10, 0, 5, 10), 30, 1));
+
+    // Add proxy server panel
+    connectTab.add(proxyPanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0,
+            GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
+            new Insets(10, 0, 5, 12), 4, 10));
+
+    // Add usage stats, version check and questionnaire checkboxes
+    connectTab.add(usagestats,
+            new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+                    new Insets(0, 2, 5, 5), 70, 1));
+    connectTab.add(questionnaire,
+            new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+                    new Insets(0, 2, 5, 10), 70, 1));
+    connectTab.add(versioncheck,
+            new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+                    new Insets(0, 2, 5, 5), 70, 1));
+
+    versioncheck.setVisible(false);
+
+    // Add padding so the panel doesn't look ridiculous
+    JPanel spacePanel = new JPanel();
+    connectTab.add(spacePanel,
+            new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0,
+                    GridBagConstraints.WEST, GridBagConstraints.BOTH,
+                    new Insets(0, 0, 0, 5), 70, 1));
+
+    return connectTab;
+  }
+
+  /**
+   * Initialises the Links tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initLinksTab()
+  {
+    JPanel linkTab = new JPanel();
+    linkTab.setLayout(new GridBagLayout());
+
+    // Set up table for Url links
+    linkUrlTable.getTableHeader().setReorderingAllowed(false);
+    linkUrlTable.setFillsViewportHeight(true);
+    linkUrlTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+    linkUrlTable.setAutoCreateRowSorter(true);
+    linkUrlTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+    // adjust row height so radio buttons actually fit
+    // don't do this in the renderer, it causes the awt thread to activate
+    // constantly
+    JRadioButton temp = new JRadioButton();
+    linkUrlTable.setRowHeight(temp.getMinimumSize().height);
+
+    // Table in scrollpane so that the table is given a scrollbar
+    JScrollPane linkScrollPane = new JScrollPane(linkUrlTable);
+    linkScrollPane.setBorder(null);
+
+    // Panel for links functionality
+    JPanel linkPanel = new JPanel(new GridBagLayout());
+    linkPanel.setBorder(new TitledBorder(
+            MessageManager.getString("label.url_linkfrom_sequence_id")));
+
+    // Put the Url links panel together
+
+    // Buttons go at top right, resizing only resizes the blank space vertically
+    JPanel buttonPanel = initLinkTabUrlButtons();
+    GridBagConstraints linkConstraints1 = new GridBagConstraints();
+    linkConstraints1.insets = new Insets(0, 0, 5, 0);
+    linkConstraints1.gridx = 0;
+    linkConstraints1.gridy = 0;
+    linkConstraints1.weightx = 1.0;
+    linkConstraints1.fill = GridBagConstraints.HORIZONTAL;
+    linkTab.add(buttonPanel, linkConstraints1);
+
+    // Links table goes at top left, resizing resizes the table
+    GridBagConstraints linkConstraints2 = new GridBagConstraints();
+    linkConstraints2.insets = new Insets(0, 0, 5, 5);
+    linkConstraints2.gridx = 0;
+    linkConstraints2.gridy = 1;
+    linkConstraints2.weightx = 1.0;
+    linkConstraints2.weighty = 1.0;
+    linkConstraints2.fill = GridBagConstraints.BOTH;
+    linkTab.add(linkScrollPane, linkConstraints2);
+
+    // Filter box and buttons goes at bottom left, resizing resizes the text box
+    JPanel filterPanel = initLinkTabFilterPanel();
+    GridBagConstraints linkConstraints3 = new GridBagConstraints();
+    linkConstraints3.insets = new Insets(0, 0, 0, 5);
+    linkConstraints3.gridx = 0;
+    linkConstraints3.gridy = 2;
+    linkConstraints3.weightx = 1.0;
+    linkConstraints3.fill = GridBagConstraints.HORIZONTAL;
+    linkTab.add(filterPanel, linkConstraints3);
+
+    return linkTab;
+  }
+
+  private JPanel initLinkTabFilterPanel()
+  {
+    // Filter textbox and reset button
+    JLabel filterLabel = new JLabel(
+            MessageManager.getString("label.filter"));
+    filterLabel.setFont(LABEL_FONT);
+    filterLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    filterLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+
+    filterTB.setFont(LABEL_FONT);
+    filterTB.setText("");
+
+    doReset.setText(MessageManager.getString("action.showall"));
+    userOnly.setText(MessageManager.getString("action.customfilter"));
+
+    // Panel for filter functionality
+    JPanel filterPanel = new JPanel(new GridBagLayout());
+    filterPanel.setBorder(new TitledBorder("Filter"));
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.anchor = GridBagConstraints.WEST;
+
+    filterPanel.add(filterLabel, gbc);
+
+    GridBagConstraints gbc1 = new GridBagConstraints();
+    gbc1.gridx = 1;
+    gbc1.gridwidth = 2;
+    gbc1.fill = GridBagConstraints.HORIZONTAL;
+    gbc1.anchor = GridBagConstraints.WEST;
+    gbc1.weightx = 1.0;
+    filterPanel.add(filterTB, gbc1);
+
+    GridBagConstraints gbc2 = new GridBagConstraints();
+    gbc2.gridx = 3;
+    gbc2.fill = GridBagConstraints.NONE;
+    gbc2.anchor = GridBagConstraints.WEST;
+    filterPanel.add(doReset, gbc2);
+
+    GridBagConstraints gbc3 = new GridBagConstraints();
+    gbc3.gridx = 4;
+    gbc3.fill = GridBagConstraints.NONE;
+    gbc3.anchor = GridBagConstraints.WEST;
+    filterPanel.add(userOnly, gbc3);
+
+    return filterPanel;
+  }
+
+  private JPanel initLinkTabUrlButtons()
+  {
+    // Buttons for new / edit / delete Url links
+    JButton newLink = new JButton();
+    newLink.setText(MessageManager.getString("action.new"));
+
+    editLink.setText(MessageManager.getString("action.edit"));
+
+    deleteLink.setText(MessageManager.getString("action.delete"));
+
+    // no current selection, so initially disable delete/edit buttons
+    editLink.setEnabled(false);
+    deleteLink.setEnabled(false);
+
+    newLink.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
-        annotations_actionPerformed(e);
+        newLink_actionPerformed(e);
       }
     });
-    showUnconserved.setFont(verdana11);
-    showUnconserved.setHorizontalAlignment(SwingConstants.RIGHT);
-    showUnconserved.setHorizontalTextPosition(SwingConstants.LEFT);
-    showUnconserved.setSelected(true);
-    showUnconserved.setText("Show Unconserved");
-    showUnconserved.addActionListener(new ActionListener()
+
+    editLink.setText(MessageManager.getString("action.edit"));
+    editLink.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
-        showunconserved_actionPerformed(e);
+        editLink_actionPerformed(e);
       }
     });
-    // / TODO: fit these in to preferences panel!!!!!
-    shareSelections.setFont(verdana11);
-    shareSelections.setHorizontalAlignment(SwingConstants.RIGHT);
-    shareSelections.setHorizontalTextPosition(SwingConstants.LEFT);
-    shareSelections.setSelected(true);
-    shareSelections.setText("Share selection across views");
-    followHighlight.setFont(verdana11);
-    followHighlight.setHorizontalAlignment(SwingConstants.RIGHT);
-    followHighlight.setHorizontalTextPosition(SwingConstants.LEFT);
-    // showUnconserved.setBounds(new Rectangle(169, 40, 200, 23));
-    followHighlight.setSelected(true);
-    followHighlight.setText("Scroll to highlighted regions");
-
-    gapLabel.setFont(verdana11);
-    gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    gapLabel.setText("Gap Symbol ");
-    colour.setFont(verdana11);
-    colour.setBounds(new Rectangle(172, 225, 155, 21));
-    colourLabel.setFont(verdana11);
-    colourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    colourLabel.setText("Alignment Colour ");
-    fontLabel.setFont(verdana11);
-    fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    fontLabel.setText("Font ");
-    fontSizeCB.setFont(verdana11);
-    fontSizeCB.setBounds(new Rectangle(319, 104, 49, 23));
-    fontStyleCB.setFont(verdana11);
-    fontStyleCB.setBounds(new Rectangle(367, 104, 70, 23));
-    fontNameCB.setFont(verdana11);
-    fontNameCB.setBounds(new Rectangle(172, 104, 147, 23));
-    gapSymbolCB.setFont(verdana11);
-    gapSymbolCB.setBounds(new Rectangle(172, 204, 69, 23));
-    mincolourLabel.setFont(verdana11);
-    mincolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    mincolourLabel.setText("Minimum Colour");
-    minColour.setFont(verdana11);
-    minColour.setBorder(BorderFactory.createEtchedBorder());
-    minColour.setPreferredSize(new Dimension(40, 20));
-    minColour.addMouseListener(new MouseAdapter()
+
+    deleteLink.setText(MessageManager.getString("action.delete"));
+    deleteLink.addActionListener(new java.awt.event.ActionListener()
     {
-      public void mousePressed(MouseEvent e)
+      @Override
+      public void actionPerformed(ActionEvent e)
       {
-          minColour_actionPerformed();
+        deleteLink_actionPerformed(e);
+      }
+    });
+
+    JPanel buttonPanel = new JPanel(new GridBagLayout());
+    buttonPanel.setBorder(new TitledBorder("Edit links"));
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.fill = GridBagConstraints.NONE;
+    buttonPanel.add(newLink, gbc);
+
+    GridBagConstraints gbc1 = new GridBagConstraints();
+    gbc1.gridx = 1;
+    gbc1.gridy = 0;
+    gbc1.fill = GridBagConstraints.NONE;
+    buttonPanel.add(editLink, gbc1);
+
+    GridBagConstraints gbc2 = new GridBagConstraints();
+    gbc2.gridx = 2;
+    gbc2.gridy = 0;
+    gbc2.fill = GridBagConstraints.NONE;
+    buttonPanel.add(deleteLink, gbc2);
+
+    GridBagConstraints gbc3 = new GridBagConstraints();
+    gbc3.gridx = 3;
+    gbc3.gridy = 0;
+    gbc3.fill = GridBagConstraints.HORIZONTAL;
+    gbc3.weightx = 1.0;
+    JPanel spacePanel = new JPanel();
+    spacePanel.setBorder(null);
+    buttonPanel.add(spacePanel, gbc3);
+
+    return buttonPanel;
+  }
+
+  /**
+   * Initialises the proxy server panel in the Connections tab
+   * 
+   * @return the proxy server panel
+   */
+  private JPanel initConnTabProxyPanel()
+  {
+    // Label for server text box
+    serverLabel.setText(MessageManager.getString("label.address"));
+    serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    serverLabel.setFont(LABEL_FONT);
+
+    // Proxy server and port text boxes
+    proxyServerTB.setFont(LABEL_FONT);
+    proxyPortTB.setFont(LABEL_FONT);
+
+    // Label for Port text box
+    portLabel.setFont(LABEL_FONT);
+    portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    portLabel.setText(MessageManager.getString("label.port"));
+
+    // Use proxy server checkbox
+    useProxy.setFont(LABEL_FONT);
+    useProxy.setHorizontalAlignment(SwingConstants.RIGHT);
+    useProxy.setHorizontalTextPosition(SwingConstants.LEADING);
+    useProxy.setText(MessageManager.getString("label.use_proxy_server"));
+    useProxy.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        useProxy_actionPerformed();
+      }
+    });
+
+    // Make proxy server panel
+    JPanel proxyPanel = new JPanel();
+    TitledBorder titledBorder1 = new TitledBorder(
+            MessageManager.getString("label.proxy_server"));
+    proxyPanel.setBorder(titledBorder1);
+    proxyPanel.setLayout(new GridBagLayout());
+    proxyPanel.add(serverLabel,
+            new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.NONE,
+                    new Insets(0, 2, 2, 0), 5, 0));
+    proxyPanel.add(portLabel,
+            new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.NONE,
+                    new Insets(0, 0, 2, 0), 11, 0));
+    proxyPanel.add(useProxy,
+            new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.NONE,
+                    new Insets(0, 2, 5, 185), 2, -4));
+    proxyPanel.add(proxyPortTB,
+            new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+                    new Insets(0, 2, 2, 2), 54, 1));
+    proxyPanel.add(proxyServerTB,
+            new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
+                    GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+                    new Insets(0, 2, 2, 0), 263, 1));
+
+    return proxyPanel;
+  }
+
+  /**
+   * Initialises the checkboxes in the Connections tab
+   */
+  private void initConnTabCheckboxes()
+  {
+    // Usage stats checkbox label
+    usagestats.setText(
+            MessageManager.getString("label.send_usage_statistics"));
+    usagestats.setFont(LABEL_FONT);
+    usagestats.setHorizontalAlignment(SwingConstants.RIGHT);
+    usagestats.setHorizontalTextPosition(SwingConstants.LEADING);
+
+    // Questionnaire checkbox label
+    questionnaire.setText(
+            MessageManager.getString("label.check_for_questionnaires"));
+    questionnaire.setFont(LABEL_FONT);
+    questionnaire.setHorizontalAlignment(SwingConstants.RIGHT);
+    questionnaire.setHorizontalTextPosition(SwingConstants.LEADING);
+
+    // Check for latest version checkbox label
+    versioncheck.setText(
+            MessageManager.getString("label.check_for_latest_version"));
+    versioncheck.setFont(LABEL_FONT);
+    versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
+    versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
+  }
+
+  /**
+   * Initialises the parent panel which contains the tabbed sections.
+   * 
+   * @return
+   */
+  private JPanel initOkCancelPanel()
+  {
+    JButton ok = new JButton();
+    ok.setText(MessageManager.getString("action.ok"));
+    ok.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed(e);
+      }
+    });
+    JButton cancel = new JButton();
+    cancel.setText(MessageManager.getString("action.cancel"));
+    cancel.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        cancel_actionPerformed(e);
+      }
+    });
+    JPanel okCancelPanel = new JPanel();
+    okCancelPanel.add(ok);
+    okCancelPanel.add(cancel);
+    return okCancelPanel;
+  }
+
+  /**
+   * Initialises the Colours tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initColoursTab()
+  {
+    JPanel coloursTab = new JPanel();
+    coloursTab.setBorder(new TitledBorder(
+            MessageManager.getString("action.open_new_alignment")));
+    coloursTab.setLayout(new FlowLayout());
+    JLabel mincolourLabel = new JLabel();
+    mincolourLabel.setFont(LABEL_FONT);
+    mincolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    mincolourLabel.setText(MessageManager.getString("label.min_colour"));
+    minColour.setFont(LABEL_FONT);
+    minColour.setBorder(BorderFactory.createEtchedBorder());
+    minColour.setPreferredSize(new Dimension(40, 20));
+    minColour.addMouseListener(new MouseAdapter()
+    {
+      @Override
+      public void mousePressed(MouseEvent e)
+      {
+        minColour_actionPerformed(minColour);
       }
     });
-    maxcolourLabel.setFont(verdana11);
+    JLabel maxcolourLabel = new JLabel();
+    maxcolourLabel.setFont(LABEL_FONT);
     maxcolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    maxcolourLabel.setText("Maximum Colour ");
-    maxColour.setFont(verdana11);
+    maxcolourLabel.setText(MessageManager.getString("label.max_colour"));
+    maxColour.setFont(LABEL_FONT);
     maxColour.setBorder(BorderFactory.createEtchedBorder());
     maxColour.setPreferredSize(new Dimension(40, 20));
     maxColour.addMouseListener(new MouseAdapter()
     {
+      @Override
+      public void mousePressed(MouseEvent e)
+      {
+        maxColour_actionPerformed(maxColour);
+      }
+    });
+
+    protColour.setFont(LABEL_FONT);
+    protColour.setBounds(new Rectangle(172, 225, 155, 21));
+    JLabel protColourLabel = new JLabel();
+    protColourLabel.setFont(LABEL_FONT);
+    protColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    protColourLabel.setText(
+            MessageManager.getString("label.prot_alignment_colour") + " ");
+    JvSwingUtils.addtoLayout(coloursTab,
+            MessageManager
+                    .getString("label.default_colour_scheme_for_alignment"),
+            protColourLabel, protColour);
+
+    nucColour.setFont(LABEL_FONT);
+    nucColour.setBounds(new Rectangle(172, 240, 155, 21));
+    JLabel nucColourLabel = new JLabel();
+    nucColourLabel.setFont(LABEL_FONT);
+    nucColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    nucColourLabel.setText(
+            MessageManager.getString("label.nuc_alignment_colour") + " ");
+    JvSwingUtils.addtoLayout(coloursTab,
+            MessageManager
+                    .getString("label.default_colour_scheme_for_alignment"),
+            nucColourLabel, nucColour);
+
+    JPanel annotationShding = new JPanel();
+    annotationShding.setBorder(new TitledBorder(
+            MessageManager.getString("label.annotation_shading_default")));
+    annotationShding.setLayout(new GridLayout(1, 2));
+    JvSwingUtils.addtoLayout(annotationShding,
+            MessageManager.getString(
+                    "label.default_minimum_colour_annotation_shading"),
+            mincolourLabel, minColour);
+    JvSwingUtils.addtoLayout(annotationShding,
+            MessageManager.getString(
+                    "label.default_maximum_colour_annotation_shading"),
+            maxcolourLabel, maxColour);
+    coloursTab.add(annotationShding); // , FlowLayout.LEFT);
+    return coloursTab;
+  }
+
+  /**
+   * Initialises the Overview tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initOverviewTab()
+  {
+    JPanel overviewPanel = new JPanel();
+    overviewPanel.setBorder(new TitledBorder(
+            MessageManager.getString("label.overview_settings")));
+
+    gapColour.setFont(LABEL_FONT);
+    // fixing the border colours stops apparent colour bleed from the panel
+    gapColour.setBorder(
+            BorderFactory.createEtchedBorder(Color.white, Color.lightGray));
+    gapColour.setPreferredSize(new Dimension(40, 20));
+    gapColour.addMouseListener(new MouseAdapter()
+    {
+      @Override
       public void mousePressed(MouseEvent e)
       {
-          maxColour_actionPerformed();
+        gapColour_actionPerformed(gapColour);
+      }
+    });
+
+    hiddenColour.setFont(LABEL_FONT);
+    // fixing the border colours stops apparent colour bleed from the panel
+    hiddenColour.setBorder(
+            BorderFactory.createEtchedBorder(Color.white, Color.lightGray));
+    hiddenColour.setPreferredSize(new Dimension(40, 20));
+    hiddenColour.addMouseListener(new MouseAdapter()
+    {
+      @Override
+      public void mousePressed(MouseEvent e)
+      {
+        hiddenColour_actionPerformed(hiddenColour);
+      }
+    });
+
+    useLegacyGap = new JCheckBox(
+            MessageManager.getString("label.ov_legacy_gap"));
+    useLegacyGap.setFont(LABEL_FONT);
+    useLegacyGap.setHorizontalAlignment(SwingConstants.LEFT);
+    useLegacyGap.setVerticalTextPosition(SwingConstants.TOP);
+    gapLabel = new JLabel(MessageManager.getString("label.gap_colour"));
+    gapLabel.setFont(LABEL_FONT);
+    gapLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    gapLabel.setVerticalTextPosition(SwingConstants.TOP);
+    showHiddenAtStart = new JCheckBox(
+            MessageManager.getString("label.ov_show_hide_default"));
+    showHiddenAtStart.setFont(LABEL_FONT);
+    showHiddenAtStart.setHorizontalAlignment(SwingConstants.LEFT);
+    showHiddenAtStart.setVerticalTextPosition(SwingConstants.TOP);
+    JLabel hiddenLabel = new JLabel(
+            MessageManager.getString("label.hidden_colour"));
+    hiddenLabel.setFont(LABEL_FONT);
+    hiddenLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    hiddenLabel.setVerticalTextPosition(SwingConstants.TOP);
+
+    useLegacyGap.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        useLegacyGaps_actionPerformed(e);
+      }
+    });
+
+    overviewPanel.setLayout(new GridBagLayout());
+    GridBagConstraints c1 = new GridBagConstraints();
+
+    c1.fill = GridBagConstraints.HORIZONTAL;
+    c1.gridx = 0;
+    c1.gridy = 0;
+    c1.weightx = 1;
+    c1.ipady = 20;
+    c1.anchor = GridBagConstraints.FIRST_LINE_START;
+    overviewPanel.add(useLegacyGap, c1);
+
+    GridBagConstraints c2 = new GridBagConstraints();
+    c2.fill = GridBagConstraints.HORIZONTAL;
+    c2.gridx = 1;
+    c2.gridy = 0;
+    c2.insets = new Insets(0, 15, 0, 10);
+    overviewPanel.add(gapLabel, c2);
+
+    GridBagConstraints c3 = new GridBagConstraints();
+    c3.fill = GridBagConstraints.HORIZONTAL;
+    c3.gridx = 2;
+    c3.gridy = 0;
+    c3.insets = new Insets(0, 0, 0, 15);
+    overviewPanel.add(gapColour, c3);
+
+    GridBagConstraints c4 = new GridBagConstraints();
+    c4.fill = GridBagConstraints.HORIZONTAL;
+    c4.gridx = 0;
+    c4.gridy = 1;
+    c4.weightx = 1;
+    overviewPanel.add(showHiddenAtStart, c4);
+
+    GridBagConstraints c5 = new GridBagConstraints();
+    c5.fill = GridBagConstraints.HORIZONTAL;
+    c5.gridx = 1;
+    c5.gridy = 1;
+    c5.insets = new Insets(0, 15, 0, 10);
+    overviewPanel.add(hiddenLabel, c5);
+
+    GridBagConstraints c6 = new GridBagConstraints();
+    c6.fill = GridBagConstraints.HORIZONTAL;
+    c6.gridx = 2;
+    c6.gridy = 1;
+    c6.insets = new Insets(0, 0, 0, 15);
+    overviewPanel.add(hiddenColour, c6);
+
+    JButton resetButton = new JButton(
+            MessageManager.getString("label.reset_to_defaults"));
+
+    resetButton.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        resetOvDefaults_actionPerformed(e);
+      }
+    });
+
+    GridBagConstraints c7 = new GridBagConstraints();
+    c7.fill = GridBagConstraints.NONE;
+    c7.gridx = 0;
+    c7.gridy = 2;
+    c7.insets = new Insets(10, 0, 0, 0);
+    c7.anchor = GridBagConstraints.WEST;
+    overviewPanel.add(resetButton, c7);
+
+    // Add padding so the panel doesn't look ridiculous
+    JPanel spacePanel = new JPanel();
+    overviewPanel.add(spacePanel,
+            new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0,
+                    GridBagConstraints.WEST, GridBagConstraints.BOTH,
+                    new Insets(0, 0, 0, 5), 0, 0));
+
+    return overviewPanel;
+  }
+
+  /**
+   * Initialises the Structure tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initStructureTab()
+  {
+    structureTab = new JPanel();
+
+    structureTab.setBorder(new TitledBorder(
+            MessageManager.getString("label.structure_options")));
+    structureTab.setLayout(null);
+    final int width = 400;
+    final int height = 22;
+    final int lineSpacing = 25;
+    int ypos = 15;
+
+    structFromPdb.setFont(LABEL_FONT);
+    structFromPdb
+            .setText(MessageManager.getString("label.struct_from_pdb"));
+    structFromPdb.setBounds(new Rectangle(5, ypos, width, height));
+    structFromPdb.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        boolean selected = structFromPdb.isSelected();
+        // enable other options only when the first is checked
+        useRnaView.setEnabled(selected);
+        addSecondaryStructure.setEnabled(selected);
+        addTempFactor.setEnabled(selected);
+      }
+    });
+    structureTab.add(structFromPdb);
+
+    // indent checkboxes that are conditional on the first one
+    ypos += lineSpacing;
+    useRnaView.setFont(LABEL_FONT);
+    useRnaView.setText(MessageManager.getString("label.use_rnaview"));
+    useRnaView.setBounds(new Rectangle(25, ypos, width, height));
+    structureTab.add(useRnaView);
+
+    ypos += lineSpacing;
+    addSecondaryStructure.setFont(LABEL_FONT);
+    addSecondaryStructure
+            .setText(MessageManager.getString("label.autoadd_secstr"));
+    addSecondaryStructure.setBounds(new Rectangle(25, ypos, width, height));
+    structureTab.add(addSecondaryStructure);
+
+    ypos += lineSpacing;
+    addTempFactor.setFont(LABEL_FONT);
+    addTempFactor.setText(MessageManager.getString("label.autoadd_temp"));
+    addTempFactor.setBounds(new Rectangle(25, ypos, width, height));
+    structureTab.add(addTempFactor);
+
+    ypos += lineSpacing;
+    JLabel viewerLabel = new JLabel();
+    viewerLabel.setFont(LABEL_FONT);
+    viewerLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    viewerLabel.setText(MessageManager.getString("label.structure_viewer"));
+    viewerLabel.setBounds(new Rectangle(10, ypos, 200, height));
+    structureTab.add(viewerLabel);
+
+    structViewer.setFont(LABEL_FONT);
+    structViewer.setBounds(new Rectangle(160, ypos, 120, height));
+    structViewer.addItem(ViewerType.JMOL.name());
+    structViewer.addItem(ViewerType.CHIMERA.name());
+    structViewer.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        structureViewer_actionPerformed(
+                (String) structViewer.getSelectedItem());
+      }
+    });
+    structureTab.add(structViewer);
+
+    ypos += lineSpacing;
+    JLabel pathLabel = new JLabel();
+    pathLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
+    pathLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    pathLabel.setText(MessageManager.getString("label.chimera_path"));
+    pathLabel.setBounds(new Rectangle(10, ypos, 140, height));
+    structureTab.add(pathLabel);
+
+    chimeraPath.setFont(LABEL_FONT);
+    chimeraPath.setText("");
+    final String tooltip = JvSwingUtils.wrapTooltip(true,
+            MessageManager.getString("label.chimera_path_tip"));
+    chimeraPath.setToolTipText(tooltip);
+    chimeraPath.setBounds(new Rectangle(160, ypos, 300, height));
+    chimeraPath.addMouseListener(new MouseAdapter()
+    {
+      @Override
+      public void mouseClicked(MouseEvent e)
+      {
+        if (e.getClickCount() == 2)
+        {
+          String chosen = openFileChooser();
+          if (chosen != null)
+          {
+            chimeraPath.setText(chosen);
+          }
+        }
+      }
+    });
+    structureTab.add(chimeraPath);
+
+    ypos += lineSpacing;
+    nwMapping.setFont(LABEL_FONT);
+    nwMapping.setText(MessageManager.getString("label.nw_mapping"));
+    siftsMapping.setFont(LABEL_FONT);
+    siftsMapping.setText(MessageManager.getString("label.sifts_mapping"));
+    mappingMethod.add(nwMapping);
+    mappingMethod.add(siftsMapping);
+    JPanel mappingPanel = new JPanel();
+    mappingPanel.setFont(LABEL_FONT);
+    TitledBorder mmTitledBorder = new TitledBorder(
+            MessageManager.getString("label.mapping_method"));
+    mmTitledBorder.setTitleFont(LABEL_FONT);
+    mappingPanel.setBorder(mmTitledBorder);
+    mappingPanel.setBounds(new Rectangle(10, ypos, 452, 45));
+    // GridLayout mappingLayout = new GridLayout();
+    mappingPanel.setLayout(new GridLayout());
+    mappingPanel.add(nwMapping);
+    mappingPanel.add(siftsMapping);
+    structureTab.add(mappingPanel);
+
+    ypos += lineSpacing;
+    ypos += lineSpacing;
+    FTSDataColumnPreferences docFieldPref = new FTSDataColumnPreferences(
+            PreferenceSource.PREFERENCES, PDBFTSRestClient.getInstance());
+    docFieldPref.setBounds(new Rectangle(10, ypos, 450, 120));
+    structureTab.add(docFieldPref);
+
+    return structureTab;
+  }
+
+  /**
+   * Action on choosing a structure viewer from combobox options.
+   * 
+   * @param selectedItem
+   */
+  protected void structureViewer_actionPerformed(String selectedItem)
+  {
+  }
+
+  /**
+   * Show a dialog for the user to choose a file. Returns the chosen path, or
+   * null on Cancel.
+   * 
+   * @return
+   */
+  protected String openFileChooser()
+  {
+    String choice = null;
+    JFileChooser chooser = new JFileChooser();
+
+    // chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle(
+            MessageManager.getString("label.open_local_file"));
+    chooser.setToolTipText(MessageManager.getString("action.open"));
+
+    int value = chooser.showOpenDialog(this);
+
+    if (value == JFileChooser.APPROVE_OPTION)
+    {
+      choice = chooser.getSelectedFile().getPath();
+    }
+    return choice;
+  }
+
+  /**
+   * Validate the structure tab preferences; if invalid, set focus on this tab.
+   * 
+   * @param e
+   */
+  protected boolean validateStructure(FocusEvent e)
+  {
+    if (!validateStructure())
+    {
+      e.getComponent().requestFocusInWindow();
+      return false;
+    }
+    return true;
+  }
+
+  protected boolean validateStructure()
+  {
+    return false;
+  }
+
+  /**
+   * Initialises the Visual tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initVisualTab()
+  {
+    JPanel visualTab = new JPanel();
+    visualTab.setBorder(new TitledBorder(
+            MessageManager.getString("action.open_new_alignment")));
+    visualTab.setLayout(null);
+    fullScreen.setFont(LABEL_FONT);
+    fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);
+    fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);
+    fullScreen.setText(MessageManager.getString("label.maximize_window"));
+    quality.setEnabled(false);
+    quality.setFont(LABEL_FONT);
+    quality.setHorizontalAlignment(SwingConstants.RIGHT);
+    quality.setHorizontalTextPosition(SwingConstants.LEFT);
+    quality.setSelected(true);
+    quality.setText(MessageManager.getString("label.quality"));
+    conservation.setEnabled(false);
+    conservation.setFont(LABEL_FONT);
+    conservation.setHorizontalAlignment(SwingConstants.RIGHT);
+    conservation.setHorizontalTextPosition(SwingConstants.LEFT);
+    conservation.setSelected(true);
+    conservation.setText(MessageManager.getString("label.conservation"));
+    identity.setEnabled(false);
+    identity.setFont(LABEL_FONT);
+    identity.setHorizontalAlignment(SwingConstants.RIGHT);
+    identity.setHorizontalTextPosition(SwingConstants.LEFT);
+    identity.setSelected(true);
+    identity.setText(MessageManager.getString("label.consensus"));
+    showOccupancy.setFont(LABEL_FONT);
+    showOccupancy.setEnabled(false);
+    showOccupancy.setHorizontalAlignment(SwingConstants.RIGHT);
+    showOccupancy.setHorizontalTextPosition(SwingConstants.LEFT);
+    showOccupancy.setSelected(true);
+    showOccupancy.setText(MessageManager.getString("label.occupancy"));
+
+    JLabel showGroupbits = new JLabel();
+    showGroupbits.setFont(LABEL_FONT);
+    showGroupbits.setHorizontalAlignment(SwingConstants.RIGHT);
+    showGroupbits.setHorizontalTextPosition(SwingConstants.LEFT);
+    showGroupbits
+            .setText(MessageManager.getString("action.show_group") + ":");
+    JLabel showConsensbits = new JLabel();
+    showConsensbits.setFont(LABEL_FONT);
+    showConsensbits.setHorizontalAlignment(SwingConstants.RIGHT);
+    showConsensbits.setHorizontalTextPosition(SwingConstants.LEFT);
+    showConsensbits
+            .setText(MessageManager.getString("label.consensus") + ":");
+    showConsensHistogram.setEnabled(false);
+    showConsensHistogram.setFont(LABEL_FONT);
+    showConsensHistogram.setHorizontalAlignment(SwingConstants.RIGHT);
+    showConsensHistogram.setHorizontalTextPosition(SwingConstants.LEFT);
+    showConsensHistogram.setSelected(true);
+    showConsensHistogram
+            .setText(MessageManager.getString("label.histogram"));
+    showConsensLogo.setEnabled(false);
+    showConsensLogo.setFont(LABEL_FONT);
+    showConsensLogo.setHorizontalAlignment(SwingConstants.RIGHT);
+    showConsensLogo.setHorizontalTextPosition(SwingConstants.LEFT);
+    showConsensLogo.setSelected(true);
+    showConsensLogo.setText(MessageManager.getString("label.logo"));
+    showGroupConsensus.setEnabled(false);
+    showGroupConsensus.setFont(LABEL_FONT);
+    showGroupConsensus.setHorizontalAlignment(SwingConstants.RIGHT);
+    showGroupConsensus.setHorizontalTextPosition(SwingConstants.LEFT);
+    showGroupConsensus.setSelected(true);
+    showGroupConsensus.setText(MessageManager.getString("label.consensus"));
+    showGroupConservation.setEnabled(false);
+    showGroupConservation.setFont(LABEL_FONT);
+    showGroupConservation.setHorizontalAlignment(SwingConstants.RIGHT);
+    showGroupConservation.setHorizontalTextPosition(SwingConstants.LEFT);
+    showGroupConservation.setSelected(true);
+    showGroupConservation
+            .setText(MessageManager.getString("label.conservation"));
+    showNpTooltip.setEnabled(true);
+    showNpTooltip.setFont(LABEL_FONT);
+    showNpTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
+    showNpTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
+    showNpTooltip.setSelected(true);
+    showNpTooltip.setText(
+            MessageManager.getString("label.non_positional_features"));
+    showDbRefTooltip.setEnabled(true);
+    showDbRefTooltip.setFont(LABEL_FONT);
+    showDbRefTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
+    showDbRefTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
+    showDbRefTooltip.setSelected(true);
+    showDbRefTooltip
+            .setText(MessageManager.getString("label.database_references"));
+    annotations.setFont(LABEL_FONT);
+    annotations.setHorizontalAlignment(SwingConstants.RIGHT);
+    annotations.setHorizontalTextPosition(SwingConstants.LEFT);
+    annotations.setSelected(true);
+    annotations.setText(MessageManager.getString("label.show_annotations"));
+    // annotations.setBounds(new Rectangle(169, 12, 200, 23));
+    annotations.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        annotations_actionPerformed(e);
+      }
+    });
+    identity.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        annotations_actionPerformed(e);
+      }
+    });
+    showGroupConsensus.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        annotations_actionPerformed(e);
       }
     });
-    
-    startupCheckbox.setText("Open file");
-    startupCheckbox.setFont(verdana11);
+    showUnconserved.setFont(LABEL_FONT);
+    showUnconserved.setHorizontalAlignment(SwingConstants.RIGHT);
+    showUnconserved.setHorizontalTextPosition(SwingConstants.LEFT);
+    showUnconserved.setSelected(true);
+    showUnconserved
+            .setText(MessageManager.getString("action.show_unconserved"));
+    showUnconserved.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        showunconserved_actionPerformed(e);
+      }
+    });
+
+    // TODO these are not yet added to / action from Preferences
+    // JCheckBox shareSelections = new JCheckBox();
+    // shareSelections.setFont(verdana11);
+    // shareSelections.setHorizontalAlignment(SwingConstants.RIGHT);
+    // shareSelections.setHorizontalTextPosition(SwingConstants.LEFT);
+    // shareSelections.setSelected(true);
+    // shareSelections.setText(MessageManager
+    // .getString("label.share_selection_across_views"));
+    // JCheckBox followHighlight = new JCheckBox();
+    // followHighlight.setFont(verdana11);
+    // followHighlight.setHorizontalAlignment(SwingConstants.RIGHT);
+    // followHighlight.setHorizontalTextPosition(SwingConstants.LEFT);
+    // // showUnconserved.setBounds(new Rectangle(169, 40, 200, 23));
+    // followHighlight.setSelected(true);
+    // followHighlight.setText(MessageManager
+    // .getString("label.scroll_highlighted_regions"));
+
+    seqLimit.setFont(LABEL_FONT);
+    seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);
+    seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);
+    seqLimit.setText(MessageManager.getString("label.full_sequence_id"));
+    smoothFont.setFont(LABEL_FONT);
+    smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);
+    smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);
+    smoothFont.setText(MessageManager.getString("label.smooth_font"));
+    scaleProteinToCdna.setFont(LABEL_FONT);
+    scaleProteinToCdna.setHorizontalAlignment(SwingConstants.RIGHT);
+    scaleProteinToCdna.setHorizontalTextPosition(SwingConstants.LEADING);
+    scaleProteinToCdna.setText(
+            MessageManager.getString("label.scale_protein_to_cdna"));
+    scaleProteinToCdna.setToolTipText(
+            MessageManager.getString("label.scale_protein_to_cdna_tip"));
+    JLabel gapLabel = new JLabel();
+    gapLabel.setFont(LABEL_FONT);
+    gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    gapLabel.setText(MessageManager.getString("label.gap_symbol") + " ");
+    JLabel fontLabel = new JLabel();
+    fontLabel.setFont(LABEL_FONT);
+    fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    fontLabel.setText(MessageManager.getString("label.font"));
+    fontSizeCB.setFont(LABEL_FONT);
+    fontSizeCB.setBounds(new Rectangle(320, 112, 65, 23));
+    fontStyleCB.setFont(LABEL_FONT);
+    fontStyleCB.setBounds(new Rectangle(382, 112, 80, 23));
+    fontNameCB.setFont(LABEL_FONT);
+    fontNameCB.setBounds(new Rectangle(172, 112, 147, 23));
+    gapSymbolCB.setFont(LABEL_FONT);
+    gapSymbolCB.setBounds(new Rectangle(172, 215, 69, 23));
+    DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
+    dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
+    gapSymbolCB.setRenderer(dlcr);
+
+    startupCheckbox.setText(MessageManager.getString("action.open_file"));
+    startupCheckbox.setFont(LABEL_FONT);
     startupCheckbox.setHorizontalAlignment(SwingConstants.RIGHT);
     startupCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
     startupCheckbox.setSelected(true);
-    startupFileTextfield.setFont(verdana11);
-    startupFileTextfield.setBounds(new Rectangle(172, 273, 270, 20));
+    startupFileTextfield.setFont(LABEL_FONT);
+    startupFileTextfield.setBounds(new Rectangle(172, 310, 330, 20));
+    final String tooltip = JvSwingUtils.wrapTooltip(true,
+            MessageManager.getString("label.double_click_to_browse"));
+    startupFileTextfield.setToolTipText(tooltip);
     startupFileTextfield.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mouseClicked(MouseEvent e)
       {
         if (e.getClickCount() > 1)
@@ -468,355 +1587,1093 @@ public class GPreferences extends JPanel
       }
     });
 
-    connectTab.setLayout(gridBagLayout3);
-    serverLabel.setText("Address");
-    serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    serverLabel.setFont(verdana11);
-    proxyServerTB.setFont(verdana11);
-    proxyPortTB.setFont(verdana11);
-    portLabel.setFont(verdana11);
-    portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    portLabel.setText("Port");
-    browserLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
-    browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
-    browserLabel.setText("Default Browser (Unix)");
-    defaultBrowser.setFont(verdana11);
-    defaultBrowser.setText("");
-    usagestats.setText("Send usage statistics");
-    usagestats.setFont(verdana11);
-    usagestats.setHorizontalAlignment(SwingConstants.RIGHT);
-    usagestats.setHorizontalTextPosition(SwingConstants.LEADING);
-    questionnaire.setText("Check for questionnaires");
-    questionnaire.setFont(verdana11);
-    questionnaire.setHorizontalAlignment(SwingConstants.RIGHT);
-    questionnaire.setHorizontalTextPosition(SwingConstants.LEADING);
-    versioncheck.setText("Check for latest version");
-    versioncheck.setFont(verdana11);
-    versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
-    versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
-    newLink.setText("New");
-    newLink.addActionListener(new java.awt.event.ActionListener()
+    sortby.setFont(LABEL_FONT);
+    sortby.setBounds(new Rectangle(172, 260, 155, 21));
+    JLabel sortLabel = new JLabel();
+    sortLabel.setFont(LABEL_FONT);
+    sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    sortLabel.setText(MessageManager.getString("label.sort_by"));
+    sortAnnBy.setFont(LABEL_FONT);
+    sortAnnBy.setBounds(new Rectangle(172, 285, 110, 21));
+    JLabel sortAnnLabel = new JLabel();
+    sortAnnLabel.setFont(LABEL_FONT);
+    sortAnnLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+    sortAnnLabel.setText(MessageManager.getString("label.sort_ann_by"));
+    sortAutocalc.setFont(LABEL_FONT);
+    sortAutocalc.setBounds(new Rectangle(290, 285, 165, 21));
+
+    JPanel annsettingsPanel = new JPanel();
+    annsettingsPanel.setBounds(new Rectangle(173, 13, 320, 96));
+    annsettingsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+    annsettingsPanel.setBorder(new EtchedBorder());
+    visualTab.add(annsettingsPanel);
+    Border jb = new EmptyBorder(1, 1, 4, 5);
+    annotations.setBorder(jb);
+    showOccupancy.setBorder(jb);
+    quality.setBorder(jb);
+    conservation.setBorder(jb);
+    identity.setBorder(jb);
+    showConsensbits.setBorder(jb);
+    showGroupbits.setBorder(jb);
+    showGroupConsensus.setBorder(jb);
+    showGroupConservation.setBorder(jb);
+    showConsensHistogram.setBorder(jb);
+    showConsensLogo.setBorder(jb);
+
+    JPanel autoAnnotSettings = new JPanel();
+    annsettingsPanel.add(autoAnnotSettings);
+    autoAnnotSettings.setLayout(new GridLayout(0, 2));
+    autoAnnotSettings.add(annotations);
+    autoAnnotSettings.add(quality);
+    // second row of autoannotation box
+    autoAnnotSettings = new JPanel();
+    annsettingsPanel.add(autoAnnotSettings);
+
+    autoAnnotSettings.setLayout(new GridLayout(0, 3));
+    autoAnnotSettings.add(conservation);
+    autoAnnotSettings.add(identity);
+    autoAnnotSettings.add(showOccupancy);
+    autoAnnotSettings.add(showGroupbits);
+    autoAnnotSettings.add(showGroupConservation);
+    autoAnnotSettings.add(showGroupConsensus);
+    autoAnnotSettings.add(showConsensbits);
+    autoAnnotSettings.add(showConsensHistogram);
+    autoAnnotSettings.add(showConsensLogo);
+
+    JPanel tooltipSettings = new JPanel();
+    tooltipSettings.setBorder(new TitledBorder(
+            MessageManager.getString("label.sequence_id_tooltip")));
+    tooltipSettings.setBounds(173, 140, 220, 62);
+    tooltipSettings.setLayout(new GridLayout(2, 1));
+    tooltipSettings.add(showDbRefTooltip);
+    tooltipSettings.add(showNpTooltip);
+    visualTab.add(tooltipSettings);
+
+    wrap.setFont(LABEL_FONT);
+    wrap.setHorizontalAlignment(SwingConstants.TRAILING);
+    wrap.setHorizontalTextPosition(SwingConstants.LEADING);
+    wrap.setText(MessageManager.getString("label.wrap_alignment"));
+    rightAlign.setFont(LABEL_FONT);
+    rightAlign.setForeground(Color.black);
+    rightAlign.setHorizontalAlignment(SwingConstants.RIGHT);
+    rightAlign.setHorizontalTextPosition(SwingConstants.LEFT);
+    rightAlign.setText(MessageManager.getString("label.right_align_ids"));
+    idItalics.setFont(LABEL_FONT_ITALIC);
+    idItalics.setHorizontalAlignment(SwingConstants.RIGHT);
+    idItalics.setHorizontalTextPosition(SwingConstants.LEADING);
+    idItalics.setText(
+            MessageManager.getString("label.sequence_name_italics"));
+    openoverv.setFont(LABEL_FONT);
+    openoverv.setActionCommand(
+            MessageManager.getString("label.open_overview"));
+    openoverv.setHorizontalAlignment(SwingConstants.RIGHT);
+    openoverv.setHorizontalTextPosition(SwingConstants.LEFT);
+    openoverv.setText(MessageManager.getString("label.open_overview"));
+    JPanel jPanel2 = new JPanel();
+    jPanel2.setBounds(new Rectangle(7, 17, 158, 310));
+    jPanel2.setLayout(new GridLayout(14, 1));
+    jPanel2.add(fullScreen);
+    jPanel2.add(openoverv);
+    jPanel2.add(seqLimit);
+    jPanel2.add(rightAlign);
+    jPanel2.add(fontLabel);
+    jPanel2.add(showUnconserved);
+    jPanel2.add(idItalics);
+    jPanel2.add(smoothFont);
+    jPanel2.add(scaleProteinToCdna);
+    jPanel2.add(gapLabel);
+    jPanel2.add(wrap);
+    jPanel2.add(sortLabel);
+    jPanel2.add(sortAnnLabel);
+    jPanel2.add(startupCheckbox);
+    visualTab.add(jPanel2);
+    visualTab.add(startupFileTextfield);
+    visualTab.add(sortby);
+    visualTab.add(sortAnnBy);
+    visualTab.add(sortAutocalc);
+    visualTab.add(gapSymbolCB);
+    visualTab.add(fontNameCB);
+    visualTab.add(fontSizeCB);
+    visualTab.add(fontStyleCB);
+    return visualTab;
+  }
+
+  /**
+   * Load the saved Backups options EXCEPT "Enabled" and "Scheme"
+   */
+
+  protected void loadLastSavedBackupsOptions()
+  {
+    BackupFilesPresetEntry savedPreset = BackupFilesPresetEntry
+            .getSavedBackupEntry();
+    enableBackupFiles
+            .setSelected(Cache.getDefault(BackupFiles.ENABLED, true));
+
+    BackupFilesPresetEntry backupfilesCustomEntry = BackupFilesPresetEntry
+            .createBackupFilesPresetEntry(Cache
+                    .getDefault(BackupFilesPresetEntry.CUSTOMCONFIG, null));
+    if (backupfilesCustomEntry == null)
+    {
+      backupfilesCustomEntry = BackupFilesPresetEntry.backupfilesPresetEntriesValues
+              .get(BackupFilesPresetEntry.BACKUPFILESSCHEMEDEFAULT);
+    }
+    BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
+            BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM,
+            backupfilesCustomEntry);
+
+    setComboIntStringKey(backupfilesPresetsCombo,
+            Cache.getDefault(BackupFiles.NS + "_PRESET",
+                    BackupFilesPresetEntry.BACKUPFILESSCHEMEDEFAULT));
+
+    backupsSetOptions(savedPreset);
+
+    backupsOptionsSetEnabled();
+    updateBackupFilesExampleLabel();
+  }
+
+  private boolean warnAboutSuffixReverseChange()
+  {
+    BackupFilesPresetEntry bfpe = BackupFilesPresetEntry
+            .getSavedBackupEntry();
+    boolean savedSuffixReverse = bfpe.reverse;
+    int savedSuffixDigits = bfpe.digits;
+    String savedSuffixTemplate = bfpe.suffix;
+
+    boolean nowSuffixReverse = suffixReverse.isSelected();
+    int nowSuffixDigits = getSpinnerInt(suffixDigitsSpinner, 3);
+    String nowSuffixTemplate = suffixTemplate.getText();
+    return nowSuffixReverse != savedSuffixReverse
+            && nowSuffixDigits == savedSuffixDigits
+            && nowSuffixTemplate != null
+            && nowSuffixTemplate.equals(savedSuffixTemplate);
+  }
+
+  /**
+   * Initialises the Backups tabbed panel.
+   * 
+   * @return
+   */
+  private JPanel initBackupsTab()
+  {
+    JPanel backupsTab = new JPanel();
+    backupsTab.setBorder(new TitledBorder(
+            MessageManager.getString("label.backup_files")));
+    backupsTab.setLayout(new GridBagLayout());
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 0.0;
+    gbc.weighty = 0.0;
+    gbc.anchor = GridBagConstraints.FIRST_LINE_START;
+    gbc.fill = GridBagConstraints.NONE;
+
+    initBackupsTabPresetsPanel();
+    initBackupsTabSuffixPanel();
+    initBackupsTabKeepFilesPanel();
+    initBackupsTabFilenameExamplesPanel();
+
+    enableBackupFiles.setFont(LABEL_FONT_BOLD);
+    enableBackupFiles
+            .setText(MessageManager.getString("label.enable_backupfiles"));
+    enableBackupFiles.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        // enable other options only when the first is checked
+        backupsOptionsSetEnabled();
+      }
+    });
+
+
+    // enable checkbox 1 col
+    gbc.gridwidth = 1;
+    gbc.gridheight = 1;
+    gbc.gridx = 0;
+    gbc.gridy = 0; // row 0
+    backupsTab.add(enableBackupFiles, gbc);
+
+    // summary of scheme box (over two rows)
+    gbc.gridx = 1;
+    gbc.weightx = 0.0;
+    gbc.gridheight = 2;
+    gbc.anchor = GridBagConstraints.FIRST_LINE_END;
+    gbc.fill = GridBagConstraints.BOTH;
+    backupsTab.add(exampleFilesPanel, gbc);
+    gbc.gridheight = 1;
+    gbc.anchor = GridBagConstraints.FIRST_LINE_START;
+    gbc.fill = GridBagConstraints.NONE;
+
+    // fill empty space on right
+    gbc.gridx++;
+    gbc.weightx = 1.0;
+    backupsTab.add(new JPanel(), gbc);
+
+    // schemes box
+    gbc.weightx = 0.0;
+    gbc.gridx = 0;
+    gbc.gridy++; // row 1
+    backupsTab.add(presetsPanel, gbc);
+
+    // now using whole row
+    gbc.gridwidth = 2;
+    gbc.gridheight = 1;
+    // keep files box
+    gbc.gridx = 0;
+    gbc.gridy++; // row 2
+    backupsTab.add(keepfilesPanel, gbc);
+
+    // filename strategy box
+    gbc.gridy++; // row 3
+    backupsTab.add(suffixPanel, gbc);
+
+    // fill empty space
+    gbc.gridy++; // row 4
+    gbc.weighty = 1.0;
+    backupsTab.add(new JPanel(), gbc);
+
+    backupsOptionsSetEnabled();
+    return backupsTab;
+  }
+
+  private JPanel initBackupsTabPresetsPanel()
+  {
+
+    String title = MessageManager.getString("label.schemes");
+
+    presetsPanel.setLayout(new GridBagLayout());
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 0.0;
+    gbc.weighty = 0.0;
+    gbc.anchor = GridBagConstraints.BASELINE_LEADING;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.gridwidth = 1;
+    gbc.gridheight = 1;
+
+    // "Scheme: "
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+
+    presetsComboLabel = new JLabel(title + ":");
+    presetsPanel.add(presetsComboLabel, gbc);
+
+    List<Object> entries = Arrays
+            .asList((Object[]) BackupFilesPresetEntry.backupfilesPresetEntries);
+    List<String> tooltips = Arrays.asList(
+            BackupFilesPresetEntry.backupfilesPresetEntryDescriptions);
+    backupfilesPresetsCombo = JvSwingUtils.buildComboWithTooltips(entries,
+            tooltips);
+    /*
+    for (int i = 0; i < BackupFilesPresetEntry.backupfilesPresetEntries.length; i++)
+    {
+      backupfilesPresetsCombo
+              .addItem(BackupFilesPresetEntry.backupfilesPresetEntries[i]);
+    }
+    */
+
+    backupfilesPresetsCombo.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        int key = getComboIntStringKey(backupfilesPresetsCombo);
+        if (!customiseCheckbox.isSelected())
+        {
+          backupfilesPresetsComboLastSelected = key;
+        }
+        if (key == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
+        {
+          if (customiseCheckbox.isSelected())
+          {
+            // got here by clicking on customiseCheckbox so don't change the values
+            backupfilesCustomOptionsSetEnabled();
+          }
+          else
+          {
+            backupsTabUpdatePresets();
+            backupfilesCustomOptionsSetEnabled();
+          }
+        }
+        else
+        {
+          customiseCheckbox.setSelected(false);
+          backupsTabUpdatePresets();
+          backupfilesCustomOptionsSetEnabled();
+        }
+      }
+    });
+
+    // dropdown list of preset schemes
+    gbc.gridx = 1;
+    presetsPanel.add(backupfilesPresetsCombo, gbc);
+
+    revertButton.setText(MessageManager.getString("label.cancel_changes"));
+    revertButton.setToolTipText(
+            MessageManager.getString("label.cancel_changes_description"));
+    revertButton.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        backupsSetOptions(
+                BackupFilesPresetEntry.backupfilesPresetEntriesValues.get(
+                        BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM));
+        backupfilesCustomOptionsSetEnabled();
+      }
+
+    });
+    revertButton.setFont(LABEL_FONT);
+
+    customiseCheckbox.setFont(LABEL_FONT);
+    customiseCheckbox.setText(MessageManager.getString("label.customise"));
+    customiseCheckbox.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        int currently = getComboIntStringKey(backupfilesPresetsCombo);
+        if (customiseCheckbox.isSelected())
+        {
+          backupfilesPresetsComboLastSelected = currently;
+          setComboIntStringKey(backupfilesPresetsCombo,
+                  BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM);
+        }
+        else
+        {
+          setComboIntStringKey(backupfilesPresetsCombo,
+                  backupfilesPresetsComboLastSelected);
+
+        }
+        backupfilesCustomOptionsSetEnabled();
+      }
+    });
+    customiseCheckbox.setToolTipText(
+            MessageManager.getString("label.customise_description"));
+
+    // customise checkbox
+    gbc.gridx = 0;
+    gbc.gridy++;
+    presetsPanel.add(customiseCheckbox, gbc);
+
+    // "Cancel changes" button (aligned with combo box above)
+    gbc.gridx = 1;
+    presetsPanel.add(revertButton, gbc);
+
+    return presetsPanel;
+  }
+
+  private JPanel initBackupsTabFilenameExamplesPanel()
+  {
+    String title = MessageManager
+            .getString("label.scheme_examples");
+    TitledBorder tb = new TitledBorder(title);
+    exampleFilesPanel.setBorder(tb);
+    exampleFilesPanel.setLayout(new GridBagLayout());
+
+
+    backupfilesExampleLabel.setEditable(false);
+    backupfilesExampleLabel
+            .setBackground(exampleFilesPanel.getBackground());
+
+    updateBackupFilesExampleLabel();
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 1.0;
+    gbc.weighty = 1.0;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.anchor = GridBagConstraints.FIRST_LINE_START;
+
+    exampleFilesPanel.add(backupfilesExampleLabel, gbc);
+    return exampleFilesPanel;
+  }
+
+  private void backupsTabUpdatePresets()
+  {
+    IntKeyStringValueEntry entry = (IntKeyStringValueEntry) backupfilesPresetsCombo
+            .getSelectedItem();
+    int key = entry.k;
+    String value = entry.v;
+
+    if (BackupFilesPresetEntry.backupfilesPresetEntriesValues
+            .containsKey(key))
+    {
+      backupsSetOptions(
+              BackupFilesPresetEntry.backupfilesPresetEntriesValues
+                      .get(key));
+    }
+    else
+    {
+      Cache.log.error(
+              "Preset '" + value + "' [key:" + key + "] not implemented");
+    }
+
+    // Custom options will now be enabled when the customiseCheckbox is checked
+    // (performed above)
+    // backupfilesCustomOptionsSetEnabled();
+    updateBackupFilesExampleLabel();
+  }
+
+  protected int getComboIntStringKey(
+          JComboBox<Object> backupfilesPresetsCombo2)
+  {
+    IntKeyStringValueEntry e;
+    try
+    {
+      e = (IntKeyStringValueEntry) backupfilesPresetsCombo2
+              .getSelectedItem();
+    } catch (Exception ex)
+    {
+      Cache.log.error(
+              "Problem casting Combo entry to IntKeyStringValueEntry.");
+      e = null;
+    }
+    return e != null ? e.k : 0;
+  }
+
+  protected void setComboIntStringKey(
+          JComboBox<Object> backupfilesPresetsCombo2,
+          int key)
+  {
+    for (int i = 0; i < backupfilesPresetsCombo2.getItemCount(); i++)
+    {
+      IntKeyStringValueEntry e;
+      try
+      {
+        e = (IntKeyStringValueEntry) backupfilesPresetsCombo2.getItemAt(i);
+      } catch (Exception ex)
+      {
+        Cache.log.error(
+                "Problem casting Combo entry to IntKeyStringValueEntry. Skipping item. ");
+        continue;
+      }
+      if (e.k == key)
+      {
+        backupfilesPresetsCombo2.setSelectedIndex(i);
+        break;
+      }
+    }
+    // backupsTabUpdatePresets();
+  }
+
+  private JPanel initBackupsTabSuffixPanel()
+  {
+    suffixPanel.setBorder(new TitledBorder(
+            MessageManager.getString("label.backup_filename_strategy")));
+    suffixPanel.setLayout(new GridBagLayout());
+
+    suffixTemplateLabel
+            .setText(MessageManager.getString("label.append_to_filename"));
+    suffixTemplateLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    suffixTemplateLabel.setFont(LABEL_FONT);
+
+    final String tooltip = JvSwingUtils.wrapTooltip(true,
+            MessageManager.getString("label.append_to_filename_tooltip"));
+    suffixTemplate.setToolTipText(tooltip);
+    suffixTemplate.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        updateBackupFilesExampleLabel();
+        backupfilesCustomOptionsSetEnabled();
+        backupfilesRevertButtonSetEnabled(true);
+      }
+
+    });
+    suffixTemplate.addKeyListener(new KeyListener()
+    {
+      @Override
+      public void keyReleased(KeyEvent e)
+      {
+        updateBackupFilesExampleLabel();
+        backupfilesCustomOptionsSetEnabled();
+        backupfilesRevertButtonSetEnabled(true);
+      }
+
+      @Override
+      public void keyPressed(KeyEvent e)
+      {
+      }
+
+      // disable use of ':' or '/' or '\'
+      @Override
+      public void keyTyped(KeyEvent e)
+      {
+        char c = e.getKeyChar();
+        if (c == ':' || c == '/' || c == '\\')
+        {
+          // don't process ':' or '/' or '\'
+          e.consume();
+        }
+      }
+
+    });
+
+    // digits spinner
+    suffixDigitsLabel
+            .setText(MessageManager.getString("label.index_digits"));
+    suffixDigitsLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    suffixDigitsLabel.setFont(LABEL_FONT);
+    ChangeListener c = new ChangeListener()
+    {
+      @Override
+      public void stateChanged(ChangeEvent e)
+      {
+        backupfilesRevertButtonSetEnabled(true);
+        updateBackupFilesExampleLabel();
+      }
+
+    };
+    setIntegerSpinner(suffixDigitsSpinner, BackupFilesPresetEntry.DIGITSMIN,
+            BackupFilesPresetEntry.DIGITSMAX, 3, c);
+
+    suffixReverse.setLabels(MessageManager.getString("label.reverse_roll"),
+            MessageManager.getString("label.increment_index"));
+    suffixReverse.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        boolean okay = true;
+        if (warnAboutSuffixReverseChange())
+        {
+          // Warning popup
+          okay = confirmSuffixReverseChange();
+        }
+        if (okay)
+        {
+          backupfilesRevertButtonSetEnabled(true);
+          updateBackupFilesExampleLabel();
+        }
+        else
+        {
+          boolean savedSuffixReverse = BackupFilesPresetEntry
+                  .getSavedBackupEntry().reverse;
+          suffixReverse.setSelected(savedSuffixReverse);
+        }
+      }
+    });
+
+    GridBagConstraints sgbc = new GridBagConstraints();
+
+    // first row (template text box)
+    sgbc.anchor = GridBagConstraints.WEST;
+    sgbc.gridx = 0;
+    sgbc.gridy = 0;
+    sgbc.gridwidth = 1;
+    sgbc.gridheight = 1;
+    sgbc.weightx = 1.0;
+    sgbc.weighty = 0.0;
+    sgbc.fill = GridBagConstraints.NONE;
+    suffixPanel.add(suffixTemplateLabel, sgbc);
+
+    sgbc.gridx = 1;
+    sgbc.fill = GridBagConstraints.HORIZONTAL;
+    suffixPanel.add(suffixTemplate, sgbc);
+
+    // second row (number of digits spinner)
+    sgbc.gridy = 1;
+
+    sgbc.gridx = 0;
+    sgbc.fill = GridBagConstraints.NONE;
+    suffixPanel.add(suffixDigitsLabel, sgbc);
+
+    sgbc.gridx = 1;
+    sgbc.fill = GridBagConstraints.HORIZONTAL;
+    suffixPanel.add(suffixDigitsSpinner, sgbc);
+
+    // third row (forward order radio selection)
+    sgbc.gridx = 0;
+    sgbc.gridy = 2;
+    sgbc.gridwidth = GridBagConstraints.REMAINDER;
+    sgbc.fill = GridBagConstraints.HORIZONTAL;
+    suffixPanel.add(suffixReverse.getFalseButton(), sgbc);
+
+    // fourth row (reverse order radio selection)
+    sgbc.gridy = 3;
+    suffixPanel.add(suffixReverse.getTrueButton(), sgbc);
+    return suffixPanel;
+  }
+
+  private boolean confirmSuffixReverseChange()
+  {
+    boolean ret = false;
+    String warningMessage = MessageManager
+            .getString("label.warning_confirm_change_reverse");
+    int confirm = JvOptionPane.showConfirmDialog(Desktop.desktop,
+            warningMessage,
+            MessageManager.getString("label.change_increment_decrement"),
+            JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE);
+
+    ret = (confirm == JvOptionPane.YES_OPTION);
+    return ret;
+  }
+
+  private JPanel initBackupsTabKeepFilesPanel()
+  {
+    keepfilesPanel.setBorder(
+            new TitledBorder(MessageManager.getString("label.keep_files")));
+    keepfilesPanel.setLayout(new GridBagLayout());
+
+    backupfilesKeepAll.setLabels(
+            MessageManager.getString("label.keep_all_backup_files"),
+            MessageManager.getString(
+                    "label.keep_only_this_number_of_backup_files"));
+    backupfilesKeepAll.addTrueActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
-        newLink_actionPerformed(e);
+        backupfilesRevertButtonSetEnabled(true);
+        updateBackupFilesExampleLabel();
       }
     });
-    editLink.setText("Edit");
-    editLink.addActionListener(new java.awt.event.ActionListener()
+    backupfilesKeepAll.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
-        editLink_actionPerformed(e);
+        backupfilesRevertButtonSetEnabled(true);
+        keepRollMaxOptionsEnabled();
+        updateBackupFilesExampleLabel();
       }
     });
-    deleteLink.setText("Delete");
-    deleteLink.addActionListener(new java.awt.event.ActionListener()
+
+    ChangeListener c = new ChangeListener()
     {
-      public void actionPerformed(ActionEvent e)
+      @Override
+      public void stateChanged(ChangeEvent e)
       {
-        deleteLink_actionPerformed(e);
+        backupfilesRevertButtonSetEnabled(true);
+        updateBackupFilesExampleLabel();
       }
-    });
 
-    linkURLList.addListSelectionListener(new ListSelectionListener()
+    };
+    setIntegerSpinner(backupfilesRollMaxSpinner,
+            BackupFilesPresetEntry.ROLLMAXMIN,
+            BackupFilesPresetEntry.ROLLMAXMAX, 4, true, c);
+
+    backupfilesConfirmDelete.setLabels(
+            MessageManager.getString("label.always_ask"),
+            MessageManager.getString("label.auto_delete"));
+    backupfilesConfirmDelete.addActionListener(new ActionListener()
     {
-      public void valueChanged(ListSelectionEvent e)
+      @Override
+      public void actionPerformed(ActionEvent e)
       {
-        int index = linkURLList.getSelectedIndex();
-        linkNameList.setSelectedIndex(index);
+        backupfilesRevertButtonSetEnabled(true);
       }
     });
+    // update the enabled section
+    keepRollMaxOptionsEnabled();
+
+    GridBagConstraints kgbc = new GridBagConstraints();
+
+    // first row (template text box)
+    kgbc.anchor = GridBagConstraints.WEST;
+    kgbc.gridx = 0;
+    kgbc.gridy = 0;
+    kgbc.gridwidth = GridBagConstraints.REMAINDER;
+    kgbc.gridheight = 1;
+    kgbc.weightx = 1.0;
+    kgbc.weighty = 0.0;
+    kgbc.fill = GridBagConstraints.HORIZONTAL;
+    keepfilesPanel.add(backupfilesKeepAll.getTrueButton(), kgbc);
+
+    // second row
+    kgbc.gridy = 1;
+
+    kgbc.gridx = 0;
+    kgbc.gridwidth = GridBagConstraints.RELATIVE;
+    keepfilesPanel.add(backupfilesKeepAll.getFalseButton(), kgbc);
+
+    kgbc.gridx = 1;
+    kgbc.gridwidth = GridBagConstraints.REMAINDER;
+    keepfilesPanel.add(backupfilesRollMaxSpinner, kgbc);
+
+    // third row (indented)
+    kgbc.gridy = 2;
+    kgbc.insets = new Insets(0, 20, 0, 0);
+
+    kgbc.gridx = 0;
+    kgbc.gridwidth = GridBagConstraints.REMAINDER;
+    kgbc.fill = GridBagConstraints.HORIZONTAL;
+    kgbc.weightx = 1.0;
+
+    JPanel jp = new JPanel();
+    jp.setLayout(new FlowLayout());
+    oldBackupFilesLabel
+            .setText(MessageManager
+                    .getString("label.autodelete_old_backup_files"));
+    oldBackupFilesLabel.setFont(LABEL_FONT);
+    oldBackupFilesLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    jp.add(oldBackupFilesLabel);
+    jp.add(backupfilesConfirmDelete.getTrueButton());
+    jp.add(backupfilesConfirmDelete.getFalseButton());
+    keepfilesPanel.add(jp, kgbc);
+
+    return keepfilesPanel;
+  }
+
+  protected void updateBackupFilesExampleLabel()
+  {
+    int exampleindex = 12;
+    String base = MessageManager.getString("label.filename") + ".fa";
+    if (base == null || base.length() == 0)
+    {
+      base = "file_name.fa";
+    }
+
+    boolean reverse = suffixReverse.isSelected();
+    boolean keepAll = backupfilesKeepAll.isSelected();
+    int rollMax = 4;
+    String suffix = suffixTemplate.getText();
+    int digits = 3;
+
+    backupfilesExampleLabel.setFont(LABEL_FONT_ITALIC);
+    if (suffix == null || suffix.length() == 0)
+    {
+      backupfilesExampleLabel
+              .setText(MessageManager.getString("label.no_backup_files"));
+      backupfilesExampleLabel.setFont(LABEL_FONT_BOLD);
+      return;
+    }
+
+    rollMax = getSpinnerInt(backupfilesRollMaxSpinner, 4);
+    rollMax = rollMax < 1 ? 1 : rollMax;
+
+    if (suffix.indexOf(BackupFiles.NUM_PLACEHOLDER) == -1)
+    {
+      rollMax = 1;
+    }
 
-    linkNameList.addListSelectionListener(new ListSelectionListener()
+    digits = getSpinnerInt(suffixDigitsSpinner, 3);
+    digits = digits < 1 ? 1 : digits;
+
+    int lowersurround = 2;
+    int uppersurround = 0;
+    StringBuilder exampleSB = new StringBuilder();
+    boolean firstLine = true;
+    int lineNumber = 0;
+    if (reverse)
     {
-      public void valueChanged(ListSelectionEvent e)
+
+      int min = 1;
+      int max = keepAll ? exampleindex : rollMax;
+      for (int index = min; index <= max; index++)
       {
-        int index = linkNameList.getSelectedIndex();
-        linkURLList.setSelectedIndex(index);
+        if (index == min + lowersurround && index < max - uppersurround - 1)
+        {
+          exampleSB.append("\n...");
+          lineNumber++;
+        }
+        else if (index > min + lowersurround && index < max - uppersurround)
+        {
+          // nothing
+        }
+        else
+        {
+          if (firstLine)
+          {
+            firstLine = false;
+          }
+          else
+          {
+            exampleSB.append("\n");
+            lineNumber++;
+          }
+          exampleSB.append(BackupFilenameParts.getBackupFilename(index,
+                  base, suffix, digits));
+          if (min == max)
+          {
+            // no extra text needed
+          }
+          else if (index == min)
+          {
+            String newest = MessageManager.getString("label.braced_newest");
+            if (newest != null && newest.length() > 0)
+            {
+              exampleSB.append(" " + newest);
+            }
+          }
+          else if (index == max)
+          {
+            String oldest = MessageManager.getString("label.braced_oldest");
+            if (oldest != null && oldest.length() > 0)
+            {
+              exampleSB.append(" " + oldest);
+            }
+          }
+        }
       }
-    });
+    }
+    else
+    {
 
-    linkScrollPane.setBorder(null);
-    linkPanel.setBorder(new TitledBorder("URL link from Sequence ID"));
-    linkPanel.setLayout(borderLayout2);
-    editLinkButtons.setLayout(gridLayout1);
-    gridLayout1.setRows(3);
-    linkNameList.setFont(verdana11);
-    linkNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-    linkPanel2.setLayout(borderLayout3);
-    linkURLList.setFont(verdana11);
-    linkURLList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+      int min = (keepAll || exampleindex - rollMax < 0) ? 1
+              : exampleindex - rollMax + 1;
+      int max = exampleindex;
 
-    defaultBrowser.addMouseListener(new MouseAdapter()
-    {
-      public void mouseClicked(MouseEvent e)
+      for (int index = min; index <= max; index++)
       {
-        if (e.getClickCount() > 1)
+
+        if (index == min + lowersurround && index < max - uppersurround - 1)
         {
-          defaultBrowser_mouseClicked(e);
+          exampleSB.append("\n...");
+          lineNumber++;
+        }
+        else if (index > min + lowersurround && index < max - uppersurround)
+        {
+          // nothing
+        }
+        else
+        {
+          if (firstLine)
+          {
+            firstLine = false;
+          }
+          else
+          {
+            exampleSB.append("\n");
+            lineNumber++;
+          }
+          exampleSB.append(BackupFilenameParts.getBackupFilename(index,
+                  base, suffix, digits));
+          if (min == max)
+          {
+            // no extra text needed
+          }
+          else if (index == min)
+          {
+            String oldest = MessageManager.getString("label.braced_oldest");
+            if (oldest != null && oldest.length() > 0)
+            {
+              exampleSB.append(" " + oldest);
+            }
+          }
+          else if (index == max)
+          {
+            String newest = MessageManager.getString("label.braced_newest");
+            if (newest != null && newest.length() > 0)
+            {
+              exampleSB.append(" " + newest);
+            }
+          }
         }
       }
-    });
-    useProxy.setFont(verdana11);
-    useProxy.setHorizontalAlignment(SwingConstants.RIGHT);
-    useProxy.setHorizontalTextPosition(SwingConstants.LEADING);
-    useProxy.setText("Use a proxy server");
-    useProxy.addActionListener(new ActionListener()
+
+    }
+
+    // add some extra empty lines to pad out the example files box. ugh, please tell
+    // me how to do this better
+    int remainingLines = lowersurround + uppersurround + 1 - lineNumber;
+    if (remainingLines > 0)
     {
-      public void actionPerformed(ActionEvent e)
+      for (int i = 0; i < remainingLines; i++)
       {
-        useProxy_actionPerformed();
+        exampleSB.append("\n ");
+        lineNumber++;
       }
-    });
-    jPanel1.setBorder(titledBorder1);
-    jPanel1.setLayout(gridBagLayout1);
-    sortby.setFont(verdana11);
-    sortby.setBounds(new Rectangle(172, 249, 155, 21));
-    sortLabel.setFont(verdana11);
-    sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    sortLabel.setText("Sort by ");
-    jPanel2.setBounds(new Rectangle(7, 17, 158, 278));
-    jPanel2.setLayout(gridLayout2);
-    gridLayout2.setRows(12);
-    exportTab.setLayout(null);
-    epsLabel.setFont(verdana11);
-    epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-    epsLabel.setText("EPS Rendering Style");
-    epsLabel.setBounds(new Rectangle(9, 31, 140, 24));
-    epsRendering.setFont(verdana11);
-    epsRendering.setBounds(new Rectangle(154, 34, 187, 21));
-    jLabel1.setFont(verdana11);
-    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
-    jLabel1.setText("Append /start-end (/15-380)");
-    jLabel1.setFont(verdana11);
-    fastajv.setFont(verdana11);
-    fastajv.setHorizontalAlignment(SwingConstants.LEFT);
-    clustaljv.setText("Clustal     ");
-    blcjv.setText("BLC     ");
-    fastajv.setText("Fasta     ");
-    msfjv.setText("MSF     ");
-    pfamjv.setText("PFAM     ");
-    pileupjv.setText("Pileup     ");
-    msfjv.setFont(verdana11);
-    msfjv.setHorizontalAlignment(SwingConstants.LEFT);
-    pirjv.setText("PIR     ");
-    jPanel11.setFont(verdana11);
-    jPanel11.setBorder(titledBorder2);
-    jPanel11.setBounds(new Rectangle(30, 72, 196, 182));
-    jPanel11.setLayout(gridLayout3);
-    blcjv.setFont(verdana11);
-    blcjv.setHorizontalAlignment(SwingConstants.LEFT);
-    clustaljv.setFont(verdana11);
-    clustaljv.setHorizontalAlignment(SwingConstants.LEFT);
-    pfamjv.setFont(verdana11);
-    pfamjv.setHorizontalAlignment(SwingConstants.LEFT);
-    pileupjv.setFont(verdana11);
-    pileupjv.setHorizontalAlignment(SwingConstants.LEFT);
-    pirjv.setFont(verdana11);
-    pirjv.setHorizontalAlignment(SwingConstants.LEFT);
-    seqLimit.setFont(verdana11);
-    seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);
-    seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);
-    seqLimit.setText("Full Sequence Id");
-    gridLayout3.setRows(8);
-    smoothFont.setFont(verdana11);
-    smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);
-    smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);
-    smoothFont.setText("Smooth Font");
-    calcTab.setLayout(null);
-    autoCalculateConsCheck.setFont(JvSwingUtils.getLabelFont());
-    autoCalculateConsCheck.setText("AutoCalculate Consensus");
-    autoCalculateConsCheck.setBounds(new Rectangle(21, 52, 209, 23));
-    padGaps.setFont(JvSwingUtils.getLabelFont());
-    padGaps.setText("Pad Gaps When Editing");
-    padGaps.setBounds(new Rectangle(22, 94, 168, 23));
-    sortByTree.setFont(JvSwingUtils.getLabelFont());
-    sortByTree.setText("Sort With New Tree");
-    sortByTree.setToolTipText("When selected, any trees calculated or loaded onto the alignment will automatically sort the alignment.");
-    sortByTree.setBounds(new Rectangle(22, 136, 168, 23));
-    modellerOutput.setFont(JvSwingUtils.getLabelFont());
-    modellerOutput.setText("Use Modeller Output");
-    modellerOutput.setBounds(new Rectangle(228, 226, 168, 23));
-    dasPanel.setLayout(borderLayout4);
-    wsPanel.setLayout(borderLayout5);
-    wrap.setFont(JvSwingUtils.getLabelFont());
-    wrap.setHorizontalAlignment(SwingConstants.TRAILING);
-    wrap.setHorizontalTextPosition(SwingConstants.LEADING);
-    wrap.setText("Wrap Alignment");
-    rightAlign.setFont(JvSwingUtils.getLabelFont());
-    rightAlign.setForeground(Color.black);
-    rightAlign.setHorizontalAlignment(SwingConstants.RIGHT);
-    rightAlign.setHorizontalTextPosition(SwingConstants.LEFT);
-    rightAlign.setText("Right Align Ids");
-    idItalics.setFont(JvSwingUtils.getLabelFont());
-    idItalics.setHorizontalAlignment(SwingConstants.RIGHT);
-    idItalics.setHorizontalTextPosition(SwingConstants.LEADING);
-    idItalics.setText("Sequence Name Italics");
-    openoverv.setFont(JvSwingUtils.getLabelFont());
-    openoverv.setActionCommand("Open Overview");
-    openoverv.setHorizontalAlignment(SwingConstants.RIGHT);
-    openoverv.setHorizontalTextPosition(SwingConstants.LEFT);
-    openoverv.setText("Open Overview");
-    jPanel2.add(fullScreen);
-    jPanel2.add(openoverv);
-    jPanel2.add(seqLimit);
-    jPanel2.add(rightAlign);
-    jPanel2.add(fontLabel);
-    jPanel2.add(showUnconserved);
-    jPanel2.add(idItalics);
-    jPanel2.add(smoothFont);
-    jPanel2.add(gapLabel);
-    jPanel2.add(wrap);
-    jPanel2.add(sortLabel);
-    jPanel2.add(startupCheckbox);
-    visualTab.add(annotations);
-    visualTab.add(startupFileTextfield);
-    visualTab.add(sortby);
-    visualTab.add(gapSymbolCB);
-    visualTab.add(fontNameCB);
-    visualTab.add(fontSizeCB);
-    visualTab.add(fontStyleCB);
-    annsettingsPanel.setBounds(new Rectangle(173, 34, 300, 61));
-    annsettingsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
-    annsettingsPanel.add(autoAnnotSettings1);
-    annsettingsPanel.add(autoAnnotSettings2);
-    annsettingsPanel.add(autoAnnotSettings3);
-    autoAnnotSettings1.setLayout(new GridLayout(3, 1, 0, 0));
-    autoAnnotSettings2.setLayout(new GridLayout(3, 1, 0, 0));
-    autoAnnotSettings3.setLayout(new GridLayout(3, 1, 0, 0));
-    visualTab.add(annsettingsPanel);
-    Border jb = new EmptyBorder(1, 1, 4, 5);
-    quality.setBorder(jb);
-    conservation.setBorder(jb);
-    identity.setBorder(jb);
-    showConsensbits.setBorder(jb);
-    showGroupbits.setBorder(jb);
-    showGroupConsensus.setBorder(jb);
-    showGroupConservation.setBorder(jb);
-    showConsensHistogram.setBorder(jb);
-    showConsensLogo.setBorder(jb);
+    }
 
-    autoAnnotSettings2.add(conservation);
-    autoAnnotSettings1.add(quality);
-    autoAnnotSettings3.add(identity);
-    autoAnnotSettings1.add(showGroupbits);
-    autoAnnotSettings3.add(showGroupConsensus);
-    autoAnnotSettings2.add(showGroupConservation);
-    autoAnnotSettings1.add(showConsensbits);
-    autoAnnotSettings2.add(showConsensHistogram);
-    autoAnnotSettings3.add(showConsensLogo);
+    backupfilesExampleLabel.setText(exampleSB.toString());
+  }
 
-    JPanel tooltipSettings = new JPanel();
-    tooltipSettings.setBorder(new TitledBorder("Sequence ID Tooltip"));
-    tooltipSettings.setBounds(173, 130, 200, 62);
-    tooltipSettings.setLayout(new GridLayout(2, 1));
-    tooltipSettings.add(showDbRefTooltip);
-    tooltipSettings.add(showNpTooltip);
-    visualTab.add(tooltipSettings);
-    visualTab.add(jPanel2);
-    JvSwingUtils.addtoLayout(visual2Tab, "Default Colourscheme for alignment", colourLabel, colour);
-    JPanel annotationShding=new JPanel();
-    annotationShding.setBorder(new TitledBorder("Annotation Shading Default"));
-    annotationShding.setLayout(new GridLayout(1,2));
-    JvSwingUtils.addtoLayout(annotationShding, "Default Minimum Colour for annotation shading", mincolourLabel,minColour);
-    JvSwingUtils.addtoLayout(annotationShding,"Default Maximum Colour for annotation shading", maxcolourLabel, maxColour);
-    visual2Tab.add(annotationShding); // , FlowLayout.LEFT);
-
-//    visual2panel.add(minColour);
-//    visual2panel.add(maxColour);
-//    visual2Tab.add(visual2panel);
-
-    linkPanel.add(editLinkButtons, BorderLayout.EAST);
-    editLinkButtons.add(newLink, null);
-    editLinkButtons.add(editLink, null);
-    editLinkButtons.add(deleteLink, null);
-    linkPanel.add(linkScrollPane, BorderLayout.CENTER);
-    linkScrollPane.getViewport().add(linkPanel2, null);
-    linkPanel2.add(linkURLList, BorderLayout.CENTER);
-    linkPanel2.add(linkNameList, BorderLayout.WEST);
-    okCancelPanel.add(ok);
-    okCancelPanel.add(cancel);
-    this.add(tabbedPane, java.awt.BorderLayout.CENTER);
-
-    this.add(okCancelPanel, java.awt.BorderLayout.SOUTH);
-    jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
-            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
-                    2, 4, 0), 5, 0));
-    jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
-            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
-                    0, 4, 0), 11, 6));
-    connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
-            GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
-                    16, 0, 0, 12), 359, -17));
-    connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0,
-            GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
-                    21, 0, 35, 12), 4, 6));
-    connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
-            0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
-            new Insets(16, 0, 0, 0), 5, 1));
-    jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0,
-            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
-            new Insets(0, 2, 4, 2), 54, 1));
-    jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
-            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
-            new Insets(0, 2, 4, 0), 263, 1));
-    connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0,
-            0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
-            new Insets(15, 0, 0, 15), 307, 1));
-    connectTab.add(usagestats, new GridBagConstraints(0, 4, 1, 1, 1.0, 0.0,
-            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
-            new Insets(0, 2, 4, 2), 70, 1));
-    connectTab.add(questionnaire, new GridBagConstraints(1, 4, 1, 1, 1.0,
-            0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
-            new Insets(0, 2, 4, 2), 70, 1));
-    connectTab.add(versioncheck, new GridBagConstraints(0, 5, 1, 1, 1.0,
-            0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
-            new Insets(0, 2, 4, 2), 70, 1));
-
-    jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
-            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
-                    2, 5, 185), 2, -4));
-    DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
-    dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
-    gapSymbolCB.setRenderer(dlcr);
+  protected void setIntegerSpinner(JSpinner s, int min, int max, int def,
+          boolean useExistingVal, ChangeListener c)
+  {
+    int i = def;
+    if (useExistingVal)
+    {
+      try
+      {
+        i = Integer.parseInt((String) s.getValue());
+      } catch (Exception e)
+      {
+        Cache.log.error(
+                "Exception casting the initial value of s.getValue()");
+      }
+    }
 
-    tabbedPane.add(visualTab, "Visual");
-    tabbedPane.add(visual2Tab,"Colours");
-    tabbedPane.add(connectTab, "Connections");
-    tabbedPane.add(exportTab, "Output");
-    jPanel11.add(jLabel1);
-    jPanel11.add(blcjv);
-    jPanel11.add(clustaljv);
-    jPanel11.add(fastajv);
-    jPanel11.add(msfjv);
-    jPanel11.add(pfamjv);
-    jPanel11.add(pileupjv);
-    jPanel11.add(pirjv);
-    exportTab.add(modellerOutput);
-    tabbedPane.add(calcTab, "Editing");
-    calcTab.add(autoCalculateConsCheck);
-    calcTab.add(padGaps);
-    calcTab.add(sortByTree);
-    
-    tabbedPane.add(dasPanel, "DAS Settings");
-    tabbedPane.add(wsPanel, "Web Services");
+    setIntegerSpinner(s, min, max, i, c);
+  }
+
+  protected void setIntegerSpinner(JSpinner s, int min, int max, int def,
+          ChangeListener c)
+  {
+    // integer spinner for number of digits
+    if (def > max)
+    {
+      max = def;
+    }
+    SpinnerModel sModel = new SpinnerNumberModel(def, min, max, 1);
+    s.setModel(sModel);
+
+    s.addChangeListener(c);
+
+  }
+
+  protected static int getSpinnerInt(JSpinner s, int def)
+  {
+    int i = def;
+    try
+    {
+      s.commitEdit();
+      i = (Integer) s.getValue();
+    } catch (Exception e)
+    {
+      Cache.log.error("Failed casting (Integer) JSpinner s.getValue()");
+    }
+    return i;
+  }
+
+  private void keepRollMaxOptionsEnabled()
+  {
+    boolean enabled = backupfilesKeepAll.isEnabled()
+            && !backupfilesKeepAll.isSelected();
+    oldBackupFilesLabel.setEnabled(enabled);
+    backupfilesRollMaxSpinner.setEnabled(enabled);
+    backupfilesConfirmDelete.setEnabled(enabled);
+  }
+
+  private void backupfilesKeepAllSetEnabled(boolean tryEnabled)
+  {
+    boolean enabled = tryEnabled && enableBackupFiles.isSelected()
+            && customiseCheckbox.isSelected()
+            && suffixTemplate.getText()
+                    .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1;
+    keepfilesPanel.setEnabled(enabled);
+    backupfilesKeepAll.setEnabled(enabled);
+    oldBackupFilesLabel.setEnabled(enabled);
+    keepRollMaxOptionsEnabled();
+  }
+
+  private void backupfilesSuffixTemplateDigitsSetEnabled()
+  {
+    boolean enabled = suffixTemplate.isEnabled() && suffixTemplate.getText()
+            .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1;
+    suffixDigitsLabel.setEnabled(enabled);
+    suffixDigitsSpinner.setEnabled(enabled);
+    suffixReverse.setEnabled(enabled);
+  }
+
+  private void backupfilesSuffixTemplateSetEnabled(boolean tryEnabled)
+  {
+    boolean enabled = tryEnabled && enableBackupFiles.isSelected()
+            && customiseCheckbox.isSelected();
+    suffixPanel.setEnabled(enabled);
+    suffixTemplateLabel.setEnabled(enabled);
+    suffixTemplate.setEnabled(enabled);
+    backupfilesSuffixTemplateDigitsSetEnabled();
+  }
+
+  private void backupfilesRevertButtonSetEnabled(boolean tryEnabled)
+  {
+    boolean enabled = tryEnabled && enableBackupFiles.isSelected()
+            && customiseCheckbox.isSelected() && backupfilesCustomChanged();
+    revertButton.setEnabled(enabled);
+  }
+
+  private boolean backupfilesCustomChanged()
+  {
+    BackupFilesPresetEntry custom = BackupFilesPresetEntry.backupfilesPresetEntriesValues
+            .get(BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM);
+    BackupFilesPresetEntry current = getBackupfilesCurrentEntry();
+    return !custom.equals(current);
+  }
+
+  protected BackupFilesPresetEntry getBackupfilesCurrentEntry()
+  {
+    String suffix = suffixTemplate.getText();
+    int digits = getSpinnerInt(suffixDigitsSpinner, 3);
+    boolean reverse = suffixReverse.isSelected();
+    boolean keepAll = backupfilesKeepAll.isSelected();
+    int rollMax = getSpinnerInt(backupfilesRollMaxSpinner, 3);
+    boolean confirmDelete = backupfilesConfirmDelete.isSelected();
+
+    BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
+            reverse, keepAll, rollMax, confirmDelete);
+
+    return bfpe;
+  }
+
+  protected void backupfilesCustomOptionsSetEnabled()
+  {
+    boolean enabled = customiseCheckbox.isSelected();
+
+    backupfilesRevertButtonSetEnabled(enabled);
+    backupfilesSuffixTemplateSetEnabled(enabled);
+    backupfilesKeepAllSetEnabled(enabled);
+  }
+
+  private void backupfilesSummarySetEnabled()
+  {
+    boolean enabled = enableBackupFiles.isSelected();
+    backupfilesExampleLabel.setEnabled(enabled);
+    exampleFilesPanel.setEnabled(enabled);
+  }
+
+  private void backupfilesPresetsSetEnabled()
+  {
+    boolean enabled = enableBackupFiles.isSelected();
+    presetsPanel.setEnabled(enabled);
+    presetsComboLabel.setEnabled(enabled);
+    backupfilesPresetsCombo.setEnabled(enabled);
+    customiseCheckbox.setEnabled(enabled);
+    revertButton.setEnabled(enabled);
+  }
+
+  protected void backupsOptionsSetEnabled()
+  {
+    backupfilesPresetsSetEnabled();
+    backupfilesSummarySetEnabled();
+    backupfilesCustomOptionsSetEnabled();
+  }
+
+  protected void backupsSetOptions(String suffix, int digits,
+          boolean reverse, boolean keepAll, int rollMax,
+          boolean confirmDelete)
+  {
+    suffixTemplate.setText(suffix);
+    suffixDigitsSpinner.setValue(digits);
+    suffixReverse.setSelected(reverse);
+    backupfilesKeepAll.setSelected(keepAll);
+    backupfilesRollMaxSpinner.setValue(rollMax);
+    backupfilesConfirmDelete.setSelected(confirmDelete);
+  }
 
-    exportTab.add(epsLabel);
-    exportTab.add(epsRendering);
-    exportTab.add(jPanel11);
+  protected void backupsSetOptions(BackupFilesPresetEntry p)
+  {
+    backupsSetOptions(p.suffix, p.digits, p.reverse, p.keepAll, p.rollMax,
+            p.confirmDelete);
   }
 
-  protected void maxColour_actionPerformed()
+  protected void autoIdWidth_actionPerformed()
   {
     // TODO Auto-generated method stub
-    
+
   }
 
-  protected void minColour_actionPerformed()
+  protected void userIdWidth_actionPerformed()
   {
     // TODO Auto-generated method stub
-    
+
+  }
+
+  protected void maxColour_actionPerformed(JPanel panel)
+  {
+  }
+
+  protected void minColour_actionPerformed(JPanel panel)
+  {
+  }
+
+  protected void gapColour_actionPerformed(JPanel panel)
+  {
+  }
+
+  protected void hiddenColour_actionPerformed(JPanel panel)
+  {
   }
 
   protected void showunconserved_actionPerformed(ActionEvent e)
@@ -825,6 +2682,14 @@ public class GPreferences extends JPanel
 
   }
 
+  protected void useLegacyGaps_actionPerformed(ActionEvent e)
+  {
+  }
+
+  protected void resetOvDefaults_actionPerformed(ActionEvent e)
+  {
+  }
+
   /**
    * DOCUMENT ME!
    * 
@@ -889,8 +2754,83 @@ public class GPreferences extends JPanel
 
   public void useProxy_actionPerformed()
   {
-    proxyServerTB.setEnabled(useProxy.isSelected());
-    proxyPortTB.setEnabled(useProxy.isSelected());
+    boolean enabled = useProxy.isSelected();
+    portLabel.setEnabled(enabled);
+    serverLabel.setEnabled(enabled);
+    proxyServerTB.setEnabled(enabled);
+    proxyPortTB.setEnabled(enabled);
+  }
+
+  /**
+   * Customer renderer for JTable: supports column of radio buttons
+   */
+  public class RadioButtonRenderer extends JRadioButton
+          implements TableCellRenderer
+  {
+    public RadioButtonRenderer()
+    {
+      setHorizontalAlignment(CENTER);
+      setToolTipText(MessageManager.getString("label.urltooltip"));
+    }
+
+    @Override
+    public Component getTableCellRendererComponent(JTable table,
+            Object value, boolean isSelected, boolean hasFocus, int row,
+            int column)
+    {
+      setSelected((boolean) value);
+
+      // set colours to match rest of table
+      if (isSelected)
+      {
+        setBackground(table.getSelectionBackground());
+        setForeground(table.getSelectionForeground());
+      }
+      else
+      {
+        setBackground(table.getBackground());
+        setForeground(table.getForeground());
+      }
+      return this;
+    }
   }
 
+  /**
+   * Customer cell editor for JTable: supports column of radio buttons in
+   * conjunction with renderer
+   */
+  public class RadioButtonEditor extends AbstractCellEditor
+          implements TableCellEditor
+  {
+    private JRadioButton button = new JRadioButton();
+
+    public RadioButtonEditor()
+    {
+      button.setHorizontalAlignment(SwingConstants.CENTER);
+      this.button.addActionListener(new ActionListener()
+      {
+        @Override
+        public void actionPerformed(ActionEvent e)
+        {
+          fireEditingStopped();
+        }
+      });
+    }
+
+    @Override
+    public Component getTableCellEditorComponent(JTable table, Object value,
+            boolean isSelected, int row, int column)
+    {
+      button.setSelected((boolean) value);
+      return button;
+    }
+
+    @Override
+    public Object getCellEditorValue()
+    {
+      return button.isSelected();
+    }
+
+  }
 }
+