package org.gepard.client.userinterface; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.io.File; import java.io.IOException; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.InputVerifier; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollBar; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.gepard.client.ClientGlobals; import org.gepard.client.Config; import org.gepard.client.Controller; import org.gepard.client.InvalidParamSetException; import org.gepard.client.SubstMatrixFile; import org.gepard.client.SubstMatrixList; import org.gepard.common.FASTAReader; import org.gepard.common.InvalidFASTAFileException; import org.gepard.common.InvalidSubMatFileException; import org.gepard.common.ParameterSet; import org.gepard.common.SubstitutionMatrix; public class ControlPanel extends JPanel implements AdjustmentListener, ActionListener, ChangeListener { private static final long serialVersionUID = 2211444361988984615L; private static NumberFormat INTFMT = new DecimalFormat("###,###,###,###,##0", new DecimalFormatSymbols(Locale.ENGLISH)); // main constants private static final int HOR_MARGIN = 5; private static final int CMB_HEIGHT = 18; private static final int SEQ_HEIGHT = 218; private static final int FUNCT_HEIGHT = 132; private static final int OPT_HEIGHT = 285; // sequence tab constants private static final int SEQ_TAB_SPACE_TOP = 3; private static final int SEQ_TAB_SPACE_BOTTOM = 3; private static final int SEQ_TAB_BETWEEN_SEQS = 10; private static final int SEQ_TAB_INITIAL_TOP = 5; private static final int SEQ_TAB_BUTTON_HEIGHT = 20; // function panel private static final int FUNCT_BETWEEN_ZOOM = 5; private static final int FUNCT_MARGIN_ZOOM = 10; private static final int FUNCT_GOADV_HOR_MARGIN = 40; private static final int FUNCT_ABOVE_GO = 8; private static final int FUNCT_BELOW_GO = 12; private static final int FUNCT_ABOVE_ADV = 20; // plotopt panel private static final int PLOTOPT_VERTSPACE = 2; private static final int PLOTOPT_EXTRAVERT = 5; private static final int PLOTOPT_BEGIN_VERTSPACE = 5; private static final int PLOTOPT_ITEMS_INDENT = 6; // misc tab private static final int MISC_VERTSPACE = 2; private static final int MISC_EXTRAVERT = 6; private static final int MISC_INITVERT = 3; // disp tab private static final int DISP_VERT_SMALL = 4; private static final int DISP_VERT_BIG = 8; private static final int DISP_ABOVE_EXPORT = 5; // quit button private static final int QUIT_BTN_HEIGHT = 27; private static final int BELOW_QUIT_BTN = 5; private static final int QUIT_BTN_HOR_MARGIN = 40; // font(s) private static final Font MAIN_FONT = new Font("Dialog", Font.BOLD, 11); private static final Font CAPT_FONT = new Font("Dialog", Font.BOLD, 12); private static final Font TEXT_FONT = new Font("Dialog", Font.PLAIN, 11); // CONTROLS // tabs private JTabbedPane seqTabs; private JTabbedPane optTabs; // "Local" tab private JButton btnLocalSeq1, btnLocalSeq2; private JTextField txtLocalSeq1, txtLocalSeq2; private JCheckBox chkFirstComp, chkSecondComp; // plot options tab private JCheckBox chkAutoZoom, chkSmallPlots, chkAutoParams, chkAutoMatrix; private JTextField txtZoom, txtWordlen, txtWinsize; private CustomComboBox cmbMatrices; // ... coordinates private JTextField txtStart1, txtStop1, txtStart2, txtStop2; // misc tab private JCheckBox chkSaveSA; private JLabel lblSASpace; private JButton btnDeleteSAs; private JRadioButton optLocalShowAlign, optLocalExport, optLocalDoNothing; private JButton btnSetupProxy; // display tab private JPanel dispTab; private JScrollBar scrLower, scrUpper, scrGreyscale;// , scrNuclDistr; private JCheckBox chkRevCompAlign; // global stuff private JButton btnGo; private JButton btnAdvanced; private JButton btnFullPlot; private JButton btnZoomOut; private JButton btnExportFile; private JButton btnZoomIn; private JButton btnQuit; private String curSubmatName; // current mode (simple or advanced) private boolean isAdvancedMode = false; // substitution matrix list private SubstMatrixFile[] substMatrices; // custom subst matrix private SubstitutionMatrix customMatrix = null; // sequence files changed? private boolean needreload; private boolean noScrollbarEvents = false; // controller object reference Controller ctrl; public ControlPanel(Controller ictrl) { // store controller ctrl = ictrl; // load substitution matrices from XML file try { substMatrices = SubstMatrixList.getInstance().getMatrixFiles(); } catch (Exception e) { ClientGlobals.errMessage("Could not open substitution matrix list. " + "The 'matrices/' subfolder seems to be corrupted"); System.exit(1); } // sequences panel JPanel localTab = generateLocalTab(); seqTabs = new JTabbedPane(); // add sequence panes seqTabs.addTab("Sequences", localTab); seqTabs.addChangeListener(this); // function panel JPanel functPanel = generateFunctionPanel(); // options panel JPanel plotOptTab = generatePlotOptTab(); JPanel miscTab = generateMiscTab(); dispTab = generateDispTab(); optTabs = new JTabbedPane(); optTabs.setFont(MAIN_FONT); // optTabs.setBorder(BorderFactory.createEmptyBorder()); optTabs.addTab("Plot", plotOptTab); optTabs.addTab("Misc", miscTab); optTabs.addTab("Display", dispTab); optTabs.setSelectedIndex(0); // create layout seqTabs.setAlignmentX(Component.LEFT_ALIGNMENT); optTabs.setAlignmentX(Component.LEFT_ALIGNMENT); btnGo.setAlignmentX(Component.LEFT_ALIGNMENT); functPanel.setAlignmentX(Component.LEFT_ALIGNMENT); JPanel fixedBox = new JPanel(); fixedBox.setLayout(new BoxLayout(fixedBox, BoxLayout.Y_AXIS)); // fixedBox.setLayout(new GridBagLayout()); fixedBox.add(Box.createRigidArea(new Dimension(0, 3))); fixedBox.add(seqTabs); fixedBox.add(Box.createRigidArea(new Dimension(0, 10))); fixedBox.add(functPanel); // fixedBox.add(Box.createRigidArea(new Dimension(0,10))); fixedBox.add(Box.createRigidArea(new Dimension(0, 10))); fixedBox.add(optTabs); seqTabs.setPreferredSize(new Dimension(1, SEQ_HEIGHT)); functPanel.setPreferredSize(new Dimension(1, FUNCT_HEIGHT)); optTabs.setPreferredSize(new Dimension(1, OPT_HEIGHT)); // dummy panel which pushes the go button to the bottom of the window JPanel panelQuit = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 0; c.gridy = 0; c.weightx = 1; c.weighty = 1000; panelQuit.add(new JLabel(""), c); c.gridy++; c.weighty = 1; c.insets = new Insets(0, HOR_MARGIN + QUIT_BTN_HOR_MARGIN, BELOW_QUIT_BTN, HOR_MARGIN + QUIT_BTN_HOR_MARGIN); panelQuit.add(btnQuit = new JButton("Quit"), c); btnQuit.setPreferredSize(new Dimension(1, QUIT_BTN_HEIGHT)); setLayout(new BorderLayout()); add(fixedBox, BorderLayout.NORTH); add(panelQuit, BorderLayout.CENTER); btnQuit.addActionListener(this); // simple or advanced mode if (Config.getInstance().getIntVal("advanced", 0) == 1) switchMode(true); else switchMode(false); // help tooltips btnQuit.setToolTipText(HelpTexts.getInstance().getHelpText("quit")); // set initial parameters needreload = true; setDispTabEnabled(false); setNavigationEnabled(false); } public void setGoButtonCaption(boolean update) { if (update) btnGo.setText("Update dotplot"); else btnGo.setText("Create dotplot"); } private JPanel generateFunctionPanel() { HelpTexts hlp = HelpTexts.getInstance(); JPanel functPane = new JPanel(); functPane.setLayout(new GridBagLayout()); // load icons ImageIcon icoZoomIn = new ImageIcon(this.getClass().getResource("/resources/images/zoomin.gif")); ImageIcon icoZoomOut = new ImageIcon(this.getClass().getResource("/resources/images/zoomout.gif")); ImageIcon icoShowFull = new ImageIcon(this.getClass().getResource("/resources/images/zoomfull.gif")); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.weighty = 1; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 4; c.insets = new Insets(FUNCT_ABOVE_GO, FUNCT_GOADV_HOR_MARGIN, FUNCT_BELOW_GO, FUNCT_GOADV_HOR_MARGIN); functPane.add(btnGo = getCustomButton(""), c); c.gridwidth = 1; c.gridy++; c.insets = new Insets(0, FUNCT_BETWEEN_ZOOM + FUNCT_MARGIN_ZOOM, 0, FUNCT_BETWEEN_ZOOM); functPane.add(btnZoomIn = new JButton(icoZoomIn), c); c.gridx++; c.insets = new Insets(0, FUNCT_BETWEEN_ZOOM, 0, FUNCT_BETWEEN_ZOOM); functPane.add(btnZoomOut = new JButton(icoZoomOut), c); c.gridx++; functPane.add(btnFullPlot = new JButton(icoShowFull), c); // advanced mode button c.insets = new Insets(FUNCT_ABOVE_ADV, FUNCT_GOADV_HOR_MARGIN, 0, FUNCT_GOADV_HOR_MARGIN); c.gridx = 0; c.gridy++; c.gridwidth = 4; functPane.add(btnAdvanced = getCustomButton(""), c); setGoButtonCaption(false); // insert stretcher c.gridy++; c.weighty = 10000; c.gridwidth = 1; functPane.add(new JLabel(), c); // event handlers btnGo.addActionListener(this); btnAdvanced.addActionListener(this); btnFullPlot.addActionListener(this); btnZoomIn.addActionListener(this); btnZoomOut.addActionListener(this); // set help texts btnGo.setToolTipText(hlp.getHelpText("createplot")); btnZoomIn.setToolTipText(hlp.getHelpText("zoomin")); btnZoomOut.setToolTipText(hlp.getHelpText("zoomout")); btnFullPlot.setToolTipText(hlp.getHelpText("fullplot")); btnAdvanced.setToolTipText(hlp.getHelpText("advmode")); return functPane; } private JPanel generateLocalTab() { HelpTexts hlp = HelpTexts.getInstance(); JPanel localPanel = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(SEQ_TAB_SPACE_TOP + SEQ_TAB_INITIAL_TOP, HOR_MARGIN, SEQ_TAB_SPACE_BOTTOM, HOR_MARGIN); c.gridx = 0; c.gridy = 0; c.gridwidth = 2; c.gridheight = 1; c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; localPanel.add(getLargeLabel("Sequence 1 (horizontal):"), c); c.insets = new Insets(SEQ_TAB_SPACE_TOP, HOR_MARGIN, SEQ_TAB_SPACE_BOTTOM, HOR_MARGIN); c.gridy++; localPanel.add(txtLocalSeq1 = getCustomTextField(""), c); c.gridy++; c.gridwidth = 1; c.gridx = 0; c.anchor = GridBagConstraints.WEST; localPanel.add(chkFirstComp = getCustomCheckbox("Complementary"), c); c.gridx++; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; localPanel.add(btnLocalSeq1 = getCustomButton("Select file"), c); btnLocalSeq1.setPreferredSize(new Dimension(100, SEQ_TAB_BUTTON_HEIGHT)); btnLocalSeq1.setMinimumSize(new Dimension(100, SEQ_TAB_BUTTON_HEIGHT)); c.gridwidth = 2; c.gridx = 0; // a little extra space c.insets = new Insets(SEQ_TAB_SPACE_TOP + SEQ_TAB_BETWEEN_SEQS, HOR_MARGIN, SEQ_TAB_SPACE_BOTTOM, HOR_MARGIN); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.gridy++; localPanel.add(getLargeLabel("Sequence 2 (vertical):"), c); c.insets = new Insets(SEQ_TAB_SPACE_TOP, HOR_MARGIN, SEQ_TAB_SPACE_BOTTOM, HOR_MARGIN); c.gridy++; localPanel.add(txtLocalSeq2 = getCustomTextField(""), c); c.gridy++; c.gridwidth = 1; c.gridx = 0; c.anchor = GridBagConstraints.WEST; localPanel.add(chkSecondComp = getCustomCheckbox("Complementary"), c); c.gridx++; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; localPanel.add(btnLocalSeq2 = getCustomButton("Select file"), c); btnLocalSeq2.setPreferredSize(new Dimension(100, SEQ_TAB_BUTTON_HEIGHT)); btnLocalSeq2.setMinimumSize(new Dimension(100, SEQ_TAB_BUTTON_HEIGHT)); // create empty jlabel which eats up the remaining space c.gridy++; c.weighty = 200; localPanel.add(new JLabel(""), c); // help tooltips txtLocalSeq1.setToolTipText(hlp.getHelpText("sequence1")); btnLocalSeq1.setToolTipText(hlp.getHelpText("sequence1select")); txtLocalSeq2.setToolTipText(hlp.getHelpText("sequence2")); btnLocalSeq2.setToolTipText(hlp.getHelpText("sequence2select")); // event handler btnLocalSeq1.addActionListener(this); btnLocalSeq2.addActionListener(this); chkFirstComp.addActionListener(this); chkSecondComp.addActionListener(this); return localPanel; } private JPanel generatePlotOptTab() { HelpTexts hlp = HelpTexts.getInstance(); JPanel plotOptTab = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); JLabel horStretcher; JLabel start1; c.weightx = 1; c.weighty = 1; c.gridx = 0; c.gridy = 0; c.fill = GridBagConstraints.HORIZONTAL; Insets defInsets = new Insets(0, HOR_MARGIN, PLOTOPT_VERTSPACE, HOR_MARGIN); Insets leftspaceInsets = new Insets(0, HOR_MARGIN + PLOTOPT_ITEMS_INDENT, PLOTOPT_VERTSPACE, HOR_MARGIN); Insets extraVertInsets = new Insets(0, HOR_MARGIN + PLOTOPT_ITEMS_INDENT, PLOTOPT_VERTSPACE + PLOTOPT_EXTRAVERT, HOR_MARGIN); c.gridwidth = 2; c.insets = new Insets(PLOTOPT_BEGIN_VERTSPACE, HOR_MARGIN, PLOTOPT_VERTSPACE, HOR_MARGIN); plotOptTab.add(getCustomLabel("Coordinates"), c); c.gridy++; c.gridwidth = 1; c.insets = leftspaceInsets; plotOptTab.add(start1 = getCustomLabel("Start 1:"), c); c.gridx++; c.insets = defInsets; plotOptTab.add(txtStart1 = getCustomTextField("0", 20), c); c.gridx++; c.insets = leftspaceInsets; plotOptTab.add(horStretcher = new JLabel()); c.gridx = 0; c.gridy++; c.insets = leftspaceInsets; plotOptTab.add(getCustomLabel("Stop 1:"), c); c.gridx++; c.insets = defInsets; plotOptTab.add(txtStop1 = getCustomTextField("0", 20), c); c.gridx = 0; c.gridy++; c.insets = leftspaceInsets; plotOptTab.add(getCustomLabel("Start 2:"), c); c.gridx++; c.insets = defInsets; plotOptTab.add(txtStart2 = getCustomTextField("0", 20), c); c.gridx = 0; c.gridy++; c.insets = extraVertInsets; plotOptTab.add(getCustomLabel("Stop 2:"), c); c.gridx++; c.insets = defInsets; plotOptTab.add(txtStop2 = getCustomTextField("0", 20), c); c.gridx = 0; c.gridy++; c.gridwidth = 1; c.insets = defInsets; plotOptTab.add(chkAutoZoom = getCustomCheckbox("Auto zoom"), c); c.gridx++; c.gridwidth = 2; plotOptTab.add(chkSmallPlots = getCustomCheckbox("Small plots"), c); c.gridx = 0; c.gridy++; c.gridwidth = 1; c.insets = extraVertInsets; plotOptTab.add(getCustomLabel("Zoom:"), c); c.gridx++; c.insets = defInsets; plotOptTab.add(txtZoom = getCustomTextField("0", 5), c); c.gridx = 0; c.gridy++; c.gridwidth = 2; plotOptTab.add(chkAutoParams = getCustomCheckbox("Auto params"), c); c.gridy++; c.gridwidth = 1; c.insets = leftspaceInsets; plotOptTab.add(getCustomLabel("Word length:"), c); c.gridx++; c.insets = defInsets; plotOptTab.add(txtWordlen = getCustomTextField("10", 5), c); c.gridx = 0; c.gridy++; c.insets = extraVertInsets; plotOptTab.add(getCustomLabel("Window size:"), c); c.gridx++; c.insets = defInsets; plotOptTab.add(txtWinsize = getCustomTextField("0", 5), c); c.gridx = 0; c.gridy++; c.gridwidth = 1; plotOptTab.add(chkAutoMatrix = getCustomCheckbox("Auto matrix"), c); c.gridy++; c.gridwidth = 1; c.insets = leftspaceInsets; plotOptTab.add(getCustomLabel("Use matrix:"), c); c.gridx++; c.gridwidth = 2; c.insets = defInsets; c.fill = GridBagConstraints.NONE; c.weighty = 1; plotOptTab.add(cmbMatrices = getCustomComboBox(), c); cmbMatrices.setMaximumSize(new Dimension(170, CMB_HEIGHT)); cmbMatrices.setMinimumSize(new Dimension(170, CMB_HEIGHT)); cmbMatrices.setPreferredSize(new Dimension(170, CMB_HEIGHT)); // insert stretcher c.gridy++; c.gridx = 0; c.weighty = 10000; c.gridwidth = 1; plotOptTab.add(new JLabel(""), c); // set sizes horStretcher.setMinimumSize(new Dimension(50, 1)); start1.setMinimumSize(new Dimension(140, 15)); // help tooltips chkAutoZoom.setToolTipText(hlp.getHelpText("autozoom")); txtZoom.setToolTipText(hlp.getHelpText("zoom")); chkAutoParams.setToolTipText(hlp.getHelpText("autoparams")); txtWordlen.setToolTipText(hlp.getHelpText("wordlen")); txtWinsize.setToolTipText(hlp.getHelpText("winsize")); txtStart1.setToolTipText(hlp.getHelpText("coordinates")); txtStop1.setToolTipText(hlp.getHelpText("coordinates")); txtStart2.setToolTipText(hlp.getHelpText("coordinates")); txtStop2.setToolTipText(hlp.getHelpText("coordinates")); chkAutoMatrix.setToolTipText(hlp.getHelpText("automatrix")); cmbMatrices.setToolTipText(hlp.getHelpText("substmatrix")); chkSmallPlots.setToolTipText(hlp.getHelpText("smallplots")); // set input verifiers txtZoom.setInputVerifier(new IntVerifier("Ratio", ClientGlobals.MINZOOM, ClientGlobals.MAXZOOM)); txtWordlen.setInputVerifier(new IntVerifier("Word length", ClientGlobals.MINWORDLEN - 1, ClientGlobals.MAXWORDLEN)); txtWinsize.setInputVerifier(new IntVerifier("Window size", ClientGlobals.MINWINDOWSIZE, ClientGlobals.MAXWINDOWSIZE)); txtStart1.setInputVerifier(new IntVerifier("Coordinates", 0, Integer.MAX_VALUE)); txtStop1.setInputVerifier(new IntVerifier("Coordinates", 0, Integer.MAX_VALUE)); txtStart2.setInputVerifier(new IntVerifier("Coordinates", 0, Integer.MAX_VALUE)); txtStop2.setInputVerifier(new IntVerifier("Coordinates", 0, Integer.MAX_VALUE)); // event handler chkAutoZoom.addActionListener(this); chkAutoParams.addActionListener(this); chkAutoMatrix.addActionListener(this); cmbMatrices.addActionListener(this); chkSmallPlots.addActionListener(this); // read values for auto zoom and auto parameters from config chkAutoZoom.setSelected(Config.getInstance().getIntVal("autozoom", 1) == 1 ? true : false); chkAutoParams.setSelected(Config.getInstance().getIntVal("autoparams", 1) == 1 ? true : false); chkAutoMatrix.setSelected(Config.getInstance().getIntVal("automatrix", 1) == 1 ? true : false); chkSmallPlots.setSelected(Config.getInstance().getIntVal("smallplots", 0) == 1 ? true : false); // enable/disable text boxes accordingly txtZoom.setEnabled(!chkAutoZoom.isSelected()); txtWordlen.setEnabled(!chkAutoParams.isSelected()); txtWinsize.setEnabled(!chkAutoParams.isSelected()); cmbMatrices.setEnabled(!chkAutoMatrix.isSelected()); chkSmallPlots.setEnabled(chkAutoZoom.isSelected()); fillSubstMatrixCombo(); return plotOptTab; } private void switchMode(boolean advanced) { if (advanced) { btnAdvanced.setText("<< Simple mode"); optTabs.setVisible(true); isAdvancedMode = true; } else { btnAdvanced.setText(">> Advanced mode"); optTabs.setVisible(false); isAdvancedMode = false; } // store setting Config.getInstance().setIntVal("advanced", isAdvancedMode ? 1 : 0); } private void fillSubstMatrixCombo() { cmbMatrices.removeAllItems(); for (int i = 0; i < substMatrices.length; i++) // cmbMatrices.addItem("ya"); cmbMatrices.addItem(substMatrices[i].getName()); cmbMatrices.adaptPopupWidth(); } private JPanel generateMiscTab() { JPanel miscTab = new JPanel(); HelpTexts hlp = HelpTexts.getInstance(); miscTab.setLayout(new GridBagLayout()); Insets defInsets = new Insets(MISC_VERTSPACE, HOR_MARGIN, 0, HOR_MARGIN); Insets extraVertInsets = new Insets(MISC_VERTSPACE, HOR_MARGIN, MISC_EXTRAVERT, HOR_MARGIN); Insets initInsets = new Insets(MISC_VERTSPACE + MISC_INITVERT, HOR_MARGIN, 0, HOR_MARGIN); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.weightx = 1; c.weighty = 1; c.anchor = GridBagConstraints.WEST; c.gridy++; c.insets = initInsets; miscTab.add(chkSaveSA = getCustomCheckbox("Save suffix arrays "), c); c.gridy++; c.insets = defInsets; miscTab.add(lblSASpace = getCustomLabel(""), c); c.gridy++; c.insets = extraVertInsets; miscTab.add(btnDeleteSAs = getCustomButton("Delete suffix array files"), c); c.gridy++; c.insets = defInsets; miscTab.add(getCustomLabel("Local dotplot click action..."), c); c.gridy++; miscTab.add(optLocalShowAlign = getCustomRadioButton("... show alignment"), c); c.gridy++; miscTab.add(optLocalExport = getCustomRadioButton("... export window to FASTA"), c); c.gridy++; c.insets = extraVertInsets; miscTab.add(optLocalDoNothing = getCustomRadioButton("... do nothing"), c); c.gridy++; miscTab.add(btnSetupProxy = getCustomButton("HTTP proxy settings"), c); // set sizes btnDeleteSAs.setPreferredSize(new Dimension(175, 24)); btnDeleteSAs.setMinimumSize(new Dimension(175, 24)); btnSetupProxy.setPreferredSize(new Dimension(175, 24)); btnSetupProxy.setMinimumSize(new Dimension(175, 24)); // insert stretcher c.gridy++; c.weighty = 100000; c.gridwidth = 1; miscTab.add(new JLabel(""), c); updateSADiskSpace(); // pre-select optLocalShowAlign.setSelected(true); // create button groups ButtonGroup localGrp = new ButtonGroup(); localGrp.add(optLocalShowAlign); localGrp.add(optLocalExport); localGrp.add(optLocalDoNothing); // load values from config chkSaveSA.setSelected(Config.getInstance().getIntVal("savesa", 0) == 1 ? true : false); optLocalShowAlign.setSelected(Config.getInstance().getIntVal("local_click", 0) == 0 ? true : false); optLocalExport.setSelected(Config.getInstance().getIntVal("local_click", 0) == 1 ? true : false); optLocalDoNothing.setSelected(Config.getInstance().getIntVal("local_click", 0) == 2 ? true : false); // tell GUI if alignments shall be shown (for local plots) ctrl.showAlignments(optLocalShowAlign.isSelected()); // add action listeners chkSaveSA.addActionListener(this); optLocalShowAlign.addActionListener(this); optLocalExport.addActionListener(this); optLocalDoNothing.addActionListener(this); btnDeleteSAs.addActionListener(this); btnSetupProxy.addActionListener(this); // help tooltips chkSaveSA.setToolTipText(hlp.getHelpText("savesa")); optLocalShowAlign.setToolTipText(hlp.getHelpText("localclick")); optLocalDoNothing.setToolTipText(hlp.getHelpText("localclick")); btnDeleteSAs.setToolTipText(hlp.getHelpText("deletesas")); btnSetupProxy.setToolTipText(hlp.getHelpText("httpproxy")); return miscTab; } private JRadioButton getCustomRadioButton(String caption) { JRadioButton ret = new JRadioButton(caption); ret.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); ret.setFont(MAIN_FONT); return ret; } private JCheckBox getCustomCheckbox(String caption) { JCheckBox ret = new JCheckBox(caption); ret.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); ret.setFont(MAIN_FONT); return ret; } private JButton getCustomButton(String caption) { JButton ret = new JButton(caption); ret.setFont(MAIN_FONT); return ret; } private JLabel getCustomLabel(String caption) { JLabel ret = new JLabel(caption); ret.setFont(MAIN_FONT); return ret; } private JLabel getLargeLabel(String caption) { JLabel ret = new JLabel(caption); ret.setFont(CAPT_FONT); return ret; } private JTextField getCustomTextField(String text, int size) { JTextField ret = new JTextField(text, size); ret.setFont(TEXT_FONT); return ret; } private JTextField getCustomTextField(String text) { JTextField ret = new JTextField(text); ret.setFont(TEXT_FONT); return ret; } private CustomComboBox getCustomComboBox() { CustomComboBox ret = new CustomComboBox(); ret.setFont(TEXT_FONT); ret.setPreferredSize(new Dimension(1, CMB_HEIGHT)); return ret; } private JPanel generateDispTab() { JPanel dispTab = new JPanel(); HelpTexts hlp = HelpTexts.getInstance(); ImageIcon icoExport = new ImageIcon(this.getClass().getResource("/resources/images/export.gif")); Insets smallInsets = new Insets(DISP_VERT_SMALL, HOR_MARGIN, 0, HOR_MARGIN); Insets bigInsets = new Insets(DISP_VERT_BIG, HOR_MARGIN, 0, HOR_MARGIN); Insets extraInsets = new Insets(DISP_VERT_BIG + DISP_ABOVE_EXPORT, HOR_MARGIN, 0, HOR_MARGIN); GridBagConstraints c = new GridBagConstraints(); dispTab.setLayout(new GridBagLayout()); c.gridx = 0; c.gridy = 0; c.gridwidth = 2; c.gridheight = 1; c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = smallInsets; dispTab.add(getCustomLabel("Lower color limit:"), c); c.gridy++; dispTab.add(scrLower = new JScrollBar(SwingConstants.HORIZONTAL, 0, 0, 0, 1), c); c.gridy++; c.insets = bigInsets; dispTab.add(getCustomLabel("Upper color limit:"), c); c.gridy++; c.insets = smallInsets; dispTab.add(scrUpper = new JScrollBar(SwingConstants.HORIZONTAL, 0, 0, 0, 1), c); c.gridy++; c.insets = bigInsets; dispTab.add(getCustomLabel("Greyscale start:"), c); c.gridy++; c.insets = smallInsets; dispTab.add(scrGreyscale = new JScrollBar(SwingConstants.HORIZONTAL, 0, 0, 0, 100), c); c.gridy++; c.insets = bigInsets; dispTab.add(chkRevCompAlign = getCustomCheckbox("Reverse complementary alignment"), c); c.gridy++; c.insets = smallInsets; c.gridx = 0; c.gridy++; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = extraInsets; c.gridwidth = 1; dispTab.add(getCustomLabel("Export image:"), c); c.gridx++; c.anchor = GridBagConstraints.EAST; dispTab.add(btnExportFile = new JButton(icoExport), c); // btnExportFile = new JButton(icoExport); // insert stretcher c.gridy++; c.weighty = 10000; c.gridwidth = 1; dispTab.add(new JLabel(), c); // help tooltips scrLower.setToolTipText(hlp.getHelpText("lowerlimit")); scrUpper.setToolTipText(hlp.getHelpText("upperlimit")); scrGreyscale.setToolTipText(hlp.getHelpText("greyscale")); btnExportFile.setToolTipText(hlp.getHelpText("export")); chkRevCompAlign.setToolTipText(hlp.getHelpText("reversecomplementary")); // add event handler scrLower.addAdjustmentListener(this); scrUpper.addAdjustmentListener(this); scrGreyscale.addAdjustmentListener(this); btnExportFile.addActionListener(this); chkRevCompAlign.addActionListener(this); // set size of export button btnExportFile.setMaximumSize(new Dimension(20, 30)); return dispTab; } private void setDispTabEnabled(boolean e) { Component[] components = dispTab.getComponents(); for (int i = 0; i < components.length; i++) components[i].setEnabled(e); } private void setNavigationEnabled(boolean e) { btnZoomOut.setEnabled(e); btnZoomIn.setEnabled(e); btnFullPlot.setEnabled(e); btnExportFile.setEnabled(e); } // called by controller when dotplot starts being calculated public void dotplotStartCalc() { btnGo.setEnabled(false); setDispTabEnabled(false); setNavigationEnabled(false); } // called by controller when dotplot is ready public void dotplotReady() { btnGo.setEnabled(true); setDispTabEnabled(true); setNavigationEnabled(true); } // called by controller when dotplot calculation failed public void dotplotFailed() { btnGo.setEnabled(true); if (ctrl.dotplotExists()) { setDispTabEnabled(true); setNavigationEnabled(true); } // reset coordinates txtStart1.setText("0"); txtStop1.setText("0"); txtStart2.setText("0"); txtStop2.setText("0"); } public boolean saveSuffixArrays() { return chkSaveSA.isSelected(); } public boolean needReload() { return needreload; } public void setNeedReload(boolean c) { // set changed flag needreload = c; } // setup scrollbar parameters according to current dotmatrix public void setupScrollbars(float lowest, float highest) { noScrollbarEvents = true; // round limit value scrLower.setMaximum((int) (highest * 100)); scrUpper.setMaximum((int) (highest * 100)); scrLower.setMinimum((int) (lowest * 100)); scrUpper.setMinimum((int) (lowest * 100)); // set scrollbar increment values scrLower.setUnitIncrement((int) (highest / 10)); scrLower.setBlockIncrement((int) (highest)); scrUpper.setUnitIncrement((int) (highest / 10)); scrUpper.setBlockIncrement((int) (highest)); noScrollbarEvents = false; } public void setScrollbars(float percentLower, float percentUpper, float percentGreyscale, float percentFunCats) { noScrollbarEvents = true; // set values scrUpper.setValue((int) ((float) (scrUpper.getMaximum() - scrUpper.getMinimum()) / 100f * (float) percentUpper) + scrUpper.getMinimum()); scrLower.setValue((int) ((float) (scrLower.getMaximum() - scrLower.getMinimum()) / 100f * (float) percentLower) + scrLower.getMinimum()); scrGreyscale.setValue( (int) ((float) (scrGreyscale.getMaximum() - scrGreyscale.getMinimum()) / 100f * (float) percentGreyscale) + scrGreyscale.getMinimum()); // manually call adjustment value change handler to invoke // Plotter.reCalc() noScrollbarEvents = false; adjustmentValueChanged(null); } public void adjustmentValueChanged(AdjustmentEvent evt) { try { if (!noScrollbarEvents) { // get values int lv = scrLower.getValue(), uv = scrUpper.getValue(), gv = scrGreyscale.getValue(); // assure lower value is not higher than upper value if (lv >= uv) { scrLower.setValue(uv - 1); lv = uv - 1; } // replot ctrl.eventReplot(lv / 100f, uv / 100f, gv / 100f); } } catch (Exception e) { e.printStackTrace(); ClientGlobals.unexpectedError(e, ctrl); } } public void actionPerformed(ActionEvent evt) { // catch everything (which is not caught by inner try blocks) try { // check which control generated the event if (evt.getSource() == cmbMatrices) { // *** MATRIX CHANGED, RELOAD REQUIRED needreload = true; // check if the user wants to select a custom matrix file if (substMatrices[cmbMatrices.getSelectedIndex()].getFile().equals("-")) { FileChooseResult f = showFileDialog("Select matrix file", true, false); // set value in GUI if (f.file != null) { // try to load this file try { customMatrix = SubstitutionMatrix.loadFromFile(f.file); customMatrix.setNucleotideMatrix(false); } catch (InvalidSubMatFileException e) { ClientGlobals.warnMessage("The substitution matrix seems to be invalid.\nPlease specify a matrix file in Blast compatible format."); customMatrix = null; } } } else customMatrix = null; } else if ((evt.getSource() == btnLocalSeq1) || (evt.getSource() == btnLocalSeq2)) { // *** SELECT SEQUENCE FILE // show dialog FileChooseResult f = showFileDialog("Select sequence file", true, false); // set value in GUI if (f.file != null) { if (evt.getSource() == btnLocalSeq1) // set first sequence txtLocalSeq1.setText(f.file); else // set second sequence txtLocalSeq2.setText(f.file); newDotplot(); } } else if (evt.getSource() == btnGo) { initiateLocalDotplot(); } else if (evt.getSource() == chkAutoZoom) { // *** auto ratio checkbox // enable/disable ratio text box txtZoom.setEnabled(!chkAutoZoom.isSelected()); chkSmallPlots.setEnabled(chkAutoZoom.isSelected()); chkSmallPlots.setSelected(false); // save config setting Config.getInstance().setVal("autozoom", chkAutoZoom.isSelected() ? "1" : "0"); } else if (evt.getSource() == chkAutoParams) { // *** auto params checkbox // enable/disable wordlen & winsize text box txtWordlen.setEnabled(!chkAutoParams.isSelected()); txtWinsize.setEnabled(!chkAutoParams.isSelected()); // save config setting Config.getInstance().setVal("autoparams", chkAutoParams.isSelected() ? "1" : "0"); } else if (evt.getSource() == btnFullPlot) { // *** show full dotplot ctrl.zoomFullPlot(); } else if (evt.getSource() == btnZoomOut) { // *** zoom out ctrl.zoom(ClientGlobals.ZOOMOUTFACTOR); } else if (evt.getSource() == btnZoomIn) { // *** zoom in ctrl.zoom(ClientGlobals.ZOOMINFACTOR); } else if (evt.getSource() == btnExportFile) { // *** export image FileChooseResult f = showFileDialog("Store plot to image file", false, true); // report to controller if (f.file != null) ctrl.eventExportImage(f.file, f.type); } else if (evt.getSource() == chkSaveSA) { // save config setting Config.getInstance().setVal("savesa", chkSaveSA.isSelected() ? "1" : "0"); } else if (evt.getSource() == optLocalShowAlign) { // tell controller if alignments will be shown setupForAlignments(); // save setting Config.getInstance().setVal("local_click", "0"); } else if (evt.getSource() == optLocalExport) { // tell controller if alignments will be shown setupForAlignments(); // save setting Config.getInstance().setVal("local_click", "1"); } else if (evt.getSource() == optLocalDoNothing) { // tell controller if alignments will be shown setupForAlignments(); // save setting Config.getInstance().setVal("local_click", "2"); } else if (evt.getSource() == btnAdvanced) switchMode(!isAdvancedMode); else if (evt.getSource() == chkAutoMatrix) { // set GUI if (chkAutoMatrix.isSelected()) { cmbMatrices.setEnabled(false); cmbMatrices.setSelectedIndex(0); // store setting Config.getInstance().setVal("automatrix", "1"); } else { cmbMatrices.setEnabled(true); // store setting Config.getInstance().setVal("automatrix", "0"); } } else if (evt.getSource() == btnDeleteSAs) { // delete suffix array files deleteSAFiles(); updateSADiskSpace(); } else if (evt.getSource() == btnQuit) { ctrl.exit(); } else if (evt.getSource() == btnSetupProxy) { new ProxyDialog(ctrl); } else if (evt.getSource() == chkSmallPlots) { // store setting Config.getInstance().setVal("smallplots", (chkSmallPlots.isSelected()) ? "1" : "0"); } else if (evt.getSource() == chkFirstComp) { if (chkFirstComp.isSelected()) chkSecondComp.setSelected(false); newDotplot(); } else if (evt.getSource() == chkSecondComp) { if (chkSecondComp.isSelected()) chkFirstComp.setSelected(false); newDotplot(); } else if (evt.getSource() == chkRevCompAlign) { ctrl.updateAlignment(); } } catch (Exception e) { e.printStackTrace(); ClientGlobals.unexpectedError(e, ctrl); } } private void setupForAlignments() { // local mode if (optLocalShowAlign.isSelected()) ctrl.showAlignments(true); else ctrl.showAlignments(false); } private void newDotplot() { // set changed flag needreload = true; // set coordinates to zero txtStart1.setText("0"); txtStop1.setText("0"); txtStart2.setText("0"); txtStop2.setText("0"); // set go-button caption setGoButtonCaption(false); } private void initiateLocalDotplot() { // check if the user actually selected two sequences if (txtLocalSeq1.getText().trim().equals("") || txtLocalSeq2.getText().trim().equals("")) { ClientGlobals.warnMessage("Please select two sequence files."); return; } // determine type of both sequence files boolean firstSecIsNucl; try { firstSecIsNucl = FASTAReader.isNucleotideFile(txtLocalSeq1.getText()); } catch (IOException e) { ClientGlobals.errMessage("Failed loading sequence file 1\nIO error: " + e.getMessage()); return; } catch (InvalidFASTAFileException e) { ClientGlobals.errMessage("Failed loading sequence file 1\nInvalid FASTA file: " + e.getMessage()); return; } boolean secondSecIsNucl; try { secondSecIsNucl = FASTAReader.isNucleotideFile(txtLocalSeq2.getText()); } catch (IOException e) { ClientGlobals.errMessage("Failed loading sequence file 2\nIO error: " + e.getMessage()); return; } catch (InvalidFASTAFileException e) { ClientGlobals.errMessage("Failed loading sequence file 2\nInvalid FASTA file: " + e.getMessage()); return; } // load matrix String basePath = ClientGlobals.PATH_MATRICES; SubstitutionMatrix mat; if (!chkAutoMatrix.isSelected()) { // no automatrix-mode if (customMatrix == null) { // use specified matrix mat = loadSubstMatrix(basePath + substMatrices[cmbMatrices.getSelectedIndex()].getFile()); mat.setNucleotideMatrix(substMatrices[cmbMatrices.getSelectedIndex()].isNucleotideMatrix()); curSubmatName = substMatrices[cmbMatrices.getSelectedIndex()].getName(); } else { // use custom matrix mat = customMatrix; curSubmatName = "Custom"; } // one cannot use custom DNA substitution matrices if (customMatrix != null && (firstSecIsNucl || secondSecIsNucl)) { ClientGlobals.warnMessage("Custom matrices are only allowed for protein dotplots."); return; } } else { // auto-matrix mode // check if both types are equal if (firstSecIsNucl != secondSecIsNucl) { ClientGlobals.warnMessage("The two sequences do not seem to have the same type (DNA/Protein).\n" + "Please choose different sequences or do not use auto-matrix mode."); return; } // now set automatic matrix if (firstSecIsNucl) { mat = loadSubstMatrix(basePath + ClientGlobals.AUTO_NUCL_MATRIX); curSubmatName = ClientGlobals.AUTO_NUCL_MATRIX_NAME; mat.setNucleotideMatrix(true); } else { mat = loadSubstMatrix(basePath + ClientGlobals.AUTO_PROT_MATRIX); curSubmatName = ClientGlobals.AUTO_PROT_MATRIX_NAME; mat.setNucleotideMatrix(false); } } // get parameters ParameterSet params; try { params = getParameterSet(false); } catch (InvalidParamSetException e) { // do nothing, getParameterSet() has already informed the user return; } if (params == null) { dotplotFailed(); return; } // do last GUI check if ((params.wordLength == 0) && (params.windowSize == 0)) { ClientGlobals.warnMessage("Whether window size or word length must have a non-zero value"); return; } if (mat != null) { // determine if theres a sequence we need to use the complementary // of int compseq = 0; if (chkFirstComp.isSelected()) compseq = 1; if (chkSecondComp.isSelected()) compseq = 2; // create local dotplot ctrl.initiateLocalDotplot(mat, txtLocalSeq1.getText(), txtLocalSeq2.getText(), params, compseq); } } public ParameterSet getParameterSet(boolean novalidation) throws InvalidParamSetException { // read values try { int ratio = Integer.parseInt(txtZoom.getText()); int wordlen = Integer.parseInt(txtWordlen.getText()); int windowsize = Integer.parseInt(txtWinsize.getText()); int seq1start = Integer.parseInt(txtStart1.getText()); int seq1stop = Integer.parseInt(txtStop1.getText()); int seq2start = Integer.parseInt(txtStart2.getText()); int seq2stop = Integer.parseInt(txtStop2.getText()); // parameter validation if (!novalidation && (((seq1stop <= seq1start) && (seq1start != 0 || seq1stop != 0)) || ((seq2stop <= seq2start) && (seq2start != 0 || seq2stop != 0)))) { ClientGlobals.warnMessage("Sequence start parameter must be smaller than stop parameter"); throw new InvalidParamSetException(); } // return parameter set return new ParameterSet(ratio, wordlen, windowsize, seq1start, seq1stop, seq2start, seq2stop, curSubmatName); } catch (Exception e) { // we need to catch an exception here as GUI values became corrupted // sometimes ClientGlobals.warnMessage("Something went wrong in the GUI, please try again what you were just intending to do."); e.printStackTrace(); return null; } } public void setParameterSet(ParameterSet params) { // set values txtZoom.setText(params.zoom + ""); txtWordlen.setText(params.wordLength + ""); txtWinsize.setText(params.windowSize + ""); txtStart1.setText(params.seq1Start + ""); txtStop1.setText(params.seq1Stop + ""); txtStart2.setText(params.seq2Start + ""); txtStop2.setText(params.seq2Stop + ""); } public boolean useAutoZoom() { return chkAutoZoom.isSelected(); } public boolean useAutoParameters() { return chkAutoParams.isSelected(); } public void showOptionsTab() { optTabs.setSelectedIndex(0); } public void showDisplayTab() { optTabs.setSelectedIndex(2); } public int getLocalClickAction() { if (optLocalShowAlign.isSelected()) return ClientGlobals.LOCALCLICK_SHOWALIGN; else if (optLocalExport.isSelected()) return ClientGlobals.LOCALCLICK_EXPORT; else return ClientGlobals.LOCALCLICK_NOTHING; } private FileChooseResult showFileDialog(String title, boolean open, boolean imageexport) { // create file chooser object JFileChooser f; if (!imageexport) f = new JFileChooser(Config.getInstance().getStringVal("lastopendir", "")); else f = new JFileChooser(Config.getInstance().getStringVal("lastopendir_export", "")); if (imageexport) { // remove first filter f.removeChoosableFileFilter(f.getFileFilter()); ExampleFileFilter filter = new ExampleFileFilter(); filter.addExtension("jpg"); filter.addExtension("jpeg"); filter.setDescription("JPEG image files"); f.addChoosableFileFilter(filter); filter = new ExampleFileFilter(); filter.addExtension("png"); filter.setDescription("PNG image files"); f.addChoosableFileFilter(filter); filter = new ExampleFileFilter(); filter.addExtension("bmp"); filter.setDescription("Bitmap image files"); f.addChoosableFileFilter(filter); } // show correct dialog int retval; if (open) retval = f.showOpenDialog(this); else retval = f.showSaveDialog(this); if (retval == JFileChooser.APPROVE_OPTION && f.getSelectedFile() != null) { // store dir if (!imageexport) Config.getInstance().setVal("lastopendir", f.getSelectedFile().getParent()); else Config.getInstance().setVal("lastopendir_export", f.getSelectedFile().getParent()); String filename = f.getSelectedFile().getAbsolutePath(); String selextension; // append extension if needed and if in image mode if (imageexport) { // get extension of selected type ExampleFileFilter sel = (ExampleFileFilter) f.getFileFilter(); selextension = sel.getFirstExtension(); // if this is a save file dialog and the entered file name // does not have an extension -> add extension if (!open && (filename.lastIndexOf(".") == -1)) filename += "." + selextension; } else selextension = ""; // return filename and type return new FileChooseResult(filename, selextension); } else return new FileChooseResult(null, null); } private SubstitutionMatrix loadSubstMatrix(String file) { // call static load method try { SubstitutionMatrix mat = SubstitutionMatrix.loadFromResource(file); return mat; } catch (IOException e) { JOptionPane.showMessageDialog(null, "IO error while opening matrix file:\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); return null; } catch (InvalidSubMatFileException e) { // JOptionPane.showMessageDialog(null, "Could not load matrix file:\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); return null; } } class IntVerifier extends InputVerifier { private String m_name; private int m_min, m_max; public IntVerifier(String name, int min, int max) { m_name = name; m_min = min; m_max = max; } public boolean verify(JComponent input) { // get text String contents = ((JTextField) input).getText(); // assume valid input boolean valueok = true; // check if text field contains a valid integer between m_min and // m_max try { int value = Integer.parseInt(contents); if ((value < m_min) || (value > m_max)) valueok = false; } catch (NumberFormatException nfe) { valueok = false; } if (valueok == false) // show warning message JOptionPane.showMessageDialog(input.getParent().getParent(), m_name + " must be a valid integer between " + INTFMT.format(m_min) + " and " + INTFMT.format(m_max), "Invalid value", JOptionPane.WARNING_MESSAGE); return valueok; } } private class FileChooseResult { public String file; public String type; public FileChooseResult(String file, String type) { this.file = file; this.type = type; } } private long calcCurrentSADiskSpace() { long totalSize = 0; // iterate over file list String[] saFiles = new File(ClientGlobals.SETTINGS_DIR).list(); for (int i = 0; i < saFiles.length; i++) { // check for .sa extension if (saFiles[i].substring(saFiles[i].length() - 3).equals(".sa")) totalSize += new File(ClientGlobals.SETTINGS_DIR + System.getProperty("file.separator") + saFiles[i]).length(); } return totalSize; } private void deleteSAFiles() { // iterate over file list String[] saFiles = new File(ClientGlobals.SETTINGS_DIR).list(); for (int i = 0; i < saFiles.length; i++) { // check for .sa extension if (saFiles[i].substring(saFiles[i].length() - 3).equals(".sa")) new File(ClientGlobals.SETTINGS_DIR + System.getProperty("file.separator") + saFiles[i]).delete(); } } public void updateSADiskSpace() { lblSASpace.setText("Suffix arrays diskspace: " + ClientGlobals.convenientFileSize(calcCurrentSADiskSpace())); } public void stateChanged(ChangeEvent arg0) { // disable funcat tab in local mode optTabs.setEnabledAt(3, seqTabs.getSelectedIndex() == 1); setupForAlignments(); } public boolean smallPlots() { return chkSmallPlots.isSelected(); } public void uncheckFirstComp() { chkFirstComp.setSelected(false); } public void uncheckSecondComp() { chkSecondComp.setSelected(false); } public String getGUIDump() { StringBuilder guidump = new StringBuilder(); // local sequences guidump.append("==== LOCAL SEQUENCES ====\n"); guidump.append("Sequence 1: " + this.txtLocalSeq1.getText() + "\n"); guidump.append("Seq1comp : " + this.chkFirstComp.isSelected() + "\n"); guidump.append("Sequence 2: " + this.txtLocalSeq2.getText() + "\n"); guidump.append("Seq2comp : " + this.chkSecondComp.isSelected() + "\n"); guidump.append("\n"); // plot settings guidump.append("==== PLOT SETTINGS ====\n"); guidump.append("Seq1 coords : " + this.txtStart1.getText() + "-" + this.txtStop1.getText() + "\n"); guidump.append("Seq2 coords : " + this.txtStart2.getText() + "-" + this.txtStop2.getText() + "\n"); guidump.append("Auto zoom : " + this.chkAutoZoom.isSelected() + "\n"); guidump.append("Small plots: " + this.chkSmallPlots.isSelected() + "\n"); guidump.append("Zoom : " + this.txtZoom.getText() + "\n"); guidump.append("Auto params : " + this.chkAutoParams.isSelected() + "\n"); guidump.append("Word length : " + this.txtWordlen.getText() + "\n"); guidump.append("Window size : " + this.txtWinsize.getText() + "\n"); guidump.append("Auto matrix: " + this.chkAutoMatrix.isSelected() + "\n"); guidump.append("Matrix : " + this.cmbMatrices.getSelectedItem() + "\n"); guidump.append("\n"); // misc settings guidump.append("==== MISC SETTINGS ====\n"); guidump.append("Save SAs: " + this.chkSaveSA.isSelected() + "\n"); String localaction; if (this.optLocalDoNothing.isSelected()) localaction = "Do nothing"; else localaction = "Show alignment"; guidump.append("Local click action: " + localaction + "\n"); guidump.append("\n"); return guidump.toString(); } public void setRevComplAlign(boolean revcomp) { chkRevCompAlign.setSelected(revcomp); } public boolean reverseComplementaryAlignments() { return chkRevCompAlign.isSelected(); } public void setNucleotidePlot(boolean nuclplot) { if (nuclplot) { chkRevCompAlign.setEnabled(true); } else { chkRevCompAlign.setEnabled(false); chkRevCompAlign.setSelected(false); } } }