2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Dimension;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.event.MouseEvent;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.concurrent.CompletableFuture;
36 import javax.help.HelpSetException;
37 import javax.swing.JComboBox;
38 import javax.swing.JFileChooser;
39 import javax.swing.JInternalFrame;
40 import javax.swing.JPanel;
41 import javax.swing.ListSelectionModel;
42 import javax.swing.RowFilter;
43 import javax.swing.RowSorter;
44 import javax.swing.SortOrder;
45 import javax.swing.event.DocumentEvent;
46 import javax.swing.event.DocumentListener;
47 import javax.swing.event.ListSelectionEvent;
48 import javax.swing.event.ListSelectionListener;
49 import javax.swing.table.TableCellRenderer;
50 import javax.swing.table.TableColumn;
51 import javax.swing.table.TableModel;
52 import javax.swing.table.TableRowSorter;
54 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
55 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
56 import jalview.bin.Cache;
57 import jalview.ext.pymol.PymolManager;
58 import jalview.gui.Help.HelpId;
59 import jalview.gui.StructureViewer.ViewerType;
60 import jalview.io.BackupFiles;
61 import jalview.io.BackupFilesPresetEntry;
62 import jalview.io.FileFormatI;
63 import jalview.io.JalviewFileChooser;
64 import jalview.io.JalviewFileView;
65 import jalview.jbgui.GPreferences;
66 import jalview.jbgui.GSequenceLink;
67 import jalview.schemes.ColourSchemeI;
68 import jalview.schemes.ColourSchemes;
69 import jalview.schemes.ResidueColourScheme;
70 import jalview.urls.UrlLinkTableModel;
71 import jalview.urls.api.UrlProviderFactoryI;
72 import jalview.urls.api.UrlProviderI;
73 import jalview.urls.desktop.DesktopUrlProviderFactory;
74 import jalview.util.MessageManager;
75 import jalview.util.Platform;
76 import jalview.util.UrlConstants;
77 import jalview.ws.sifts.SiftsSettings;
86 * for merge with Jalview-JS
87 public class Preferences extends GPreferences implements ApplicationSingletonI
89 public class Preferences extends GPreferences
91 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
93 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
95 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
97 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
99 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
101 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
103 public static final String ADD_SS_ANN = "ADD_SS_ANN";
105 public static final String USE_RNAVIEW = "USE_RNAVIEW";
107 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
109 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
111 public static final String CHIMERA_PATH = "CHIMERA_PATH";
113 public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
115 public static final String PYMOL_PATH = "PYMOL_PATH";
117 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
119 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
121 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
123 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
125 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
127 public static final String GAP_COLOUR = "GAP_COLOUR";
129 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
131 private static final int MIN_FONT_SIZE = 1;
133 private static final int MAX_FONT_SIZE = 30;
135 private String previousProxyType;
137 private static Preferences INSTANCE = null; // add "final"
140 * Holds name and link separated with | character. Sequence ID must be
141 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
143 public static UrlProviderI sequenceUrlLinks;
145 public static UrlLinkTableModel dataModel;
148 * Holds name and link separated with | character. Sequence IDS and Sequences
149 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and $SEQUENCES$
150 * or $SEQUENCES=/.possible | chars ./=$ and separation character for first and
151 * second token specified after a pipe character at end |,|. (TODO: proper
152 * escape for using | to separate ids or sequences
155 public static List<String> groupURLLinks;
158 // get links selected to be in the menu (SEQUENCE_LINKS)
159 // and links entered by the user but not selected (STORED_LINKS)
160 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
161 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
162 String defaultUrl = Cache.getDefault("DEFAULT_URL",
163 UrlConstants.DEFAULT_LABEL);
165 // if both links lists are empty, add the DEFAULT_URL link
166 // otherwise we assume the default link is in one of the lists
167 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
169 inMenuString = UrlConstants.DEFAULT_STRING;
171 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
172 inMenuString, notInMenuString);
173 sequenceUrlLinks = factory.createUrlProvider();
174 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
177 * TODO: reformulate groupURL encoding so two or more can be stored in the
178 * .properties file as '|' separated strings
181 groupURLLinks = new ArrayList<>();
184 JInternalFrame frame;
186 private WsPreferences wsPrefs;
188 private OptionsParam promptEachTimeOpt = new OptionsParam(
189 MessageManager.getString("label.prompt_each_time"),
192 private OptionsParam lineArtOpt = new OptionsParam(
193 MessageManager.getString("label.lineart"), "Lineart");
195 private OptionsParam textOpt = new OptionsParam(
196 MessageManager.getString("action.text"), "Text");
198 // get singleton Preferences instance
199 public static Preferences getInstance()
201 if (INSTANCE == null || INSTANCE.frame == null
202 || INSTANCE.frame.isClosed())
204 INSTANCE = new Preferences();
209 * Replace code with the following for Jalvew-JS
210 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
211 if (INSTANCE == null || INSTANCE.frame == null
212 || INSTANCE.frame.isClosed())
214 ApplicationSingletonProvider.remove(Preferences.class);
215 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
221 public static void openPreferences()
223 openPreferences(null, null);
226 public static void openPreferences(TabRef selectTab, String message)
228 Preferences p = getInstance();
229 if (selectTab != null)
230 p.selectTab(selectTab, message);
232 p.frame.moveToFront();
236 public void selectTab(TabRef selectTab, String message)
238 this.selectTab(selectTab);
240 this.setMessage(message);
245 * Creates a new Preferences object.
247 private Preferences()
250 frame = new JInternalFrame();
251 frame.setContentPane(this);
252 if (!Platform.isJS())
259 wsPrefs = new WsPreferences();
260 wsTab.add(wsPrefs, BorderLayout.CENTER);
262 int width = 500, height = 450;
263 if (Platform.isAMacAndNotJS())
269 Desktop.addInternalFrame(frame,
270 MessageManager.getString("label.preferences"), width, height);
271 frame.setMinimumSize(new Dimension(width, height));
274 * Set Visual tab defaults
276 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
277 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
278 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
279 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
281 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
282 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
283 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
284 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
286 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
287 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
289 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
290 showGroupConservation.setSelected(
291 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
292 showConsensHistogram.setSelected(
293 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
295 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
297 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
299 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
301 String[] fonts = java.awt.GraphicsEnvironment
302 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
303 for (int i = 0; i < fonts.length; i++)
305 fontNameCB.addItem(fonts[i]);
308 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
310 fontSizeCB.addItem(i + "");
313 fontStyleCB.addItem("plain");
314 fontStyleCB.addItem("bold");
315 fontStyleCB.addItem("italic");
317 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
318 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
319 fontStyleCB.setSelectedItem(
320 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
322 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
324 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
326 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
328 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
330 gapSymbolCB.addItem("-");
331 gapSymbolCB.addItem(".");
333 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
335 sortby.addItem("No sort");
336 sortby.addItem("Id");
337 sortby.addItem("Pairwise Identity");
338 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
340 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
342 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
344 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
345 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
346 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
347 SequenceAnnotationOrder.NONE.name()));
348 sortAnnBy.setSelectedItem(savedSort.toString());
350 sortAutocalc.addItem("Autocalculated first");
351 sortAutocalc.addItem("Autocalculated last");
352 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
353 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
354 : sortAutocalc.getItemAt(1));
356 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
357 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
358 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
359 + "/examples/exampleFile_2_7.jvp"));
362 * Set Colours tab defaults
364 protColour.addItem(ResidueColourScheme.NONE);
365 nucColour.addItem(ResidueColourScheme.NONE);
366 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
368 String name = cs.getSchemeName();
369 protColour.addItem(name);
370 nucColour.addItem(name);
372 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
373 ResidueColourScheme.NONE);
374 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
375 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
376 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
377 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
378 minColour.setBackground(
379 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
380 maxColour.setBackground(
381 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
384 * Set overview panel defaults
386 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
387 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
388 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
389 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
390 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
391 gapLabel.setEnabled(!useLegacyGap.isSelected());
392 gapColour.setEnabled(!useLegacyGap.isSelected());
394 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
397 * Set Structure tab defaults
399 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, false);
400 structFromPdb.setSelected(structSelected);
401 useRnaView.setSelected(Cache.getDefault(USE_RNAVIEW, false));
402 useRnaView.setEnabled(structSelected);
403 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, false));
404 addSecondaryStructure.setEnabled(structSelected);
405 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, false));
406 addTempFactor.setEnabled(structSelected);
409 * set choice of structure viewer, and path if saved as a preference;
410 * default to Jmol (first choice) if an unexpected value is found
412 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
413 ViewerType.JMOL.name());
414 structViewer.setSelectedItem(viewerType);
415 String viewerPath = "";
416 ViewerType type = null;
419 type = ViewerType.valueOf(viewerType);
425 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
428 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
431 viewerPath = Cache.getDefault(PYMOL_PATH, "");
434 } catch (IllegalArgumentException e)
436 Cache.log.error("Unknown structure viewer type: " + viewerType
437 + ", defaulting to Jmol");
438 type = ViewerType.JMOL;
440 structureViewerPath.setText(viewerPath);
442 structureViewerPath.addActionListener(new ActionListener()
445 public void actionPerformed(ActionEvent e)
447 if (validateViewerPath())
450 structViewer.getSelectedItem().equals(
451 ViewerType.CHIMERAX.name()) ? CHIMERAX_PATH
453 structureViewerPath.getText());
458 if (Cache.getDefault("MAP_WITH_SIFTS", false))
460 siftsMapping.setSelected(true);
464 nwMapping.setSelected(true);
468 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
471 * Set Connections tab defaults
475 linkUrlTable.setModel(dataModel);
476 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
477 linkUrlTable.getModel());
478 linkUrlTable.setRowSorter(sorter);
479 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
481 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
482 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
483 SortOrder.DESCENDING));
484 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
485 SortOrder.DESCENDING));
487 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
489 sorter.setSortKeys(sortKeys);
490 // BH 2018 setSortKeys will do the sort
494 ActionListener onReset;
495 onReset = new ActionListener()
498 public void actionPerformed(ActionEvent e)
500 filterTB.setText("");
501 sorter.setRowFilter(RowFilter.regexFilter(""));
505 doReset.addActionListener(onReset);
507 // filter to display only custom urls
508 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
511 public boolean include(
512 Entry<? extends TableModel, ? extends Object> entry)
514 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
518 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
519 linkUrlTable.getModel());
520 customSorter.setRowFilter(customUrlFilter);
522 ActionListener onCustomOnly;
523 onCustomOnly = new ActionListener()
526 public void actionPerformed(ActionEvent e)
528 filterTB.setText("");
529 sorter.setRowFilter(customUrlFilter);
532 userOnly.addActionListener(onCustomOnly);
534 filterTB.getDocument().addDocumentListener(new DocumentListener()
536 String caseInsensitiveFlag = "(?i)";
539 public void changedUpdate(DocumentEvent e)
541 sorter.setRowFilter(RowFilter
542 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
546 public void removeUpdate(DocumentEvent e)
548 sorter.setRowFilter(RowFilter
549 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
553 public void insertUpdate(DocumentEvent e)
555 sorter.setRowFilter(RowFilter
556 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
560 // set up list selection functionality
561 linkUrlTable.getSelectionModel()
562 .addListSelectionListener(new UrlListSelectionHandler());
564 // set up radio buttons
565 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
567 String onClickName = linkUrlTable.getColumnName(onClickCol);
568 linkUrlTable.getColumn(onClickName)
569 .setCellRenderer(new RadioButtonRenderer());
570 linkUrlTable.getColumn(onClickName)
571 .setCellEditor(new RadioButtonEditor());
573 // get boolean columns and resize those to min possible
574 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
576 if (linkUrlTable.getModel().getColumnClass(column)
577 .equals(Boolean.class))
579 TableColumn tableColumn = linkUrlTable.getColumnModel()
581 int preferredWidth = tableColumn.getMinWidth();
583 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
585 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
586 int cwidth = c.getPreferredSize().width
587 + linkUrlTable.getIntercellSpacing().width;
588 preferredWidth = Math.max(preferredWidth, cwidth);
590 tableColumn.setPreferredWidth(preferredWidth);
594 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
595 previousProxyType = proxyTypeString;
596 switch (proxyTypeString)
598 case Cache.PROXYTYPE_NONE:
599 proxyType.setSelected(noProxy.getModel(), true);
601 case Cache.PROXYTYPE_SYSTEM:
602 proxyType.setSelected(systemProxy.getModel(), true);
604 case Cache.PROXYTYPE_CUSTOM:
605 proxyType.setSelected(customProxy.getModel(), true);
609 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
612 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
613 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
614 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
615 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
616 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
618 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
619 // we are not storing or retrieving proxy password from .jalview_properties
620 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
621 : new String(Cache.proxyAuthPassword));
622 setCustomProxyEnabled();
623 applyProxyButtonEnabled(false);
625 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
627 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
628 // note antisense here: default is true
630 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
631 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
634 * Set Output tab defaults
636 setupOutputCombo(epsRendering, "EPS_RENDERING");
637 setupOutputCombo(htmlRendering, "HTML_RENDERING");
638 setupOutputCombo(svgRendering, "SVG_RENDERING");
639 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
640 userIdWidth.setEnabled(!autoIdWidth.isSelected());
641 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
642 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
643 userIdWidth.setText(wi == null ? "" : wi.toString());
644 // TODO: refactor to use common enum via FormatAdapter and allow extension
645 // for new flat file formats
646 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
647 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
648 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
649 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
650 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
651 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
652 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
653 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
655 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
658 * Set Editing tab defaults
660 autoCalculateConsCheck
661 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
662 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
663 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
665 annotations_actionPerformed(null); // update the display of the annotation
669 * Set Backups tab defaults
671 loadLastSavedBackupsOptions();
675 * A helper method that sets the items and initial selection in a character
676 * rendering option list (Prompt each time/Lineart/Text)
681 protected void setupOutputCombo(JComboBox<Object> comboBox,
684 comboBox.addItem(promptEachTimeOpt);
685 comboBox.addItem(lineArtOpt);
686 comboBox.addItem(textOpt);
689 * JalviewJS doesn't support Lineart so force it to Text
691 String defaultOption = Platform.isJS() ? "Text"
692 : Cache.getDefault(propertyKey, "Prompt each time");
693 if (defaultOption.equalsIgnoreCase("Text"))
695 comboBox.setSelectedItem(textOpt);
697 else if (defaultOption.equalsIgnoreCase("Lineart"))
699 comboBox.setSelectedItem(lineArtOpt);
703 comboBox.setSelectedItem(promptEachTimeOpt);
708 * Save user selections on the Preferences tabs to the Cache and write out to
714 public void ok_actionPerformed(ActionEvent e)
716 if (!validateSettings())
722 * Set proxy settings first (to be before web services refresh)
727 * Save Visual settings
729 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
730 Boolean.toString(seqLimit.isSelected()));
731 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
732 Boolean.toString(rightAlign.isSelected()));
733 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
734 Boolean.toString(fullScreen.isSelected()));
735 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
736 Boolean.toString(openoverv.isSelected()));
737 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
738 Boolean.toString(annotations.isSelected()));
739 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
740 Boolean.toString(conservation.isSelected()));
741 Cache.applicationProperties.setProperty("SHOW_QUALITY",
742 Boolean.toString(quality.isSelected()));
743 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
744 Boolean.toString(identity.isSelected()));
746 Cache.applicationProperties.setProperty("GAP_SYMBOL",
747 gapSymbolCB.getSelectedItem().toString());
749 Cache.applicationProperties.setProperty("FONT_NAME",
750 fontNameCB.getSelectedItem().toString());
751 Cache.applicationProperties.setProperty("FONT_STYLE",
752 fontStyleCB.getSelectedItem().toString());
753 Cache.applicationProperties.setProperty("FONT_SIZE",
754 fontSizeCB.getSelectedItem().toString());
756 Cache.applicationProperties.setProperty("ID_ITALICS",
757 Boolean.toString(idItalics.isSelected()));
758 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
759 Boolean.toString(showUnconserved.isSelected()));
760 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
761 Boolean.toString(showOccupancy.isSelected()));
762 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
763 Boolean.toString(showGroupConsensus.isSelected()));
764 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
765 Boolean.toString(showGroupConservation.isSelected()));
766 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
767 Boolean.toString(showConsensHistogram.isSelected()));
768 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
769 Boolean.toString(showConsensLogo.isSelected()));
770 Cache.applicationProperties.setProperty("ANTI_ALIAS",
771 Boolean.toString(smoothFont.isSelected()));
772 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
773 Boolean.toString(scaleProteinToCdna.isSelected()));
774 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
775 Boolean.toString(showNpTooltip.isSelected()));
776 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
777 Boolean.toString(showDbRefTooltip.isSelected()));
779 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
780 Boolean.toString(wrap.isSelected()));
782 Cache.applicationProperties.setProperty("STARTUP_FILE",
783 startupFileTextfield.getText());
784 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
785 Boolean.toString(startupCheckbox.isSelected()));
787 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
788 sortby.getSelectedItem().toString());
790 // convert description of sort order to enum name for save
791 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
792 .forDescription(sortAnnBy.getSelectedItem().toString());
793 if (annSortOrder != null)
795 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
796 annSortOrder.name());
799 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
800 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
801 Boolean.valueOf(showAutocalcFirst).toString());
804 * Save Colours settings
806 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
807 protColour.getSelectedItem().toString());
808 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
809 nucColour.getSelectedItem().toString());
810 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
811 minColour.getBackground());
812 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
813 maxColour.getBackground());
816 * Save Overview settings
818 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
819 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
820 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
821 Boolean.toString(useLegacyGap.isSelected()));
822 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
823 Boolean.toString(showHiddenAtStart.isSelected()));
826 * Save Structure settings
828 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
829 Boolean.toString(addTempFactor.isSelected()));
830 Cache.applicationProperties.setProperty(ADD_SS_ANN,
831 Boolean.toString(addSecondaryStructure.isSelected()));
832 Cache.applicationProperties.setProperty(USE_RNAVIEW,
833 Boolean.toString(useRnaView.isSelected()));
834 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
835 Boolean.toString(structFromPdb.isSelected()));
836 String viewer = structViewer.getSelectedItem().toString();
837 String viewerPath = structureViewerPath.getText();
838 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
839 if (viewer.equals(ViewerType.CHIMERA.name()))
841 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
843 else if (viewer.equals(ViewerType.CHIMERAX.name()))
845 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
847 else if (viewer.equals(ViewerType.PYMOL.name()))
849 Cache.setOrRemove(PYMOL_PATH, viewerPath);
851 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
852 Boolean.toString(siftsMapping.isSelected()));
853 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
856 * Save Output settings
858 Cache.applicationProperties.setProperty("EPS_RENDERING",
859 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
860 Cache.applicationProperties.setProperty("HTML_RENDERING",
861 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
862 Cache.applicationProperties.setProperty("SVG_RENDERING",
863 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
866 * Save Connections settings
868 // Proxy settings set first (to catch web services)
870 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
872 jalview.util.BrowserLauncher.resetBrowser();
874 // save user-defined and selected links
875 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
876 if (menuLinks.isEmpty())
878 Cache.applicationProperties.remove("SEQUENCE_LINKS");
882 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
883 menuLinks.toString());
886 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
887 if (nonMenuLinks.isEmpty())
889 Cache.applicationProperties.remove("STORED_LINKS");
893 Cache.applicationProperties.setProperty("STORED_LINKS",
894 nonMenuLinks.toString());
897 Cache.applicationProperties.setProperty("DEFAULT_URL",
898 sequenceUrlLinks.getPrimaryUrlId());
900 Cache.setProperty("VERSION_CHECK",
901 Boolean.toString(versioncheck.isSelected()));
902 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
904 // default is false - we only set this if the user has actively agreed
905 Cache.setProperty("USAGESTATS",
906 Boolean.toString(usagestats.isSelected()));
908 if (!questionnaire.isSelected())
910 Cache.setProperty("NOQUESTIONNAIRES", "true");
914 // special - made easy to edit a property file to disable questionnaires
915 // by just adding the given line
916 Cache.removeProperty("NOQUESTIONNAIRES");
920 * Save Output settings
922 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
923 Boolean.toString(blcjv.isSelected()));
924 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
925 Boolean.toString(clustaljv.isSelected()));
926 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
927 Boolean.toString(fastajv.isSelected()));
928 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
929 Boolean.toString(msfjv.isSelected()));
930 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
931 Boolean.toString(pfamjv.isSelected()));
932 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
933 Boolean.toString(pileupjv.isSelected()));
934 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
935 Boolean.toString(pirjv.isSelected()));
936 Cache.applicationProperties.setProperty("PIR_MODELLER",
937 Boolean.toString(modellerOutput.isSelected()));
938 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
939 Boolean.toString(embbedBioJSON.isSelected()));
940 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
942 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
943 Boolean.toString(autoIdWidth.isSelected()));
944 userIdWidth_actionPerformed();
945 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
946 userIdWidth.getText());
949 * Save Editing settings
951 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
952 Boolean.toString(autoCalculateConsCheck.isSelected()));
953 Cache.applicationProperties.setProperty("SORT_BY_TREE",
954 Boolean.toString(sortByTree.isSelected()));
955 Cache.applicationProperties.setProperty("PAD_GAPS",
956 Boolean.toString(padGaps.isSelected()));
958 if (!Platform.isJS())
960 wsPrefs.updateAndRefreshWsMenuConfig(false);
964 * Save Backups settings
966 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
967 Boolean.toString(enableBackupFiles.isSelected()));
968 int preset = getComboIntStringKey(backupfilesPresetsCombo);
969 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
970 Integer.toString(preset));
972 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
974 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
975 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
976 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
977 Cache.applicationProperties.setProperty(
978 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
981 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
983 Cache.applicationProperties.setProperty(
984 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
986 Cache.saveProperties();
987 Desktop.instance.doConfigureStructurePrefs();
990 frame.setClosed(true);
991 } catch (Exception ex)
996 public void saveProxySettings()
998 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
999 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1000 : Cache.PROXYTYPE_SYSTEM;
1001 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1002 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1003 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1004 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1005 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1006 Cache.setOrRemove("PROXY_AUTH",
1007 Boolean.toString(proxyAuth.isSelected()));
1008 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1009 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1010 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1011 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1012 || !newProxyType.equals(previousProxyType))
1014 // force a re-lookup of ws if proxytype is custom or has changed
1017 previousProxyType = newProxyType;
1021 * Do any necessary validation before saving settings. Return focus to the first
1022 * tab which fails validation.
1026 private boolean validateSettings()
1028 if (!validateStructure())
1030 structureTab.requestFocusInWindow();
1037 protected boolean validateStructure()
1039 return validateViewerPath();
1047 public void startupFileTextfield_mouseClicked()
1049 // TODO: JAL-3048 not needed for Jalview-JS
1050 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1051 JalviewFileChooser chooser = JalviewFileChooser
1052 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1053 chooser.setFileView(new JalviewFileView());
1054 chooser.setDialogTitle(
1055 MessageManager.getString("label.select_startup_file"));
1057 int value = chooser.showOpenDialog(this);
1059 if (value == JalviewFileChooser.APPROVE_OPTION)
1061 FileFormatI format = chooser.getSelectedFormat();
1064 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1067 startupFileTextfield
1068 .setText(chooser.getSelectedFile().getAbsolutePath());
1079 public void cancel_actionPerformed(ActionEvent e)
1083 if (!Platform.isJS())
1085 wsPrefs.updateWsMenuConfig(true);
1086 wsPrefs.refreshWs_actionPerformed(e);
1088 frame.setClosed(true);
1089 } catch (Exception ex)
1101 public void annotations_actionPerformed(ActionEvent e)
1103 conservation.setEnabled(annotations.isSelected());
1104 quality.setEnabled(annotations.isSelected());
1105 identity.setEnabled(annotations.isSelected());
1106 showOccupancy.setEnabled(annotations.isSelected());
1107 showGroupConsensus.setEnabled(annotations.isSelected());
1108 showGroupConservation.setEnabled(annotations.isSelected());
1109 showConsensHistogram.setEnabled(annotations.isSelected()
1110 && (identity.isSelected() || showGroupConsensus.isSelected()));
1111 showConsensLogo.setEnabled(annotations.isSelected()
1112 && (identity.isSelected() || showGroupConsensus.isSelected()));
1116 public void newLink_actionPerformed(ActionEvent e)
1118 GSequenceLink link = new GSequenceLink();
1119 boolean valid = false;
1122 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1123 MessageManager.getString("label.new_sequence_url_link"),
1124 JvOptionPane.OK_CANCEL_OPTION, -1,
1125 null) == JvOptionPane.OK_OPTION)
1127 if (link.checkValid())
1129 if (((UrlLinkTableModel) linkUrlTable.getModel())
1130 .isUniqueName(link.getName()))
1132 ((UrlLinkTableModel) linkUrlTable.getModel())
1133 .insertRow(link.getName(), link.getURL());
1138 link.notifyDuplicate();
1151 public void editLink_actionPerformed(ActionEvent e)
1153 GSequenceLink link = new GSequenceLink();
1155 int index = linkUrlTable.getSelectedRow();
1158 // button no longer enabled if row is not selected
1159 Cache.log.debug("Edit with no row selected in linkUrlTable");
1163 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1165 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1167 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1168 link.setName(oldName);
1169 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1171 boolean valid = false;
1174 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1175 MessageManager.getString("label.edit_sequence_url_link"),
1176 JvOptionPane.OK_CANCEL_OPTION, -1,
1177 null) == JvOptionPane.OK_OPTION)
1179 if (link.checkValid())
1181 if ((oldName.equals(link.getName()))
1182 || (((UrlLinkTableModel) linkUrlTable.getModel())
1183 .isUniqueName(link.getName())))
1185 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1186 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1191 link.notifyDuplicate();
1204 public void deleteLink_actionPerformed(ActionEvent e)
1206 int index = linkUrlTable.getSelectedRow();
1207 int modelIndex = -1;
1210 // button no longer enabled if row is not selected
1211 Cache.log.debug("Delete with no row selected in linkUrlTable");
1216 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1219 // make sure we use the model index to delete, and not the table index
1220 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1224 public void defaultBrowser_mouseClicked(MouseEvent e)
1226 // TODO: JAL-3048 not needed for j2s
1227 if (!Platform.isJS()) // BH 2019
1234 JFileChooser chooser = new JFileChooser(".");
1235 chooser.setDialogTitle(
1236 MessageManager.getString("label.select_default_browser"));
1238 int value = chooser.showOpenDialog(this);
1240 if (value == JFileChooser.APPROVE_OPTION)
1242 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1251 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1255 protected void showunconserved_actionPerformed(ActionEvent e)
1257 // TODO Auto-generated method stub
1258 super.showunconserved_actionPerformed(e);
1261 public static List<String> getGroupURLLinks()
1263 return groupURLLinks;
1267 public void minColour_actionPerformed(JPanel panel)
1269 JalviewColourChooser.showColourChooser(this,
1270 MessageManager.getString("label.select_colour_minimum_value"),
1275 public void maxColour_actionPerformed(JPanel panel)
1277 JalviewColourChooser.showColourChooser(this,
1278 MessageManager.getString("label.select_colour_maximum_value"),
1283 public void gapColour_actionPerformed(JPanel gap)
1285 if (!useLegacyGap.isSelected())
1287 JalviewColourChooser.showColourChooser(this,
1288 MessageManager.getString("label.select_gap_colour"), gap);
1293 public void hiddenColour_actionPerformed(JPanel hidden)
1295 JalviewColourChooser.showColourChooser(this,
1296 MessageManager.getString("label.select_hidden_colour"), hidden);
1300 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1302 boolean enabled = useLegacyGap.isSelected();
1305 gapColour.setBackground(
1306 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1310 gapColour.setBackground(
1311 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1313 gapColour.setEnabled(!enabled);
1314 gapLabel.setEnabled(!enabled);
1318 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1320 useLegacyGap.setSelected(false);
1321 useLegacyGaps_actionPerformed(null);
1322 showHiddenAtStart.setSelected(false);
1323 hiddenColour.setBackground(
1324 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1328 protected void userIdWidth_actionPerformed()
1332 String val = userIdWidth.getText().trim();
1333 if (val.length() > 0)
1335 Integer iw = Integer.parseInt(val);
1336 if (iw.intValue() < 12)
1338 throw new NumberFormatException();
1340 userIdWidth.setText(iw.toString());
1342 } catch (NumberFormatException x)
1344 userIdWidth.setText("");
1345 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1347 .getString("warn.user_defined_width_requirements"),
1348 MessageManager.getString("label.invalid_id_column_width"),
1349 JvOptionPane.WARNING_MESSAGE);
1354 protected void autoIdWidth_actionPerformed()
1356 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1357 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1361 * Returns true if structure viewer path is to a valid executable, else shows an
1362 * error dialog. Does nothing if the path is empty, as is the case for Jmol
1363 * (built in to Jalview) or when Jalview is left to try default paths.
1365 private boolean validateViewerPath()
1367 if (structureViewerPath.getText().trim().length() > 0)
1369 File f = new File(structureViewerPath.getText());
1370 if (!f.canExecute())
1372 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1373 MessageManager.getString("label.invalid_viewer_path"),
1374 MessageManager.getString("label.invalid_viewer_path"),
1375 JvOptionPane.ERROR_MESSAGE);
1383 * If Chimera or ChimeraX or Pymol is selected, check it can be found on default
1384 * or user-specified path, if not show a warning/help dialog
1387 protected void structureViewer_actionPerformed(String selectedItem)
1389 if (selectedItem.equals(ViewerType.JMOL.name()))
1391 structureViewerPath.setEnabled(false);
1392 structureViewerPathLabel.setEnabled(false);
1395 boolean found = false;
1396 structureViewerPath.setEnabled(true);
1397 structureViewerPathLabel.setEnabled(true);
1398 structureViewerPathLabel.setText(MessageManager
1399 .formatMessage("label.viewer_path", selectedItem));
1402 * Try user-specified and standard paths for structure viewer executable
1404 String viewerPath = "";
1405 List<String> paths = null;
1408 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1415 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1416 paths = StructureManager.getChimeraPaths(false);
1419 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1420 paths = StructureManager.getChimeraPaths(true);
1423 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1424 paths = PymolManager.getPymolPaths();
1427 } catch (IllegalArgumentException e)
1429 // only valid entries should be in the drop-down
1431 structureViewerPath.setText(viewerPath);
1433 paths.add(0, structureViewerPath.getText());
1434 for (String path : paths)
1436 if (new File(path.trim()).canExecute())
1445 String[] options = { "OK", "Help" };
1446 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1447 JvSwingUtils.wrapTooltip(true,
1448 MessageManager.getString("label.viewer_missing")),
1449 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1450 null, options, options[0]);
1452 if (showHelp == JvOptionPane.NO_OPTION)
1454 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1457 Help.showHelpWindow(HelpId.StructureViewer);
1458 } catch (HelpSetException e)
1460 e.printStackTrace();
1463 else if (showHelp == JvOptionPane.OK_OPTION)
1465 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1466 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1469 for (int i = 0; i < 3; i++)
1471 structureViewerPath.setBackground(Color.PINK);
1473 structureViewerPath.setBackground(Color.WHITE);
1476 } catch (InterruptedException e)
1484 public class OptionsParam
1486 private String name;
1488 private String code;
1490 public OptionsParam(String name, String code)
1496 public String getName()
1501 public void setName(String name)
1506 public String getCode()
1511 public void setCode(String code)
1517 public String toString()
1523 public boolean equals(Object that)
1525 if (!(that instanceof OptionsParam))
1529 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1533 public int hashCode()
1535 return name.hashCode() + code.hashCode();
1539 private class UrlListSelectionHandler implements ListSelectionListener
1543 public void valueChanged(ListSelectionEvent e)
1545 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1547 int index = lsm.getMinSelectionIndex();
1550 // no selection, so disable delete/edit buttons
1551 editLink.setEnabled(false);
1552 deleteLink.setEnabled(false);
1555 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1557 // enable/disable edit and delete link buttons
1558 if (((UrlLinkTableModel) linkUrlTable.getModel())
1559 .isRowDeletable(modelIndex))
1561 deleteLink.setEnabled(true);
1565 deleteLink.setEnabled(false);
1568 if (((UrlLinkTableModel) linkUrlTable.getModel())
1569 .isRowEditable(modelIndex))
1571 editLink.setEnabled(true);
1575 editLink.setEnabled(false);