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