/* * org.openmicroscopy.shoola.agents.measurement.view.ObjectManager * *------------------------------------------------------------------------------ * Copyright (C) 2006-2007 University of Dundee. All rights reserved. * * * 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 2 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.measurement.view; //Java imports import java.awt.BorderLayout; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.Vector; import javax.swing.Icon; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreeSelectionModel; import org.apache.commons.collections.CollectionUtils; //Third-party libraries import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.table.ColumnFactory; import org.jdesktop.swingx.table.TableColumnExt; import org.jhotdraw.draw.Figure; //Application-internal dependencies import org.openmicroscopy.shoola.agents.measurement.IconManager; import org.openmicroscopy.shoola.agents.measurement.MeasurementAgent; import org.openmicroscopy.shoola.agents.measurement.util.TabPaneInterface; import org.openmicroscopy.shoola.agents.measurement.util.model.AnnotationDescription; import org.openmicroscopy.shoola.agents.measurement.util.roitable.ROINode; import org.openmicroscopy.shoola.agents.measurement.util.roitable.ROITableModel; import org.openmicroscopy.shoola.util.roi.figures.ROIFigure; import org.openmicroscopy.shoola.util.roi.model.ROI; import org.openmicroscopy.shoola.util.roi.model.ROIShape; import org.openmicroscopy.shoola.util.roi.model.annotation.AnnotationKeys; import org.openmicroscopy.shoola.util.roi.model.util.Coord3D; /** * UI Component managing a Region of Interest. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $Date: $) * </small> * @since OME3.0 */ class ObjectManager extends JPanel implements TabPaneInterface { /** * List of default column names. */ private static Vector<String> COLUMN_NAMES; static { COLUMN_NAMES = new Vector<String>(6); COLUMN_NAMES.add("ROI"); COLUMN_NAMES.add(AnnotationDescription.ROIID_STRING); COLUMN_NAMES.add(AnnotationDescription.ZSECTION_STRING); COLUMN_NAMES.add(AnnotationDescription.TIME_STRING); COLUMN_NAMES.add(AnnotationDescription.SHAPE_STRING); //columnNames.add(AnnotationDescription.annotationDescription.get( // AnnotationKeys.NAMESPACE)); //columnNames.add(AnnotationDescription.annotationDescription.get( // AnnotationKeys.KEYWORDS)); COLUMN_NAMES.add(AnnotationDescription.annotationDescription.get( AnnotationKeys.TEXT)); COLUMN_NAMES.add("Visible"); } /** * List of default column sizes. */ private static Map<String, Integer> COLUMN_WIDTHS; static{ COLUMN_WIDTHS = new HashMap<String, Integer>(); COLUMN_WIDTHS.put(COLUMN_NAMES.get(0), 80); COLUMN_WIDTHS.put(COLUMN_NAMES.get(1), 36); COLUMN_WIDTHS.put(COLUMN_NAMES.get(2), 36); COLUMN_WIDTHS.put(COLUMN_NAMES.get(3), 36); COLUMN_WIDTHS.put(COLUMN_NAMES.get(4), 36); //columnWidths.put(columnNames.get(5), 36); //columnWidths.put(columnNames.get(6), 96); COLUMN_WIDTHS.put(COLUMN_NAMES.get(5), 96); COLUMN_WIDTHS.put(COLUMN_NAMES.get(6), 36); } /** Index to identify tab */ private final static int INDEX = MeasurementViewerUI.MANAGER_INDEX; /** The name of the panel. */ private static final String NAME = "Manager"; /** The table hosting the ROI objects. */ private ROITable objectsTable; /** Reference to the Model. */ private MeasurementViewerModel model; /** Reference to the View. */ private MeasurementViewerUI view; /** Reference to the Model. */ private MeasurementViewerControl control; /** * The table selection listener attached to the table displaying the * objects. */ private TreeSelectionListener treeSelectionListener; /** Initializes the components composing the display. */ private void initComponents() { ROINode root = new ROINode("root"); objectsTable = new ROITable(new ROITableModel(root, COLUMN_NAMES), COLUMN_NAMES, this); objectsTable.setRootVisible(false); objectsTable.setColumnSelectionAllowed(true); objectsTable.setRowSelectionAllowed(true); treeSelectionListener = new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { TreeSelectionModel tsm = objectsTable.getTreeSelectionModel(); if (tsm.isSelectionEmpty()) return; int[] index = tsm.getSelectionRows(); if (index.length == 0) return; if (index.length == 1) { ROINode node = (ROINode) objectsTable.getNodeAtRow( objectsTable.getSelectedRow()); if (node == null) return; Object nodeValue = node.getUserObject(); view.clearInspector(); if (nodeValue instanceof ROIShape) { view.selectFigure(((ROIShape) nodeValue).getFigure()); } int col = objectsTable.getSelectedColumn(); int row = objectsTable.getSelectedRow(); if (row < 0 || col < 0) return; } else { ROIShape shape; for (int i = 0; i < index.length; i++) { shape = objectsTable.getROIShapeAtRow(index[i]); if (shape != null) { view.selectFigure(shape.getFigure()); requestFocus(); } } } } }; objectsTable.addTreeSelectionListener(treeSelectionListener); ColumnFactory columnFactory = new ColumnFactory() { public void configureColumnWidths(JXTable table, TableColumnExt columnExt) { columnExt.setPreferredWidth( COLUMN_WIDTHS.get(columnExt.getHeaderValue())); } }; objectsTable.setHorizontalScrollEnabled(true); objectsTable.setColumnControlVisible(true); objectsTable.setColumnFactory(columnFactory); } /** Builds and lays out the UI. */ private void buildGUI() { setLayout(new BorderLayout()); add(new JScrollPane(objectsTable), BorderLayout.CENTER); } /** * Creates a new instance. * * @param view Reference to the view. Mustn't be <code>null</code>. * @param controller Reference to the control. Mustn't be <code>null</code>. * @param model Reference to the Model. Mustn't be <code>null</code>. */ ObjectManager(MeasurementViewerUI view, MeasurementViewerControl control, MeasurementViewerModel model) { if (view == null) throw new IllegalArgumentException("No view."); if (model == null) throw new IllegalArgumentException("No model."); if (control == null) throw new IllegalArgumentException("No control."); this.view = view; this.model = model; this.control = control; initComponents(); buildGUI(); } /** * Displays the menu at the specified location if not already visible. * * @param x The x-coordinate of the mouse click. * @param y The y-coordinate of the mouse click. */ void showROIManagementMenu(int x, int y) { objectsTable.showROIManagementMenu(view.getDrawingView(), x, y); } /** Rebuilds Tree */ void rebuildTable() { TreeMap<Long, ROI> roiList = model.getROI(); Iterator<ROI> iterator = roiList.values().iterator(); ROI roi; TreeMap<Coord3D, ROIShape> shapeList; Iterator<ROIShape> shapeIterator; objectsTable.clear(); while(iterator.hasNext()) { roi = iterator.next(); shapeList = roi.getShapes(); shapeIterator = shapeList.values().iterator(); while (shapeIterator.hasNext()) objectsTable.addROIShape(shapeIterator.next()); } objectsTable.collapseAll(); } /** * Returns the name of the component. * * @return See above. */ String getComponentName() { return NAME; } /** * Returns the icon of the component. * * @return See above. */ Icon getComponentIcon() { IconManager icons = IconManager.getInstance(); return icons.getIcon(IconManager.MANAGER); } /** * Adds the collection of figures to the display. * * @param l The collection of objects to add. */ void addFigures(Collection l) { Iterator i=l.iterator(); ROI roi; Iterator<ROIShape> j; while (i.hasNext()) { roi = (ROI) i.next(); j = roi.getShapes().values().iterator(); while (j.hasNext()) objectsTable.addROIShape(j.next()); } } /** * Adds the collection of ROIShapes to the display. * * @param shapeList The collection of ROIShapes to add. */ void addROIShapes(List<ROIShape> shapeList) { objectsTable.addROIShapeList(shapeList); } /** * Selects the collection of figures. * * @param l The collection of objects to select. * @param clear Pass <code>true</code> to clear the selection * <code>false</code> otherwise. */ void setSelectedFigures(List<ROIShape> l, boolean clear) { Iterator<ROIShape> i = l.iterator(); TreeSelectionModel tsm = objectsTable.getTreeSelectionModel(); ROIFigure figure = null; ROIShape shape; if (clear) tsm.clearSelection(); objectsTable.removeTreeSelectionListener(treeSelectionListener); try { while (i.hasNext()) { shape = i.next(); figure = shape.getFigure(); objectsTable.selectROIShape(figure.getROIShape()); } objectsTable.repaint(); if (figure != null) objectsTable.scrollToROIShape(figure.getROIShape()); } catch (Exception e) { MeasurementAgent.getRegistry().getLogger().info(this, "Figure selection "+e); } objectsTable.addTreeSelectionListener(treeSelectionListener); } /** * Removes the passed figure from the table. * * @param figure The figure to remove. */ void removeFigure(ROIFigure figure) { if (figure == null) return; objectsTable.removeROIShape(figure.getROIShape()); objectsTable.repaint(); } /** * Removes the passed figures from the table. * * @param figures The figures to handle. */ void removeFigures(List<ROIFigure> figures) { if (figures == null || figures.size() == 0) return; Iterator<ROIFigure> i = figures.iterator(); while (i.hasNext()) { objectsTable.removeROIShape(i.next().getROIShape()); } objectsTable.repaint(); } /** * Deletes the ROI shapes in the list. * * @param shapeList see above. */ void deleteROIShapes(List<ROIShape> shapeList) { view.deleteROIShapes(shapeList); this.rebuildTable(); } /** Resets the component.*/ void reset() { model.getROIComponent().reset(); } /** * Duplicates the ROI shapes in the list and belonging to the ROI with * id. * @param id see above. * @param shapeList see above. */ void duplicateROI(long id, List<ROIShape> shapeList) { view.duplicateROI(id, shapeList); this.rebuildTable(); } /** * Calculates the statistics for the roi in the list. * * @param shapeList The collection of shapes. */ void calculateStats(List<ROIShape> shapeList) { view.calculateStats(shapeList); } /** * Merges the ROI shapes in the list and belonging to the ROI with * id in idList into a single new ROI. The ROI in the shape list should * all be on separate planes. * * @param idList see above. see above. * @param shapeList see above. */ void mergeROI(List<Long> idList, List<ROIShape> shapeList) { view.mergeROI(idList, shapeList); this.rebuildTable(); } /** * Split the ROI shapes in the list and belonging to the ROI with * id into a single new ROI. The ROI in the shape list should * all be on separate planes. * * @param id see above. see above. * @param shapeList see above. */ void splitROI(long id, List<ROIShape> shapeList) { view.splitROI(id, shapeList); this.rebuildTable(); } /** Repaints the table. */ void update() { objectsTable.refresh(); objectsTable.invalidate(); objectsTable.repaint(); } /** * Shows the roi assistant for the roi. * * @param roi see above. */ void propagateROI(ROI roi) { view.showROIAssistant(roi); } /** * Display message in status bar. * @param messageString see above. */ void showMessage(String messageString) { view.setStatus(messageString); } /** * Display Ready message in status bar. */ void showReadyMessage() { view.setReadyStatus(); } /** Invokes when new figures are selected. */ void onSelectedFigures() { objectsTable.onSelectedFigures(model.getSelectedFigures()); } /** * Returns the selected figures. * * @return See above. */ Collection<Figure> getSelectedFigures() { return model.getSelectedFigures(); } /** * Implemented as specified by the I/F {@link TabPaneInterface} * @see TabPaneInterface#getIndex() */ public int getIndex() { return INDEX; } /** Loads the tags.*/ void loadTags() { control.loadTags(); } /** * Returns a collection of all figures selected * If a ROI is selected, all the figures hosted will that ROI will be * returned. * @return See above. */ Collection<Figure> getSelectedFiguresFromTables() { List l = objectsTable.getSelectedObjects(); if (CollectionUtils.isEmpty(l)) return null; Iterator i = l.iterator(); Object o; ROI roi; ROIShape shape; List<Figure> list = new ArrayList<Figure>(); while (i.hasNext()) { o = i.next(); if (o instanceof ROI) { roi = (ROI) o; list.addAll(roi.getAllFigures()); } else if (o instanceof ROIShape) { shape = (ROIShape) o; list.add(shape.getFigure()); } } return list; } }