package cz.cuni.lf1.lge.ThunderSTORM.results; import cz.cuni.lf1.lge.ThunderSTORM.UI.RenderingOverlay; import cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.Molecule; import cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.MoleculeDescriptor; import ij.IJ; import ij.ImagePlus; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Vector; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTable; import javax.swing.SwingWorker; final class TableRowsPopUpMenu implements ActionListener { private final IJResultsTable rt; private final ResultsTableWindow tableWindow; private final GenericTableModel tableModel; private final JTable jtable; private final JMenuItem highlightMoleculeMenuItem; private final JMenuItem deleteMoleculeMenuItem; private final JMenuItem mergedMoleculesMenuItem; public TableRowsPopUpMenu(MouseEvent evt, ResultsTableWindow table) { tableWindow = table; tableModel = table.getModel(); jtable = table.getView(); rt = IJResultsTable.getResultsTable(); // highlightMoleculeMenuItem = new JMenuItem("highlight selected molecules in overlay"); deleteMoleculeMenuItem = new JMenuItem("filter out selected molecules"); mergedMoleculesMenuItem = new JMenuItem("show list of merged molecules"); // highlightMoleculeMenuItem.addActionListener(this); deleteMoleculeMenuItem.addActionListener(this); mergedMoleculesMenuItem.addActionListener(this); // JPopupMenu popup = new JPopupMenu(); if(rt.getAnalyzedImage() != null) { popup.add(highlightMoleculeMenuItem); } popup.add(deleteMoleculeMenuItem); if(jtable.getSelectedRowCount() == 1) { int rowIndex = jtable.convertRowIndexToModel(jtable.getSelectedRow()); if(tableModel.findColumn(MoleculeDescriptor.LABEL_DETECTIONS) != GenericTableModel.COLUMN_NOT_FOUND) { if(tableModel.getValueAt(rowIndex, MoleculeDescriptor.LABEL_DETECTIONS) > 1) { popup.add(mergedMoleculesMenuItem); } } } popup.show(evt.getComponent(), evt.getX(), evt.getY()); } @Override public void actionPerformed(ActionEvent evt) { if(evt.getSource() == highlightMoleculeMenuItem) { new SwingWorker() { @Override protected Object doInBackground() throws Exception { try { highlightMolecules(); } catch(Exception e) { IJ.handleException(e); } return null; } }.execute(); } else if(evt.getSource() == deleteMoleculeMenuItem) { filterMolecules(); } else if(evt.getSource() == mergedMoleculesMenuItem) { showMergedMolecules(); } } private void highlightMolecules() { ImagePlus imp = rt.getAnalyzedImage(); if(imp != null) { IJ.showStatus("Building new overlay..."); imp.setOverlay(null); // int[] rows = jtable.getSelectedRows(); HashSet<Integer> rowIndices = new HashSet<Integer>(); for(int r = 0; r < rows.length; r++) { rowIndices.add(jtable.convertRowIndexToModel(rows[r])); } List<Molecule> selectedMolecules = new ArrayList<Molecule>(); List<Molecule> notSelectedMolecules = new ArrayList<Molecule>(); for(int r = 0, rm = rt.getRowCount(); r < rm; r++) { Molecule mol = rt.getRow(r); if(rowIndices.contains(r)) { selectedMolecules.add(mol); if(!mol.isSingleMolecule()) { selectedMolecules.addAll(mol.getDetections()); } } else { notSelectedMolecules.add(mol); if(!mol.isSingleMolecule()) { notSelectedMolecules.addAll(mol.getDetections()); } } } RenderingOverlay.showPointsInImage(selectedMolecules.toArray(new Molecule[0]), imp, null, Color.GREEN, RenderingOverlay.MARKER_CIRCLE); RenderingOverlay.showPointsInImage(notSelectedMolecules.toArray(new Molecule[0]), imp, null, Color.RED, RenderingOverlay.MARKER_CROSS); // IJ.showProgress(1.0); IJ.showStatus(""); } } private void filterMolecules() { int[] rows = jtable.getSelectedRows(); Vector<Integer> rowIds = new Vector<Integer>(); for(int r = 0; r < rows.length; r++) { int rowIndex = jtable.convertRowIndexToModel(rows[r]); rowIds.add(tableModel.getValueAt(rowIndex, MoleculeDescriptor.LABEL_ID).intValue()); } Collections.sort(rowIds); int start, end; StringBuilder sb = new StringBuilder(); for(int r = 0, rm = rowIds.size(); r < rm; r++) { if(r > 0) { sb.append("&"); } start = rowIds.get(r); if((r + 1) >= rm) { sb.append("(id!=").append(start).append(")"); } else { end = rowIds.get(r + 1); if((end - start) > 1) { sb.append("(id!=").append(start).append(")"); } else { sb.append("(id<").append(start).append("|"); while(((r + 1) < rm) && ((end - start) <= 1)) { start = rowIds.get(r); end = rowIds.get(r + 1); r++; } if((end - start) > 1) { sb.append("id>").append(start).append(")"); } else { sb.append("id>").append(end).append(")"); } } } } // String formula = sb.toString(); ResultsFilter filter = tableWindow.getFilter(); filter.setFilterFormula(formula); filter.run(); } private void showMergedMolecules() { int row = jtable.getSelectedRow(); int rowIndex = jtable.convertRowIndexToModel(row); Molecule mol = tableModel.getRow(rowIndex); List<Molecule> detections = mol.getDetections(); Collections.sort(detections); new MergedMoleculesPopUp(jtable, row, 0, detections); } }