package org.gitools.ui.app.fileimport.wizard.text; /* * #%L * gitools-ui-app * %% * Copyright (C) 2013 Biomedical Genomics Lab * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import org.gitools.ui.app.fileimport.wizard.text.reader.FlatTextImporter; import org.gitools.ui.platform.dialog.MessageStatus; import org.gitools.ui.platform.wizard.AbstractWizardPage; import org.gitools.utils.readers.FileField; import org.gitools.utils.readers.FileHeader; import org.gitools.utils.readers.MatrixReaderProfile; import org.gitools.utils.readers.profile.ReaderProfileValidationException; import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; public class SelectMatrixColumnsPage extends AbstractWizardPage implements IFileImportStep { private FlatTextImporter reader; private JPanel mainPanel; private JList<FileHeader> valuesHeaderList; private JList<FileHeader> ignoredHeaderList; private JTextPane previewPane; private JSpinner columnIdsSpinner; private JSpinner rowIdsSpinner; private JButton previewRowIdsButton; private JButton previewColumnIdsButton; private JFormattedTextField valueNameBox; private JLabel previewLabel; private List<FileHeader> allheaders; private List<List<FileField>> preview; private FileHeader lastSelected; private static String ID = "id"; private static String COLUMN = "column"; private String lastPreview; private FileHeader rowIdsHeader; private boolean rowIdsHeaderWasIgnored = true; public SelectMatrixColumnsPage() { rowIdsSpinner.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { updateRowIdHeader(); updateControls(); if (lastPreview == null) { return; } if (lastPreview.equals(ID)) { updateRowIdPreview(); } else { updateColumnPreview(lastSelected); } } }); columnIdsSpinner.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { updateControls(); if (lastPreview == null) { return; } if (lastPreview.equals(ID)) { updateColumnIdPreview(); } else { updateColumnPreview(lastSelected); } } }); previewColumnIdsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateColumnIdPreview(); } }); previewRowIdsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateRowIdPreview(); } }); valueNameBox.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { updateControls(); } @Override public void removeUpdate(DocumentEvent e) { updateControls(); } @Override public void changedUpdate(DocumentEvent e) { updateControls(); } }); } private boolean correctValueName() { return !valueNameBox.getText().equals("") && !valueNameBox.getText().toLowerCase().equals("value") && !valueNameBox.getText().toLowerCase().equals("values"); } private void updateRowIdHeader() { previewLabel.setText("Row ids preview"); FileHeader newHeader = allheaders.get((int) rowIdsSpinner.getValue() - 1); FileHeader oldHeader = rowIdsHeader; if (oldHeader == null) return; //add old header where it belongs DefaultListModel restoreListModel; if (rowIdsHeaderWasIgnored) { restoreListModel = (DefaultListModel) ignoredHeaderList.getModel(); } else { restoreListModel = (DefaultListModel) valuesHeaderList.getModel(); } restoreListModel.add(0, oldHeader); //remove old header DefaultListModel removeListModel = (DefaultListModel) valuesHeaderList.getModel(); if (removeListModel.contains(newHeader)) { rowIdsHeaderWasIgnored = false; } else { removeListModel = (DefaultListModel) ignoredHeaderList.getModel(); rowIdsHeaderWasIgnored = true; } removeListModel.removeElement(newHeader); rowIdsHeader = newHeader; } private void initJList(JList<FileHeader> list, ListItemTransferHandler transferHandler, DefaultListModel<FileHeader> dataModel, boolean bold, boolean smallText) { list.setModel(dataModel); list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); list.setDropMode(DropMode.INSERT); list.setDragEnabled(true); list.setTransferHandler(transferHandler); list.setCellRenderer(new HeaderCellRenderer(bold, smallText)); // listener list.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { JList theList = (JList) e.getSource(); updateControls(); if (theList.getSelectedValue() == null) return; int i = theList.getLeadSelectionIndex(); updateColumnPreview((FileHeader) theList.getModel().getElementAt(i)); } } }); //Disable row Cut, Copy, Paste ActionMap map = list.getActionMap(); AbstractAction dummy = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { /* Dummy action */ } }; map.put(TransferHandler.getCutAction().getValue(Action.NAME), dummy); map.put(TransferHandler.getCopyAction().getValue(Action.NAME), dummy); map.put(TransferHandler.getPasteAction().getValue(Action.NAME), dummy); } private void updateRowIdPreview() { int rowPos = (int) rowIdsSpinner.getModel().getValue() - 1; int colPos = (int) columnIdsSpinner.getModel().getValue() - 1; StringBuilder html = new StringBuilder(""); html.append("<html>" + PreviewHTMLs.CSS + "<body><table>"); html.append("<tr><th>Row Ids</th><tr>"); for (List<FileField> line : preview) { FileField f = line.get(rowPos); if (f.getLine() > colPos) { html.append("<tr><td>" + f.getLabel() + "</td></tr>"); } } html.append("</table></body></html>"); previewPane.setText(html.toString()); previewPane.setCaretPosition(0); lastPreview = this.ID; } private void updateColumnIdPreview() { previewLabel.setText("Column ids preview"); int rowPos = (int) rowIdsSpinner.getModel().getValue() - 1; StringBuilder html = new StringBuilder(""); html.append("<html>" + PreviewHTMLs.CSS + "<body><table>"); html.append("<tr><th>Column Ids</th><tr>"); for (int i = 0; i < valuesHeaderList.getModel().getSize(); i++) { html.append("<tr><td>" + valuesHeaderList.getModel().getElementAt(i).getLabel() + "</td></tr>"); } html.append("</table></body></html>"); previewPane.setText(html.toString()); previewPane.setCaretPosition(0); lastPreview = this.ID; } private void updateColumnPreview(FileHeader selectedValue) { previewLabel.setText("Data column preview"); if (selectedValue == null) return; StringBuilder html = new StringBuilder(""); html.append("<html>" + PreviewHTMLs.CSS + "<body><table>"); html.append("<tr><th>" + selectedValue.getLabel() + "</th><tr>"); for (List<FileField> line : preview) { FileField f = line.get(selectedValue.getPos()); if (f.getLine() < (int) rowIdsSpinner.getModel().getValue()) continue; html.append("<tr><td>" + line.get(selectedValue.getPos()).getLabel() + "</td></tr>"); } html.append("</table></body></html>"); previewPane.setText(html.toString()); previewPane.setCaretPosition(0); lastPreview = this.COLUMN; } @Override public JComponent createControls() { return mainPanel; } @Override public void updateControls() { setMessage(MessageStatus.INFO, "Drag and Drop the file headers to choose which columns to use for the heatmap"); if ((int) rowIdsSpinner.getValue() < 1) { setMessage(MessageStatus.ERROR, "Heatmap row id must be a number bigger than 0"); setComplete(false); return; } else if ((int) columnIdsSpinner.getValue() < 1) { setMessage(MessageStatus.ERROR, "Heatmap column id must be a number bigger than 0"); setComplete(false); return; } else if (valuesHeaderList.getModel().getSize() == 0) { setMessage(MessageStatus.ERROR, "At least one column for heatmap values needed"); setComplete(false); return; } if (!correctValueName()) { setMessage(MessageStatus.ERROR, "Please specify a name describing the data values (e.g. expression)"); setComplete(false); return; } setComplete(true); } private void fillComponents() { if (allheaders == null) { this.preview = reader.getPreview(); this.allheaders = reader.getFileHeaders(); rowIdsSpinner.setValue(1); columnIdsSpinner.setValue(1); DefaultListModel<FileHeader> values = new DefaultListModel<FileHeader>(); DefaultListModel<FileHeader> ignored = new DefaultListModel<FileHeader>(); for (FileHeader header : allheaders) { if (header.getPos() != (int) rowIdsSpinner.getValue() - 1) { values.addElement(header); } else { rowIdsHeader = header; rowIdsHeaderWasIgnored = true; } } ListItemTransferHandler transferHandler = new ListItemTransferHandler(); initJList(valuesHeaderList, transferHandler, values, false, false); initJList(ignoredHeaderList, transferHandler, ignored, false, true); } } @Override public void finish() throws ReaderProfileValidationException { MatrixReaderProfile profile = (MatrixReaderProfile) reader.getReaderProfile(); profile.setRowIdsPosition((int) rowIdsSpinner.getValue() - 1); profile.setColumnIdsPosition((int) columnIdsSpinner.getValue() - 1); profile.setValueColumns(getPositions(valuesHeaderList)); profile.setIgnoredColumns(getPositions(ignoredHeaderList)); profile.setDataName(valueNameBox.getText()); reader.getReaderProfile().validate(allheaders); } private int[] getPositions(JList<FileHeader> headerList) { int[] indices = new int[headerList.getModel().getSize()]; for (int i = 0; i < indices.length; i++) { indices[i] = headerList.getModel().getElementAt(i).getPos(); } return indices; } @Override public FlatTextImporter getReader() { return reader; } public void setReader(FlatTextImporter reader) { this.reader = reader; fillComponents(); } class HeaderCellRenderer extends DefaultListCellRenderer { private boolean bold; private boolean smallFont; HeaderCellRenderer(boolean bold, boolean smallFont) { this.bold = bold; this.smallFont = smallFont; } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { FileHeader h = (FileHeader) value; String newValue = h.getLabel() + " (column " + (h.getPos() + 1) + ")"; Component c = super.getListCellRendererComponent(list, newValue, index, isSelected, cellHasFocus); if (bold) { c.setFont(c.getFont().deriveFont(Font.BOLD)); } if (smallFont) { c.setFont(c.getFont().deriveFont(11f)); } else { c.setFont(c.getFont().deriveFont(14f)); } return c; } } }