package viz.panel; import javax.swing.JPanel; import java.awt.Dimension; import java.awt.GridBagLayout; import java.util.List; import javax.swing.JCheckBox; import java.awt.GridBagConstraints; import javax.swing.JLabel; import java.awt.Insets; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import viz.DensiTree; import viz.DensiTree.LineWidthMode; import viz.DensiTree.MetaDataType; import viz.util.Util; import javax.swing.JSpinner; import java.util.ArrayList; import javax.swing.JComboBox; import javax.swing.JSeparator; public class LineWidthPanel extends JPanel implements ChangeListener { final static public String HELP_LINE_WIDTH = "Determine line width of trees of both tree set and consensus trees." + "For consensus trees, the average value for the topology is used.\n" + "DEFAULT: all lines are same width.\n" + "BY_META_DATA_PATTERN: use value of pattern specified below.\n" + "BY_META_DATA_NUMBER: use the N-th attribute value in the meta data.\n" + "meta data attribute: only available if any meta data attribute is specified. Use value of the attribute for line width of branches."; final static public String HELP_PATTERN = "Regular expression used for width of branches when BY_META_DATA_PATTERN " + "is chosen. The string of the pattern between brackets is selected as value.;"; final static public String HELP_TOP = "Specifies N-th meta data attribute for top of branch when BY_META_DATA_NUMBER is seleced."; final static public String HELP_LINE_WIDTH_BOTTOM = "Line width at bottom of branch.\n" + "same as top: use same specification as for top of branch.\n" + "Fit to bottom: adjust bottom widths so they fit to top of branch below.\n" + "BY_META_DATA_PATTERN: use value of pattern specified below.\n" + "BY_META_DATA_NUMBER: use the N-th attribute value in the meta data.\n" + "meta data attribute: only available if any meta data attribute is specified. Use value of the attribute for line width of branches."; final static public String HELP_BOTTOM = "Specifies N-th meta data attribute for top of branch when BY_META_DATA_NUMBER is seleced."; final static public String HELP_ZERO_BASED = "If selected, the minimum value is zero, otherwise the minimum value of the range of " + "whatever value is used."; final static public String HELP_SCALE = "Scale width with this number."; private static final long serialVersionUID = 1L; private JTextField textField; private JTextField textField_1; private JTextField textField_3; JSpinner spinner; JSpinner spinner_1; SpinnerNumberModel topOfBranchModel; SpinnerNumberModel bottomOfBranchModel; JComboBox<String> comboBoxBottom; JComboBox<String> comboBoxTop= new JComboBox<>(); final static String SAME_AS_BOTTOM = "Same as top"; final static String MAKE_FIT_BOTTOM = "Make fit to bottom"; DensiTree m_dt; private JSeparator separator; private JSeparator separator_1; JCheckBox chckbxZeroBased; public LineWidthPanel(DensiTree dt) { m_dt = dt; m_dt.addChangeListener(this); GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[]{0, 0}; gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; gridBagLayout.columnWeights = new double[]{1.0, 0.0}; setLayout(gridBagLayout); comboBoxBottom = new JComboBox<>(); stateChanged(null); comboBoxBottom.setPreferredSize(new Dimension(130,20)); comboBoxBottom.setMaximumSize(new Dimension(130,200)); comboBoxBottom.setSelectedItem(m_dt.m_lineWidthMode); comboBoxBottom.addActionListener(e-> { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { String selected = comboBoxBottom.getSelectedItem().toString(); LineWidthMode oldMode = m_dt.m_lineWidthMode; String oldTag = m_dt.m_lineWidthTag; if (selected.equals(LineWidthMode.DEFAULT.toString())) { m_dt.m_lineWidthMode = LineWidthMode.DEFAULT; } else if (selected.equals(LineWidthMode.BY_METADATA_PATTERN.toString())) { m_dt.m_lineWidthMode = LineWidthMode.BY_METADATA_PATTERN; } else if (selected.equals(LineWidthMode.BY_METADATA_NUMBER.toString())) { m_dt.m_lineWidthMode = LineWidthMode.BY_METADATA_NUMBER; } else { m_dt.m_lineWidthTag = selected; m_dt.m_lineWidthMode = LineWidthMode.BY_METADATA_TAG; } m_dt.resetStyle(); // txtPattern.setEnabled(m_dt.m_lineColorMode == LineColorMode.BY_METADATA_PATTERN); // chckbxShowLegend.setEnabled(m_dt.m_lineColorMode == LineColorMode.BY_METADATA_PATTERN // || m_dt.m_lineColorMode == LineColorMode.COLOR_BY_METADATA_TAG); if (m_dt.m_lineWidthMode != oldMode || (m_dt.m_lineWidthTag != null && !m_dt.m_lineWidthTag.equals(oldTag))) { m_dt.calcLineWidths(true); m_dt.makeDirty(); } updateEnabled(); repaint(); } }); }); GridBagConstraints gbc_comboBox = new GridBagConstraints(); gbc_comboBox.gridwidth = 2; gbc_comboBox.insets = new Insets(0, 0, 5, 0); //gbc_comboBox.fill = GridBagConstraints.HORIZONTAL; gbc_comboBox.gridx = 0; gbc_comboBox.gridy = 2; add(comboBoxBottom, gbc_comboBox); textField_1 = new JTextField(m_dt.m_sLineWidthPattern); GridBagConstraints gbc_textField_1 = new GridBagConstraints(); gbc_textField_1.fill = GridBagConstraints.HORIZONTAL; gbc_textField_1.insets = new Insets(0, 0, 5, 0); gbc_textField_1.gridx = 0; gbc_textField_1.gridy = 3; gbc_textField_1.gridwidth= 2; add(textField_1, gbc_textField_1); textField_1.setColumns(10); textField_1.addActionListener(e-> { try { m_dt.m_sLineWidthPattern = textField_1.getText(); if (m_dt.m_lineWidthMode!= LineWidthMode.DEFAULT) { m_dt.calcLineWidths(true); m_dt.makeDirty(); } } catch (Exception ex) {} }); bottomOfBranchModel = new SpinnerNumberModel(m_dt.m_iPatternForBottom, 1, 100, 1); topOfBranchModel = new SpinnerNumberModel(m_dt.m_iPatternForTop, 0, 100, 1); bottomOfBranchModel.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { m_dt.m_iPatternForBottom = (Integer) bottomOfBranchModel.getValue(); if (m_dt.m_iPatternForBottom < 1) { m_dt.m_iPatternForBottom = 1; } if (m_dt.m_lineWidthMode!= LineWidthMode.DEFAULT) { m_dt.m_pattern = m_dt.createPattern(); m_dt.calcLineWidths(true); m_dt.makeDirty(); } } }); topOfBranchModel.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { m_dt.m_iPatternForTop = (Integer) topOfBranchModel.getValue(); if (m_dt.m_iPatternForTop < 0) { m_dt.m_iPatternForTop = 0; } if (m_dt.m_lineWidthMode!= LineWidthMode.DEFAULT) { m_dt.m_pattern = m_dt.createPattern(); m_dt.calcLineWidths(true); m_dt.makeDirty(); } } }); JLabel lblNumberOfItem_1 = new JLabel("top"); GridBagConstraints gbc_lblNumberOfItem_1 = new GridBagConstraints(); gbc_lblNumberOfItem_1.anchor = GridBagConstraints.EAST; gbc_lblNumberOfItem_1.insets = new Insets(0, 0, 5, 5); gbc_lblNumberOfItem_1.gridx = 0; gbc_lblNumberOfItem_1.gridy = 4; add(lblNumberOfItem_1, gbc_lblNumberOfItem_1); spinner = new JSpinner(bottomOfBranchModel); GridBagConstraints gbc_spinner = new GridBagConstraints(); gbc_spinner.insets = new Insets(0, 0, 5, 0); gbc_spinner.gridx = 1; gbc_spinner.gridy = 4; add(spinner, gbc_spinner); spinner.setMaximumSize(new Dimension(1,20)); separator_1 = new JSeparator(); GridBagConstraints gbc_separator_1 = new GridBagConstraints(); gbc_separator_1.insets = new Insets(0, 0, 5, 5); gbc_separator_1.gridx = 0; gbc_separator_1.gridy = 5; add(separator_1, gbc_separator_1); GridBagConstraints gbc_comboBoxTop = new GridBagConstraints(); gbc_comboBoxTop.gridwidth = 2; gbc_comboBoxTop.insets = new Insets(0, 0, 5, 0); gbc_comboBoxTop.gridx = 0; gbc_comboBoxTop.gridy = 6; add(comboBoxTop, gbc_comboBoxTop); comboBoxTop.setPreferredSize(new Dimension(130,20)); comboBoxTop.setMaximumSize(new Dimension(130,200)); comboBoxTop.setSelectedItem(m_dt.m_lineWidthMode); comboBoxTop.addActionListener(ea-> { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { String selected = comboBoxTop.getSelectedItem().toString(); LineWidthMode oldMode = m_dt.m_lineWidthModeTop; String oldTag = m_dt.m_lineWidthTagTop; boolean oldCorrectTopOfBranch = m_dt.m_bCorrectTopOfBranch; if (selected.equals(SAME_AS_BOTTOM)) { m_dt.m_lineWidthModeTop = LineWidthMode.DEFAULT; } else if (selected.equals(MAKE_FIT_BOTTOM)) { m_dt.m_lineWidthModeTop = LineWidthMode.DEFAULT; m_dt.m_bCorrectTopOfBranch = true; } else if (selected.equals(LineWidthMode.BY_METADATA_PATTERN.toString())) { m_dt.m_lineWidthModeTop = LineWidthMode.BY_METADATA_PATTERN; } else if (selected.equals(LineWidthMode.BY_METADATA_NUMBER.toString())) { m_dt.m_lineWidthModeTop = LineWidthMode.BY_METADATA_NUMBER; } else { m_dt.m_lineWidthTagTop = selected; m_dt.m_lineWidthModeTop = LineWidthMode.BY_METADATA_TAG; } m_dt.m_bCorrectTopOfBranch = selected.equals(MAKE_FIT_BOTTOM); m_dt.resetStyle(); // txtPattern.setEnabled(m_dt.m_lineColorMode == LineColorMode.BY_METADATA_PATTERN); // chckbxShowLegend.setEnabled(m_dt.m_lineColorMode == LineColorMode.BY_METADATA_PATTERN // || m_dt.m_lineColorMode == LineColorMode.COLOR_BY_METADATA_TAG); if (m_dt.m_lineWidthModeTop != oldMode || (m_dt.m_lineWidthTag != null && !m_dt.m_lineWidthTagTop.equals(oldTag)) || oldCorrectTopOfBranch != m_dt.m_bCorrectTopOfBranch) { m_dt.calcLineWidths(true); m_dt.makeDirty(); } updateEnabled(); repaint(); } }); }); textField = new JTextField(m_dt.m_sLineWidthPatternTop); GridBagConstraints gbc_textField = new GridBagConstraints(); gbc_textField.fill = GridBagConstraints.HORIZONTAL; gbc_textField.gridwidth = 2; gbc_textField.insets = new Insets(0, 0, 5, 0); gbc_textField.gridx = 0; gbc_textField.gridy = 7; add(textField, gbc_textField); textField.addActionListener(ea-> { try { m_dt.m_sLineWidthPatternTop = textField.getText(); m_dt.calcLineWidths(true); m_dt.makeDirty(); } catch (Exception ex) {} }); textField.setColumns(10); JLabel lblNumberOfItem = new JLabel("bottom"); GridBagConstraints gbc_lblNumberOfItem = new GridBagConstraints(); gbc_lblNumberOfItem.anchor = GridBagConstraints.EAST; gbc_lblNumberOfItem.insets = new Insets(0, 0, 5, 5); gbc_lblNumberOfItem.gridx = 0; gbc_lblNumberOfItem.gridy = 8; add(lblNumberOfItem, gbc_lblNumberOfItem); spinner_1 = new JSpinner(topOfBranchModel); GridBagConstraints gbc_spinner_1 = new GridBagConstraints(); gbc_spinner_1.insets = new Insets(0, 0, 5, 0); gbc_spinner_1.gridx = 1; gbc_spinner_1.gridy = 8; add(spinner_1, gbc_spinner_1); spinner_1.setToolTipText("when 0, top will be egual to bottom"); spinner_1.setMaximumSize(new Dimension(1,20)); chckbxZeroBased = new JCheckBox("Zero based"); chckbxZeroBased.setSelected(m_dt.m_bWidthsAreZeroBased); chckbxZeroBased.addActionListener(ea-> { boolean bPrev = m_dt.m_bCorrectTopOfBranch; m_dt.m_bWidthsAreZeroBased = ((JCheckBox) ea.getSource()).isSelected(); if (bPrev != m_dt.m_bWidthsAreZeroBased) { m_dt.calcLineWidths(true); m_dt.makeDirty(); } }); separator = new JSeparator(); GridBagConstraints gbc_separator = new GridBagConstraints(); gbc_separator.insets = new Insets(0, 0, 5, 5); gbc_separator.gridx = 0; gbc_separator.gridy = 9; add(separator, gbc_separator); GridBagConstraints gbc_chckbxZeroBased = new GridBagConstraints(); gbc_chckbxZeroBased.insets = new Insets(0, 0, 5, 0); gbc_chckbxZeroBased.gridwidth = 2; gbc_chckbxZeroBased.anchor = GridBagConstraints.WEST; gbc_chckbxZeroBased.gridx = 0; gbc_chckbxZeroBased.gridy = 10; add(chckbxZeroBased, gbc_chckbxZeroBased); GridBagConstraints gbc_lblMetaDataScale = new GridBagConstraints(); gbc_lblMetaDataScale.anchor = GridBagConstraints.EAST; gbc_lblMetaDataScale.insets = new Insets(0, 0, 0, 5); gbc_lblMetaDataScale.gridx = 0; gbc_lblMetaDataScale.gridy = 11; JLabel lblMetaDataScale = new JLabel("Scale"); add(lblMetaDataScale, gbc_lblMetaDataScale); GridBagConstraints gbc_textField_3 = new GridBagConstraints(); gbc_textField_3.fill = GridBagConstraints.HORIZONTAL; gbc_textField_3.gridwidth = 1; gbc_textField_3.gridx = 1; gbc_textField_3.gridy = 11; textField_3 = new JTextField(m_dt.m_treeDrawer.LINE_WIDTH_SCALE + ""); add(textField_3, gbc_textField_3); textField_3.setColumns(3); textField_3.addActionListener(ea-> { try { m_dt.m_treeDrawer.LINE_WIDTH_SCALE = Float.parseFloat(textField_3.getText()); if (m_dt.m_lineWidthMode!= LineWidthMode.DEFAULT) { m_dt.makeDirty(); } } catch (Exception ex) {} }); updateEnabled(); // layout debugging // for (Component c : getComponents()) { // if (c instanceof JComponent) { // ((JComponent)c).setBorder(BorderFactory.createLineBorder(Color.black)); // } // } textField.setToolTipText(Util.formatToolTipAsHtml(HELP_PATTERN)); textField_1.setToolTipText(Util.formatToolTipAsHtml(HELP_PATTERN)); textField_3.setToolTipText(Util.formatToolTipAsHtml(HELP_SCALE)); spinner.setToolTipText(Util.formatToolTipAsHtml(HELP_TOP)); spinner_1.setToolTipText(Util.formatToolTipAsHtml(HELP_BOTTOM)); lblNumberOfItem_1.setToolTipText(Util.formatToolTipAsHtml(HELP_TOP)); lblNumberOfItem.setToolTipText(Util.formatToolTipAsHtml(HELP_BOTTOM)); comboBoxBottom.setToolTipText(Util.formatToolTipAsHtml(HELP_LINE_WIDTH)); comboBoxTop.setToolTipText(Util.formatToolTipAsHtml(HELP_LINE_WIDTH_BOTTOM)); chckbxZeroBased.setToolTipText(Util.formatToolTipAsHtml(HELP_ZERO_BASED)); } private void updateEnabled() { if (textField_1 == null) { return; } textField_3.setEnabled(m_dt.m_lineWidthMode != LineWidthMode.DEFAULT); chckbxZeroBased.setEnabled(m_dt.m_lineWidthMode != LineWidthMode.DEFAULT); textField_1.setEnabled(m_dt.m_lineWidthMode == LineWidthMode.BY_METADATA_PATTERN); spinner.setEnabled(m_dt.m_lineWidthMode == LineWidthMode.BY_METADATA_NUMBER); textField.setEnabled(false); spinner_1.setEnabled(false); if (m_dt.m_lineWidthMode == LineWidthMode.DEFAULT) { comboBoxTop.setEnabled(false); } else { comboBoxTop.setEnabled(true); if (m_dt.m_lineWidthModeTop == LineWidthMode.BY_METADATA_PATTERN) { textField.setEnabled(true); } if (m_dt.m_lineWidthModeTop == LineWidthMode.BY_METADATA_NUMBER) { spinner_1.setEnabled(true); } } } @Override public void stateChanged(ChangeEvent e) { List<String> selection = new ArrayList<String>(); List<String> selectionTop = new ArrayList<String>(); selection.add(LineWidthMode.DEFAULT.toString()); selectionTop.add(SAME_AS_BOTTOM); selectionTop.add(MAKE_FIT_BOTTOM); if (m_dt.m_bMetaDataReady) { selection.add(LineWidthMode.BY_METADATA_PATTERN.toString()); selectionTop.add(LineWidthMode.BY_METADATA_PATTERN.toString()); selection.add(LineWidthMode.BY_METADATA_NUMBER.toString()); selectionTop.add(LineWidthMode.BY_METADATA_NUMBER.toString()); for (int i = 0; i < m_dt.m_metaDataTags.size(); i++) { if (m_dt.m_metaDataTypes.get(i).equals(MetaDataType.NUMERIC)) { selection.add(m_dt.m_metaDataTags.get(i)); selectionTop.add(m_dt.m_metaDataTags.get(i)); } } } ComboBoxModel<String> model = new DefaultComboBoxModel<>(selection.toArray(new String[0])); comboBoxBottom.setModel(model); model = new DefaultComboBoxModel<>(selectionTop.toArray(new String[0])); comboBoxTop.setModel(model); if (m_dt.m_lineWidthMode == LineWidthMode.DEFAULT) { comboBoxBottom.setSelectedItem(LineWidthMode.DEFAULT.toString()); } else if (m_dt.m_lineWidthMode == LineWidthMode.BY_METADATA_PATTERN) { comboBoxBottom.setSelectedItem(LineWidthMode.BY_METADATA_PATTERN.toString()); } else if (m_dt.m_lineWidthMode == LineWidthMode.BY_METADATA_NUMBER) { comboBoxBottom.setSelectedItem(LineWidthMode.BY_METADATA_NUMBER.toString()); } else { comboBoxBottom.setSelectedItem(m_dt.m_lineWidthTag); } if (m_dt.m_lineWidthModeTop == LineWidthMode.DEFAULT) { if (m_dt.m_bCorrectTopOfBranch) { comboBoxTop.setSelectedItem(MAKE_FIT_BOTTOM); } else { comboBoxTop.setSelectedItem(SAME_AS_BOTTOM); } } else if (m_dt.m_lineWidthModeTop == LineWidthMode.BY_METADATA_PATTERN) { comboBoxTop.setSelectedItem(LineWidthMode.BY_METADATA_PATTERN.toString()); } else if (m_dt.m_lineWidthModeTop == LineWidthMode.BY_METADATA_NUMBER) { comboBoxTop.setSelectedItem(LineWidthMode.BY_METADATA_NUMBER.toString()); } else { comboBoxTop.setSelectedItem(m_dt.m_lineWidthTagTop); } updateEnabled(); } }