/* * #%L * gitools-ui-app * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * 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% */ package org.gitools.ui.core.pages.common; import com.alee.utils.SwingUtils; import org.gitools.api.ApplicationContext; import org.gitools.api.matrix.IMatrixLayer; import org.gitools.api.resource.ResourceReference; import org.gitools.heatmap.HeatmapDimension; import org.gitools.heatmap.header.HeatmapHeader; import org.gitools.heatmap.header.HeatmapTextLabelsHeader; import org.gitools.matrix.format.AnnotationMatrixFormat; import org.gitools.matrix.model.matrix.AnnotationMatrix; import org.gitools.persistence.locators.UrlResourceLocator; import org.gitools.ui.core.utils.DocumentChangeListener; import org.gitools.ui.core.utils.FileChooserUtils; import org.gitools.ui.core.utils.LogUtils; import org.gitools.ui.platform.IconUtils; import org.gitools.ui.platform.dialog.MessageStatus; import org.gitools.ui.platform.icons.IconNames; import org.gitools.ui.platform.settings.Settings; import org.gitools.ui.platform.wizard.AbstractWizardPage; import org.slf4j.LoggerFactory; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class AnnotationEditPage extends AbstractWizardPage { private final AnnotationMatrix annotationMatrix; private JPanel root; private JList annList; private JTextField annotationSearchField; private JScrollPane jScrollPane1; private JButton loadAnnotations; private JButton removeSelected; private JButton fromOtherHeatmapButton; private JTextField annTitleField; private JButton applyTitleChange; private JTable previewTable; private JTextField descriptionField; private JButton applyDescriptionButton; private JScrollPane previewScrollPane; private HeatmapDimension hdim; private List<AnnotationOption> annotation; private DefaultTableModel tableModel; public AnnotationEditPage(HeatmapDimension hdim) { this.hdim = hdim; annotationMatrix = hdim.getAnnotations(); setLogo(IconUtils.getImageIconResourceScaledByHeight(IconNames.annotation512, 96)); tableModel = new DefaultTableModel() { @Override public String getColumnName(int column) { if (column == 0) { return "Id"; } else if (column > 0 && column < this.getColumnCount()) { return ((AnnotationOption) annList.getSelectedValuesList().get(column - 1)).getKey(); } return super.getColumnName(column); } @Override public int getRowCount() { return annotationMatrix.getIdentifiers().size(); } @Override public int getColumnCount() { return annList.getSelectedValuesList().size() + 1; } @Override public Object getValueAt(int rowIndex, int columnIndex) { if (rowIndex < 0 || columnIndex < 0) { return null; } String id = annotationMatrix.getIdentifiers().getLabel(rowIndex); if (columnIndex == 0) { return id; } else { String key; try { key = ((AnnotationOption) annList.getSelectedValuesList().get(columnIndex - 1)).getKey(); } catch (IndexOutOfBoundsException e) { return null; } return annotationMatrix.getAnnotation(id, key); } } }; previewTable.setModel(tableModel); initComponents(); fromOtherHeatmapButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //todo: addFromOtherHeatmap(); } }); fromOtherHeatmapButton.setEnabled(false); fromOtherHeatmapButton.setVisible(false); annList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } annListSelectionChanged(); updateControls(); } }); setTitle("Annotations selection"); setComplete(true); } private void annListSelectionChanged() { tableModel.setColumnCount(annList.getSelectedValuesList().size() + 1); SwingUtils.invokeLater(new Runnable() { @Override public void run() { previewTable.updateUI(); AnnotationOption selectedValue = (AnnotationOption) annList.getSelectedValue(); if (selectedValue == null) { return; } annTitleField.setText(selectedValue.getKey()); descriptionField.setText(selectedValue.getDescription()); } }); } class FilterCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); AnnotationOption annOpt = (AnnotationOption) value; String needle = annotationSearchField.getText().toLowerCase(); boolean match; match = annotationSearchField.getText().isEmpty(); if (!match) { match = annOpt.getKey().toLowerCase().contains(needle) | annOpt.getDescription().toLowerCase().contains(needle); } if (match) {// <= put your logic here c.setFont(c.getFont().deriveFont(Font.ITALIC, 14.0f)); c.setForeground(Color.BLACK); } else { c.setFont(c.getFont().deriveFont(Font.ITALIC, 9.0f)); c.setForeground(Color.LIGHT_GRAY); } return c; } } @Override public void updateControls() { SwingUtils.invokeLater(new Runnable() { @Override public void run() { AnnotationOption ann = (AnnotationOption) annList.getSelectedValue(); if (ann != null && !annTitleField.getText().equals(ann.getKey()) && isNewKey() && annList.getSelectedIndices().length == 1) { annTitleField.setFont(annTitleField.getFont().deriveFont(Font.BOLD)); applyTitleChange.setEnabled(true); } else { annTitleField.setFont(annTitleField.getFont().deriveFont(Font.PLAIN)); applyTitleChange.setEnabled(false); } if (ann != null && !descriptionField.getText().equals(ann.getDescription()) && annList.getSelectedIndices().length == 1) { descriptionField.setFont(descriptionField.getFont().deriveFont(Font.BOLD)); applyDescriptionButton.setEnabled(true); } else { descriptionField.setFont(descriptionField.getFont().deriveFont(Font.PLAIN)); applyDescriptionButton.setEnabled(false); } } }); } private boolean isNewKey() { String newKey = annTitleField.getText(); int selectedIdx = annList.getSelectedIndex(); int elements = annList.getModel().getSize(); for (int i = 0; i < elements; i++) { if (i == selectedIdx) { continue; } AnnotationOption ao = (AnnotationOption) annList.getModel().getElementAt(i); if (newKey.toLowerCase().equals(ao.getKey().toLowerCase())) { return false; } } return true; } private void removeSelectedAnnotations() { String inUse = "id"; for (HeatmapHeader hh : hdim.getHeaders()) { inUse = inUse + ", " + hh.getAnnotationPattern(); } StringBuilder cannotRemove = new StringBuilder(); boolean stuffHasBeenRemoved = false; for (Object option : annList.getSelectedValuesList()) { String label = ((AnnotationOption) option).getKey(); if (!inUse.contains(label)) { hdim.getAnnotations().removeAnnotations(label); stuffHasBeenRemoved = true; } else { cannotRemove.append(label); cannotRemove.append(", "); } } if (stuffHasBeenRemoved) { initComponents(); } annList.setSelectedIndices(new int[0]); if (cannotRemove.length() > 0) { setMessage(MessageStatus.WARN, "<html>Could not remove some annotations because they are being used in a header: " + "<b>" + cannotRemove.toString() + "</b></html>"); } } private void updateComplete() { setComplete(annList.getSelectedIndices().length > 0); } public String[] getSelectedValues() { int[] indices = annList.getSelectedIndices(); String[] values = new String[indices.length]; for (int i = 0; i < indices.length; i++) { int index = indices[i]; if (index == 0) { values[i] = "id"; } else { values[i] = annotation.get(index - 1).getKey(); } } return values; } public void setHeatmapDimension(HeatmapDimension heatmapDimension) { this.hdim = heatmapDimension; updateControls(); } private void filterAnnotationsBox(KeyEvent evt) { annList.repaint(); } public HeatmapTextLabelsHeader.LabelSource getLabelSource() { if (annList.getSelectedIndex() == 0) { return HeatmapTextLabelsHeader.LabelSource.ID; } else { return HeatmapTextLabelsHeader.LabelSource.PATTERN; } } public String getAnnotationName() { if (annList.getSelectedIndex() > 0) { return annotation.get(annList.getSelectedIndex() - 1).getKey(); } else { return ""; } } private void initComponents() { jScrollPane1.setViewportView(annList); previewScrollPane.setViewportView(previewTable); loadAnnotations.setText("Load from file"); loadAnnotations.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { loadAnnotationsActionPerformed(evt); } }); annotationSearchField.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { annotationSearchFieldKeyReleased(evt); } }); removeSelected.setText("remove Selected"); removeSelected.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { removeSelectedAnnotations(); } }); DocumentChangeListener docListener = new DocumentChangeListener() { @Override protected void update(DocumentEvent e) { updateControls(); } }; annTitleField.getDocument().addDocumentListener(docListener); descriptionField.getDocument().addDocumentListener(docListener); applyTitleChange.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { changeAnnotationKey(); } }); applyDescriptionButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { changeDescription(); } }); if (hdim != null && hdim.getAnnotations() != null && !hdim.getAnnotations().getLabels().isEmpty()) { DefaultListModel<AnnotationOption> model = new DefaultListModel<>(); FilterCellRenderer cellRenderer = new FilterCellRenderer(); annotation = new ArrayList<>(); for (String key : hdim.getAnnotations().getLabels()) { if (key.toLowerCase().startsWith("hierarchical-cols") || key.toLowerCase().startsWith("hierarchical-rows")) { continue; } String description = hdim.getAnnotations().getAnnotationMetadata(AnnotationMatrix.METADATA_DESCRIPTION, key); annotation.add(new AnnotationOption(key, description)); } Collections.sort(annotation, new Comparator<AnnotationOption>() { @Override public int compare(AnnotationOption o1, AnnotationOption o2) { return o1.toString().toUpperCase().compareTo(o2.toString().toUpperCase()); } }); for (AnnotationOption annotationOption : annotation) { model.addElement(annotationOption); } annList.setModel(model); annList.setSelectedIndex(0); annList.setCellRenderer(cellRenderer); setMessage(MessageStatus.INFO, "View, Load and Remove annotations"); } } private void changeDescription() { int idx = annList.getSelectedIndex(); AnnotationOption anno = (AnnotationOption) annList.getSelectedValue(); annotationMatrix.setAnnotationMetadata(AnnotationMatrix.METADATA_DESCRIPTION, anno.getKey(), descriptionField.getText()); initComponents(); annList.setSelectedIndex(idx); } private void changeAnnotationKey() { AnnotationOption anno = (AnnotationOption) annList.getSelectedValue(); IMatrixLayer<String> oldLayer = annotationMatrix.getLayers().get(anno.getKey()); String newKey = annTitleField.getText(); for (String id : annotationMatrix.getIdentifiers()) { annotationMatrix.setAnnotation(id, newKey, annotationMatrix.get(oldLayer, id)); } initComponents(); } private void loadAnnotationsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadAnnotationsActionPerformed try { File file = FileChooserUtils.selectFile("Open annotationMatrix file", Settings.get().getLastAnnotationPath(), FileChooserUtils.MODE_OPEN).getFile(); if (file != null) { hdim.addAnnotations(new ResourceReference<>(new UrlResourceLocator(file), ApplicationContext.getPersistenceManager().getFormat(AnnotationMatrixFormat.EXTENSION, AnnotationMatrix.class)).get()); Settings.get().setLastAnnotationPath(file.getParent()); updateControls(); } } catch (Exception ex) { LogUtils.logException(ex, LoggerFactory.getLogger(getClass())); } } private void annotationSearchFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_annotationSearchFieldKeyReleased filterAnnotationsBox(evt); } public JPanel getPanel() { return root; } }