diff --git a/build.xml b/build.xml index 46a4493..6580f30 100644 --- a/build.xml +++ b/build.xml @@ -78,7 +78,7 @@ - baseType() { TreeInterface tree; TreeTraitMap traitSet; //JTextField traitEntry; - JComboBox relativeToComboBox; + //ComboBox relativeToComboBox; String [] sTaxa; - Object[][] tableData; - JTable table; + // Object[][] tableData; + + + + public class LocationMap { + String taxon; + Double latitude; + Double longitude; + + LocationMap(String taxon, Double latitude, Double longitude) { + this.taxon = taxon; + this.latitude = latitude; + this.longitude = longitude; + } + + public String getTaxon() { + return taxon; + } + public void setTaxon(String taxon) { + this.taxon = taxon; + } + public Double getLongitude() { + return longitude; + } + public void setLongitude(Double longitude) { + this.longitude = longitude; + } + public Double getLatitude() { + return latitude; + } + public void setLatitude(Double latitude) { + this.latitude = latitude; + } + } + TableView table; + ObservableList taxonMapping; + //UserDataType dataType; //String m_sPattern = ".*(\\d\\d\\d\\d).*"; @@ -101,14 +138,14 @@ public void initPanel(SampledMultivariateTraitLikelihood likelihood_) { m_beastObject = traitData; traitSet = traitData.traitInput.get(); - Box box = Box.createVerticalBox(); + VBox box = new VBox(); if (traitSet != null) { - box.add(createButtonBox()); - box.add(createListBox()); - box.add(createButtonBox2()); + box.getChildren().add(createButtonBox()); + box.getChildren().add(createListBox()); + box.getChildren().add(createButtonBox2()); } - add(box); + getChildren().add(box); validateInput(); // synchronise with table, useful when taxa have been deleted convertTableDataToTrait(); @@ -117,7 +154,7 @@ public void initPanel(SampledMultivariateTraitLikelihood likelihood_) { - private Component createListBox() { + private ScrollPane createListBox() { try { //traitSet.treeInput.get().getTaxaNames(); TreeInterface tree = traitSet.treeInput.get(); @@ -128,106 +165,142 @@ private Component createListBox() { } sTaxa = traitSet.treeInput.get().getTaxonset().asStringList().toArray(new String[0]); String[] columnData = new String[]{"Name", "Latitude", "Longitude"}; - tableData = new Object[sTaxa.length][3]; + //tableData = new Object[sTaxa.length][3]; + + taxonMapping = FXCollections.observableArrayList(); + for (String s : sTaxa) { + taxonMapping.add(new LocationMap(s, Double.NaN, Double.NaN)); + } convertTraitToTableData(); + // set up table. // special features: background shading of rows // custom editor allowing only Date column to be edited. - table = new JTable(tableData, columnData) { - private static final long serialVersionUID = 1L; - - // method that induces table row shading - @Override - public Component prepareRenderer(TableCellRenderer renderer, int Index_row, int Index_col) { - Component comp = super.prepareRenderer(renderer, Index_row, Index_col); - //even index, selected or not selected - if (isCellSelected(Index_row, Index_col)) { - comp.setBackground(Color.lightGray); - } else if (Index_row % 2 == 0 && !isCellSelected(Index_row, Index_col)) { - comp.setBackground(new Color(237, 243, 255)); - } else { - comp.setBackground(Color.white); - } - return comp; - } - }; - - // set up editor that makes sure only doubles are accepted as entry - // and only the Date column is editable. - table.setDefaultEditor(Object.class, new TableCellEditor() { - JTextField m_textField = new JTextField(); - int m_iRow, m_iCol; - - @Override - public boolean stopCellEditing() { - table.removeEditor(); - String sText = m_textField.getText(); - if (sText == "") { - return false; - } - tableData[m_iRow][m_iCol] = sText; - convertTableDataToTrait(); - convertTraitToTableData(); - validateInput(); - return true; - } - - @Override - public boolean isCellEditable(EventObject anEvent) { - return table.getSelectedColumn() >= 1; - } - - - @Override - public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int iRow, int iCol) { - if (!isSelected) { - return null; - } - m_iRow = iRow; - m_iCol = iCol; - m_textField.setText((String) value); - return m_textField; - } - - @Override - public boolean shouldSelectCell(EventObject anEvent) { - return false; - } - - @Override - public void removeCellEditorListener(CellEditorListener l) { - } - - @Override - public Object getCellEditorValue() { - return null; - } - - @Override - public void cancelCellEditing() { - } - - @Override - public void addCellEditorListener(CellEditorListener l) { - } - - }); - table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); - table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); - table.setRowHeight(24); - table.getColumnModel().getColumn(0).setPreferredWidth(300); - table.getColumnModel().getColumn(1).setPreferredWidth(75); - table.getColumnModel().getColumn(2).setPreferredWidth(75); - JScrollPane scrollPane = new JScrollPane(table); + table = new TableView<>(); + table.setPrefWidth(1024); + table.setEditable(true); + table.setItems(taxonMapping); + + TableColumn col1 = new TableColumn<>("Taxon"); + col1.setPrefWidth(500); + col1.setEditable(false); + col1.setCellValueFactory( + new PropertyValueFactory("Taxon") + ); + table.getColumns().add(col1); + + TableColumn col2 = new TableColumn<>("Latitude"); + col2.setPrefWidth(500); + col2.setEditable(false); + col2.setCellValueFactory( + new PropertyValueFactory("Latitude") + ); + table.getColumns().add(col2); + + TableColumn col3 = new TableColumn<>("Longitude"); + col3.setPrefWidth(500); + col3.setEditable(false); + col3.setCellValueFactory( + new PropertyValueFactory("Longitude") + ); + table.getColumns().add(col3); + +// table = new Table(tableData, columnData) { +// private static final long serialVersionUID = 1L; +// +// // method that induces table row shading +// @Override +// public Component prepareRenderer(TableCellRenderer renderer, int Index_row, int Index_col) { +// Component comp = super.prepareRenderer(renderer, Index_row, Index_col); +// //even index, selected or not selected +// if (isCellSelected(Index_row, Index_col)) { +// comp.setBackground(Color.lightGray); +// } else if (Index_row % 2 == 0 && !isCellSelected(Index_row, Index_col)) { +// comp.setBackground(new Color(237, 243, 255)); +// } else { +// comp.setBackground(Color.white); +// } +// return comp; +// } +// }; +// +// // set up editor that makes sure only doubles are accepted as entry +// // and only the Date column is editable. +// table.setDefaultEditor(Object.class, new TableCellEditor() { +// JTextField m_textField = new JTextField(); +// int m_iRow, m_iCol; +// +// @Override +// public boolean stopCellEditing() { +// table.removeEditor(); +// String sText = m_textField.getText(); +// if (sText == "") { +// return false; +// } +// tableData[m_iRow][m_iCol] = sText; +// convertTableDataToTrait(); +// convertTraitToTableData(); +// validateInput(); +// return true; +// } +// +// @Override +// public boolean isCellEditable(EventObject anEvent) { +// return table.getSelectedColumn() >= 1; +// } +// +// +// @Override +// public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int iRow, int iCol) { +// if (!isSelected) { +// return null; +// } +// m_iRow = iRow; +// m_iCol = iCol; +// m_textField.setText((String) value); +// return m_textField; +// } +// +// @Override +// public boolean shouldSelectCell(EventObject anEvent) { +// return false; +// } +// +// @Override +// public void removeCellEditorListener(CellEditorListener l) { +// } +// +// @Override +// public Object getCellEditorValue() { +// return null; +// } +// +// @Override +// public void cancelCellEditing() { +// } +// +// @Override +// public void addCellEditorListener(CellEditorListener l) { +// } +// +// }); +// table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); +// table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); +// table.setRowHeight(24); +// table.getColumnModel().getColumn(0).setPreferredWidth(300); +// table.getColumnModel().getColumn(1).setPreferredWidth(75); +// table.getColumnModel().getColumn(2).setPreferredWidth(75); + ScrollPane scrollPane = new ScrollPane(table); return scrollPane; } // createListBox /* synchronise table with data from traitSet Plugin */ private void convertTraitToTableData() { - for (int i = 0; i < tableData.length; i++) { - tableData[i][0] = sTaxa[i]; - tableData[i][1] = ""; - tableData[i][2] = ""; + for (int i = 0; i < taxonMapping.size(); i++) { + LocationMap location = taxonMapping.get(i); + location.taxon = sTaxa[i]; + location.latitude = Double.NaN; + location.longitude = Double.NaN; } String trait = traitSet.value.get(); if (trait == null || trait.trim().length() == 0) { @@ -250,32 +323,42 @@ private void convertTraitToTableData() { System.err.println(sTaxonID); // throw new Exception("Trait (" + sTaxonID + ") is not a known taxon. Spelling error perhaps?"); } else { - tableData[iTaxon][0] = sTaxonID; + LocationMap location = taxonMapping.get(iTaxon); + location.taxon = sTaxonID; String [] sStrs2 = value.trim().split("\\s+"); if (sStrs2.length == 2) { - tableData[iTaxon][1] = sStrs2[0]; - tableData[iTaxon][2] = sStrs2[1]; + location.latitude = parseDouble(sStrs2[0]); + location.longitude = parseDouble(sStrs2[1]); } else { if (Character.isSpace(sStrs[1].charAt(0))) { - tableData[iTaxon][1] = ""; - tableData[iTaxon][2] = sStrs2[0]; + location.latitude = Double.NaN; + location.longitude = parseDouble(sStrs2[0]); } else { - tableData[iTaxon][1] = sStrs2[0]; - tableData[iTaxon][2] = ""; + location.latitude = parseDouble(sStrs2[0]); + location.longitude = Double.NaN; } } } } - if (table != null) { - for (int i = 0; i < tableData.length; i++) { - table.setValueAt(tableData[i][1], i, 1); - table.setValueAt(tableData[i][2], i, 2); - } - } + table.refresh(); +// if (table != null) { +// for (int i = 0; i < taxonMapping.size(); i++) { +// table.setValueAt(tableData[i][1], i, 1); +// table.setValueAt(tableData[i][2], i, 2); +// } +// } } // convertTraitToTableData - private int indexOf(String sTaxonID) { + private Double parseDouble(String string) { + try { + return Double.parseDouble(string); + } catch (NumberFormatException e) { + return Double.NaN; + } + } + + private int indexOf(String sTaxonID) { for (int i = 0; i < sTaxa.length; i++) { if (sTaxa[i].equals(sTaxonID)) { return i; @@ -290,9 +373,9 @@ private int indexOf(String sTaxonID) { void convertTableDataToTrait() { String sTrait = ""; //Set values = new HashSet(); - for (int i = 0; i < tableData.length; i++) { - sTrait += sTaxa[i] + "=" + tableData[i][1] + " " + tableData[i][2]; - if (i < tableData.length - 1) { + for (int i = 0; i < taxonMapping.size(); i++) { + sTrait += sTaxa[i] + "=" + taxonMapping.get(i).latitude + " " + taxonMapping.get(i).longitude; + if (i < taxonMapping.size() - 1) { sTrait += ",\n"; } } @@ -307,12 +390,12 @@ void convertTableDataToTrait() { /** * create box with comboboxes for selection units and trait name * */ - private Box createButtonBox() { - Box buttonBox = Box.createHorizontalBox(); + private HBox createButtonBox() { + HBox buttonBox = FXUtils.newHBox(); - JLabel label = new JLabel("Trait: "); + Label label = new Label("Trait: "); //label.setMaximumSize(new Dimension(1024, 20)); - buttonBox.add(label); + buttonBox.getChildren().add(label); // traitEntry = new JTextField(traitSet.m_sTraitName.get()); // traitEntry.getDocument().addDocumentListener(new DocumentListener() { @@ -333,46 +416,33 @@ private Box createButtonBox() { // }); // traitEntry.setColumns(12); // buttonBox.add(traitEntry); - buttonBox.add(Box.createHorizontalGlue()); - - JButton guessButton = new JButton("Guess latitude"); - guessButton.setName("Guess latitude"); - guessButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - guess(1); - } - }); - buttonBox.add(guessButton); + // buttonBox.add(Box.createHorizontalGlue()); + + Button guessButton = new Button("Guess latitude"); + guessButton.setId("Guess latitude"); + guessButton.setOnAction(e->guess(1)); + buttonBox.getChildren().add(guessButton); - JButton guessButton2 = new JButton("Guess longitude"); - guessButton2.setName("Guess longitude"); - guessButton2.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - guess(2); - } - }); - buttonBox.add(guessButton2); + Button guessButton2 = new Button("Guess longitude"); + guessButton2.setId("Guess longitude"); + guessButton2.setOnAction(e->guess(2)); + buttonBox.getChildren().add(guessButton2); - JButton clearButton = new JButton("Clear"); - clearButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { + Button clearButton = new Button("Clear"); + clearButton.setOnAction(e-> { try { traitSet.value.setValue("", traitSet); } catch (Exception ex) { // TODO: handle exception } refreshPanel(); - } }); - buttonBox.add(clearButton); + buttonBox.getChildren().add(clearButton); - m_validateLabel = new SmallLabel("x", Color.orange); + m_validateLabel = new SmallLabel("x", "orange"); m_validateLabel.setVisible(false); - buttonBox.add(m_validateLabel); + buttonBox.getChildren().add(m_validateLabel); return buttonBox; } // createButtonBox @@ -411,9 +481,13 @@ private void guess(int column) { String [] strs2 = str.trim().split("="); String taxon = strs2[0].trim(); String value = strs2[1].trim(); - for (int i = 0; i < tableData.length; i++) { - if (tableData[i][0].equals(taxon)) { - tableData[i][column] = value; + for (int i = 0; i < taxonMapping.size(); i++) { + if (taxonMapping.get(i).taxon.equals(taxon)) { + if (column == 1) { + taxonMapping.get(i).latitude = parseDouble(value); + } else { + taxonMapping.get(i).longitude = parseDouble(value); + } break; } } @@ -425,30 +499,20 @@ private void guess(int column) { } - private Box createButtonBox2() { - Box buttonBox = Box.createHorizontalBox(); + private HBox createButtonBox2() { + HBox buttonBox = FXUtils.newHBox(); - buttonBox.add(Box.createHorizontalGlue()); + // buttonBox.add(Box.createHorizontalGlue()); - JButton manipulateButton = new JButton("Manipulate latitude"); - manipulateButton.setName("Manipulate latitude"); - manipulateButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - manipulate(1); - } - }); - buttonBox.add(manipulateButton); + Button manipulateButton = new Button("Manipulate latitude"); + manipulateButton.setId("Manipulate latitude"); + manipulateButton.setOnAction(e->manipulate(1)); + buttonBox.getChildren().add(manipulateButton); - JButton manipulateButton2 = new JButton("Manipulate longitude"); - manipulateButton2.setName("Manipulate longitude"); - manipulateButton2.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - manipulate(2); - } - }); - buttonBox.add(manipulateButton2); + Button manipulateButton2 = new Button("Manipulate longitude"); + manipulateButton2.setId("Manipulate longitude"); + manipulateButton2.setOnAction(e->manipulate(2)); + buttonBox.getChildren().add(manipulateButton2); return buttonBox; } // createButtonBox2 @@ -464,24 +528,31 @@ public void actionPerformed(ActionEvent e) { private void manipulate(int column) { String operatee = (column == 1 ? "latitude" : "longitude"); - String formula = JOptionPane.showInputDialog(this, "Give a formula with $x as the " + operatee + - " e.g., -$x to make values negative
" + - "180+$x to add 180 to " + operatee + "
" + - "$x*2+10 to multiply by 2 and add 10
" + - "max($x,100) to get the maximum of " + operatee + " and 100", "Manipulate " + operatee, JOptionPane.OK_CANCEL_OPTION); + String formula = (String) Alert.showInputDialog(null, "Give a formula with $x as the " + operatee + + " e.g., -$x to make values negative\n" + + "180+$x to add 180 to " + operatee + "\n" + + "$x*2+10 to multiply by 2 and add 10\n" + + "max($x,100) to get the maximum of " + operatee + " and 100", "Manipulate " + operatee, Alert.QUESTION_MESSAGE, "$x"); if (formula == null || formula.trim().length() == 0) { return; } - for (int i = 0; i < tableData.length; i++) { - String value = tableData[i][column].toString(); + for (int i = 0; i < taxonMapping.size(); i++) { + String value = (column == 1 ? + taxonMapping.get(i).latitude.toString(): + taxonMapping.get(i).longitude.toString() + ); try { value = Double.parseDouble(value) + ""; } catch (Exception e) { value = "0"; } String newValue = value(formula, value); - tableData[i][column] = newValue; + if (column == 1) { + taxonMapping.get(i).latitude = parseDouble(newValue); + } else { + taxonMapping.get(i).longitude = parseDouble(newValue); + } } convertTableDataToTrait(); validateInput(); @@ -505,14 +576,14 @@ String value(String formula, String value) { @Override public void validateInput() { // check all values are specified - if (tableData == null) { + if (taxonMapping == null) { return; } - for (int i = 0; i < tableData.length; i++) { - if (tableData[i][1].toString().trim().length() == 0 || tableData[i][2].toString().trim().length() == 0) { + for (int i = 0; i < taxonMapping.size(); i++) { + if (Double.isNaN(taxonMapping.get(i).latitude) || Double.isNaN(taxonMapping.get(i).longitude)) { m_validateLabel.setVisible(true); - m_validateLabel.setToolTipText("trait for " + tableData[i][0] + " needs to be specified"); - m_validateLabel.repaint(); + m_validateLabel.setTooltip(new Tooltip("trait for " + taxonMapping.get(i).taxon + " needs to be specified")); + // m_validateLabel.repaint(); return; } } diff --git a/src/beastclassic/app/beauti/TraitInputEditor.java b/src/beastclassic/app/beauti/TraitInputEditor.java index 9a87416..da0708b 100644 --- a/src/beastclassic/app/beauti/TraitInputEditor.java +++ b/src/beastclassic/app/beauti/TraitInputEditor.java @@ -1,10 +1,6 @@ package beastclassic.app.beauti; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; + import java.util.ArrayList; import java.util.Collections; import java.util.EventObject; @@ -12,30 +8,33 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.swing.Box; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.event.CellEditorListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; - import beastfx.app.inputeditor.BeautiDoc; import beastfx.app.inputeditor.GuessPatternDialog; import beastfx.app.inputeditor.ListInputEditor; import beastfx.app.inputeditor.SmallLabel; +import beastfx.app.inputeditor.TaxonSetInputEditor.TaxonMap; +import beastfx.app.util.FXUtils; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; import beast.base.core.BEASTInterface; import beast.base.core.BEASTObject; import beast.base.core.Input; import beast.base.evolution.alignment.Alignment; import beast.base.evolution.alignment.TaxonSet; import beast.base.evolution.datatype.UserDataType; +import beastclassic.app.beauti.LocationInputEditor.LocationMap; import beastclassic.evolution.alignment.AlignmentFromTrait; import beastclassic.evolution.likelihood.AncestralStateTreeLikelihood; import beast.base.evolution.tree.TraitSet; @@ -58,11 +57,36 @@ public Class baseType() { AncestralStateTreeLikelihood likelihood; TreeInterface tree; TraitSet traitSet; - JTextField traitEntry; - JComboBox relativeToComboBox; + TextField traitEntry; + //ComboBox relativeToComboBox; List sTaxa; - Object[][] tableData; - JTable table; + // Object[][] tableData; + + public class LocationMap { + String taxon; + String trait; + + LocationMap(String taxon, String trait) { + this.taxon = taxon; + this.trait = trait; + } + + public String getTaxon() { + return taxon; + } + public void setTaxon(String taxon) { + this.taxon = taxon; + } + public String getTrait() { + return trait; + } + public void setTrait(String trait) { + this.trait = trait; + } + } + + TableView table; + ObservableList taxonMapping; UserDataType dataType; //String m_sPattern = ".*(\\d\\d\\d\\d).*"; @@ -131,18 +155,15 @@ public void initPanel(AncestralStateTreeLikelihood likelihood_) { dataType = (UserDataType)traitData.userDataTypeInput.get(); - Box box = Box.createVerticalBox(); - - JCheckBox useTipDates = new JCheckBox("Use traits", traitSet != null); - useTipDates.addActionListener(new ActionListener() { + VBox box = FXUtils.newVBox(); - @Override - public void actionPerformed(ActionEvent e) { - JCheckBox checkBox = (JCheckBox) e.getSource(); + CheckBox useTipDates = new CheckBox("Use traits"); + useTipDates.setSelected(traitSet != null); + useTipDates.setOnAction(e -> { try { - Container comp = checkBox.getParent(); - comp.removeAll(); - if (checkBox.isSelected()) { + Pane comp = (Pane) useTipDates.getParent(); + comp.getChildren().removeAll(); + if (useTipDates.isSelected()) { if (traitSet == null) { traitSet = new TraitSet(); String context = BeautiDoc.parsePartition(likelihood.getID()); @@ -151,28 +172,26 @@ public void actionPerformed(ActionEvent e) { "taxa", tree.getTaxonset(), "value", ""); } - comp.add(checkBox); - comp.add(createButtonBox()); - comp.add(createListBox()); + comp.getChildren().add(useTipDates); + comp.getChildren().add(createButtonBox()); + comp.getChildren().add(createListBox()); validateInput(); m_input.setValue(traitSet, m_beastObject); } else { m_input.setValue(null, m_beastObject); - comp.add(checkBox); + comp.getChildren().add(useTipDates); } } catch (Exception ex) { ex.printStackTrace(); } - - } }); //box.add(useTipDates); if (traitSet != null) { - box.add(createButtonBox()); - box.add(createListBox()); + box.getChildren().add(createButtonBox()); + box.getChildren().add(createListBox()); } - add(box); + getChildren().add(box); validateInput(); // synchronise with table, useful when taxa have been deleted convertTableDataToDataType(); @@ -182,7 +201,7 @@ public void actionPerformed(ActionEvent e) { - private Component createListBox() { + private ScrollPane createListBox() { try { traitSet.taxaInput.get().initAndValidate(); @@ -194,103 +213,146 @@ private Component createListBox() { sTaxa = traitSet.taxaInput.get().asStringList(); } String[] columnData = new String[]{"Name", "Trait"}; - tableData = new Object[sTaxa.size()][2]; + taxonMapping = FXCollections.observableArrayList(); + for (String s : sTaxa) { + taxonMapping.add(new LocationMap(s, "")); + } + // tableData = new Object[sTaxa.size()][2]; convertTraitToTableData(); + + + // set up table. // special features: background shading of rows // custom editor allowing only Date column to be edited. - table = new JTable(tableData, columnData) { - private static final long serialVersionUID = 1L; - - // method that induces table row shading - @Override - public Component prepareRenderer(TableCellRenderer renderer, int Index_row, int Index_col) { - Component comp = super.prepareRenderer(renderer, Index_row, Index_col); - //even index, selected or not selected - if (isCellSelected(Index_row, Index_col)) { - comp.setBackground(Color.lightGray); - } else if (Index_row % 2 == 0 && !isCellSelected(Index_row, Index_col)) { - comp.setBackground(new Color(237, 243, 255)); - } else { - comp.setBackground(Color.white); - } - return comp; - } - }; - - // set up editor that makes sure only doubles are accepted as entry - // and only the Date column is editable. - table.setDefaultEditor(Object.class, new TableCellEditor() { - JTextField m_textField = new JTextField(); - int m_iRow - , - m_iCol; - - @Override - public boolean stopCellEditing() { - table.removeEditor(); - String sText = m_textField.getText(); - if (sText == "") { - return false; - } - tableData[m_iRow][m_iCol] = sText; - convertTableDataToTrait(); - convertTraitToTableData(); - validateInput(); - return true; - } - - @Override - public boolean isCellEditable(EventObject anEvent) { - return table.getSelectedColumn() == 1; - } - - - @Override - public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int iRow, int iCol) { - if (!isSelected) { - return null; - } - m_iRow = iRow; - m_iCol = iCol; - m_textField.setText((String) value); - return m_textField; - } - - @Override - public boolean shouldSelectCell(EventObject anEvent) { - return false; - } - - @Override - public void removeCellEditorListener(CellEditorListener l) { - } - - @Override - public Object getCellEditorValue() { - return null; - } - - @Override - public void cancelCellEditing() { - } - - @Override - public void addCellEditorListener(CellEditorListener l) { - } - - }); - table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); - table.setRowHeight(24); - JScrollPane scrollPane = new JScrollPane(table); +// for (Taxon taxonset2 : m_taxonset) { +// if (taxonset2 instanceof TaxonSet) { +// for (Taxon taxon : ((TaxonSet) taxonset2).taxonsetInput.get()) { +// m_lineageset.add(taxon); +// m_taxonMap.put(taxon.getID(), taxonset2.getID()); +// taxonMapping.add(new TaxonMap(taxon.getID(), taxonset2.getID())); +// } +// } +// } + + // set up table. + // special features: background shading of rows + // custom editor allowing only Date column to be edited. + table = new TableView<>(); + table.setPrefWidth(1024); + table.setEditable(true); + table.setItems(taxonMapping); + + TableColumn col1 = new TableColumn<>("Taxon"); + col1.setPrefWidth(500); + col1.setEditable(false); + col1.setCellValueFactory( + new PropertyValueFactory("Taxon") + ); + table.getColumns().add(col1); + + TableColumn col2 = new TableColumn<>("Trait"); + col2.setPrefWidth(500); + col2.setEditable(false); + col2.setCellValueFactory( + new PropertyValueFactory("Trait") + ); + table.getColumns().add(col2); + + + +// table = new JTable(tableData, columnData) { +// private static final long serialVersionUID = 1L; +// +// // method that induces table row shading +// @Override +// public Component prepareRenderer(TableCellRenderer renderer, int Index_row, int Index_col) { +// Component comp = super.prepareRenderer(renderer, Index_row, Index_col); +// //even index, selected or not selected +// if (isCellSelected(Index_row, Index_col)) { +// comp.setBackground(Color.lightGray); +// } else if (Index_row % 2 == 0 && !isCellSelected(Index_row, Index_col)) { +// comp.setBackground(new Color(237, 243, 255)); +// } else { +// comp.setBackground(Color.white); +// } +// return comp; +// } +// }; +// +// // set up editor that makes sure only doubles are accepted as entry +// // and only the Date column is editable. +// table.setDefaultEditor(Object.class, new TableCellEditor() { +// JTextField m_textField = new JTextField(); +// int m_iRow +// , +// m_iCol; +// +// @Override +// public boolean stopCellEditing() { +// table.removeEditor(); +// String sText = m_textField.getText(); +// if (sText == "") { +// return false; +// } +// tableData[m_iRow][m_iCol] = sText; +// convertTableDataToTrait(); +// convertTraitToTableData(); +// validateInput(); +// return true; +// } +// +// @Override +// public boolean isCellEditable(EventObject anEvent) { +// return table.getSelectedColumn() == 1; +// } +// +// +// @Override +// public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int iRow, int iCol) { +// if (!isSelected) { +// return null; +// } +// m_iRow = iRow; +// m_iCol = iCol; +// m_textField.setText((String) value); +// return m_textField; +// } +// +// @Override +// public boolean shouldSelectCell(EventObject anEvent) { +// return false; +// } +// +// @Override +// public void removeCellEditorListener(CellEditorListener l) { +// } +// +// @Override +// public Object getCellEditorValue() { +// return null; +// } +// +// @Override +// public void cancelCellEditing() { +// } +// +// @Override +// public void addCellEditorListener(CellEditorListener l) { +// } +// +// }); +// table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); +// table.setRowHeight(24); + ScrollPane scrollPane = new ScrollPane(table); return scrollPane; } // createListBox /* synchronise table with data from traitSet Plugin */ private void convertTraitToTableData() { - for (int i = 0; i < tableData.length; i++) { - tableData[i][0] = sTaxa.get(i); - tableData[i][1] = ""; + for (int i = 0; i < taxonMapping.size(); i++) { + taxonMapping.get(i).taxon = sTaxa.get(i); + taxonMapping.get(i).trait = ""; } String trait = traitSet.traitsInput.get(); if (trait.trim().length() == 0) { @@ -313,15 +375,16 @@ private void convertTraitToTableData() { System.err.println(sTaxonID); // throw new Exception("Trait (" + sTaxonID + ") is not a known taxon. Spelling error perhaps?"); } else { - tableData[iTaxon][0] = sTaxonID; - tableData[iTaxon][1] = value; + taxonMapping.get(iTaxon).taxon = sTaxonID; + taxonMapping.get(iTaxon).trait = value; } } if (table != null) { - for (int i = 0; i < tableData.length; i++) { - table.setValueAt(tableData[i][1], i, 1); - } + table.refresh(); +// for (int i = 0; i < tableData.length; i++) { +// table.setValueAt(tableData[i][1], i, 1); +// } } } // convertTraitToTableData @@ -331,9 +394,9 @@ private void convertTraitToTableData() { private void convertTableDataToTrait() { String sTrait = ""; //Set values = new HashSet(); - for (int i = 0; i < tableData.length; i++) { - sTrait += sTaxa.get(i) + "=" + tableData[i][1]; - if (i < tableData.length - 1) { + for (int i = 0; i < taxonMapping.size(); i++) { + sTrait += taxonMapping.get(i).taxon + "=" + taxonMapping.get(i).trait; + if (i < taxonMapping.size() - 1) { sTrait += ",\n"; } } @@ -347,9 +410,9 @@ private void convertTableDataToTrait() { private void convertTableDataToDataType() { List values = new ArrayList(); - for (int i = 0; i < tableData.length; i++) { - if (tableData[i][1].toString().trim().length() > 0 && !values.contains(tableData[i][1].toString())) { - values.add(tableData[i][1].toString()); + for (int i = 0; i < taxonMapping.size(); i++) { + if (taxonMapping.get(i).trait.trim().length() > 0 && !values.contains(taxonMapping.get(i).trait)) { + values.add(taxonMapping.get(i).trait); } } Collections.sort(values); @@ -377,49 +440,45 @@ private void convertTableDataToDataType() { /** * create box with comboboxes for selection units and trait name * */ - private Box createButtonBox() { - Box buttonBox = Box.createHorizontalBox(); + private HBox createButtonBox() { + HBox buttonBox = FXUtils.newHBox(); - JLabel label = new JLabel("Trait: "); + Label label = new Label("Trait: "); //label.setMaximumSize(new Dimension(1024, 20)); - buttonBox.add(label); - - traitEntry = new JTextField(traitSet.traitNameInput.get()); - traitEntry.getDocument().addDocumentListener(new DocumentListener() { - - @Override - public void removeUpdate(DocumentEvent e) {update();} - @Override - public void insertUpdate(DocumentEvent e) {update();} - @Override - public void changedUpdate(DocumentEvent e) {update();} - void update() { - try { - traitSet.traitNameInput.setValue(traitEntry.getText(), traitSet); - } catch (Exception e) { - // TODO: handle exception - } - } - }); - traitEntry.setColumns(12); - buttonBox.add(traitEntry); - buttonBox.add(Box.createHorizontalGlue()); - - JButton guessButton = new JButton("Guess"); - guessButton.setName("guess"); - guessButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - guess(); - } + buttonBox.getChildren().add(label); + + traitEntry = new TextField(traitSet.traitNameInput.get()); + traitEntry.setOnKeyReleased(e->{ + try { + traitSet.traitNameInput.setValue(traitEntry.getText(), traitSet); + } catch (Exception ex) { + // TODO: handle exception + } }); - buttonBox.add(guessButton); - - - JButton clearButton = new JButton("Clear"); - clearButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { +// traitEntry.getDocument().addDocumentListener(new DocumentListener() { +// +// @Override +// public void removeUpdate(DocumentEvent e) {update();} +// @Override +// public void insertUpdate(DocumentEvent e) {update();} +// @Override +// public void changedUpdate(DocumentEvent e) {update();} +// void update() { +// } +// }); + //traitEntry.setColumns(12); + traitEntry.setMinWidth(12*15); + buttonBox.getChildren().add(traitEntry); + //buttonBox.add(Box.createHorizontalGlue()); + + Button guessButton = new Button("Guess"); + guessButton.setId("guess"); + guessButton.setOnAction(e->guess()); + buttonBox.getChildren().add(guessButton); + + + Button clearButton = new Button("Clear"); + clearButton.setOnAction(e-> { try { traitSet.traitsInput.setValue("", traitSet); convertTableDataToDataType(); @@ -427,13 +486,12 @@ public void actionPerformed(ActionEvent e) { // TODO: handle exception } refreshPanel(); - } - }); - buttonBox.add(clearButton); + }); + buttonBox.getChildren().add(clearButton); - m_validateLabel = new SmallLabel("x", Color.orange); + m_validateLabel = new SmallLabel("x", "orange"); m_validateLabel.setVisible(false); - buttonBox.add(m_validateLabel); + buttonBox.getChildren().add(m_validateLabel); return buttonBox; } // createButtonBox @@ -481,14 +539,14 @@ private void guess() { @Override public void validateInput() { // check all values are specified - if (tableData == null) { + if (taxonMapping == null) { return; } - for (int i = 0; i < tableData.length; i++) { - if (tableData[i][1].toString().trim().length() == 0) { + for (int i = 0; i < taxonMapping.size(); i++) { + if (taxonMapping.get(i).trait.trim().length() == 0) { m_validateLabel.setVisible(true); - m_validateLabel.setToolTipText("trait for " + tableData[i][0] + " needs to be specified"); - m_validateLabel.repaint(); + m_validateLabel.setTooltip("trait for " + taxonMapping.get(i).taxon + " needs to be specified"); + // m_validateLabel.repaint(); return; } }