/** * Import a whole track from the {@link Model} and make it visible * * @param trackIndex the index of the track to show in TrackScheme */ private void importTrack(int trackIndex) { model.beginUpdate(); graph.getModel().beginUpdate(); try { // Flag original track as visible model.setTrackVisibility(trackIndex, true); // Find adequate column int targetColumn = getUnlaidSpotColumn(); // Create cells for track Set<Spot> trackSpots = model.getTrackModel().trackSpots(trackIndex); for (Spot trackSpot : trackSpots) { int frame = trackSpot.getFeature(Spot.FRAME).intValue(); int column = Math.max(targetColumn, getNextFreeColumn(frame)); insertSpotInGraph(trackSpot, column); rowLengths.put(frame, column); } Set<DefaultWeightedEdge> trackEdges = model.getTrackModel().trackEdges(trackIndex); for (DefaultWeightedEdge trackEdge : trackEdges) { graph.addJGraphTEdge(trackEdge); } } finally { model.endUpdate(); graph.getModel().endUpdate(); } }
/** * Used to catch spot creation events that occurred elsewhere, for instance by manual editing in * the {@link AbstractTrackMateModelView}. * * <p>We have to deal with the graph modification ourselves here, because the {@link Model} model * holds a non-listenable JGraphT instance. A modification made to the model would not be * reflected on the graph here. */ @Override public void modelChanged(final ModelChangeEvent event) { // Only catch model changes if (event.getEventID() != ModelChangeEvent.MODEL_MODIFIED) return; graph.getModel().beginUpdate(); try { ArrayList<mxICell> cellsToRemove = new ArrayList<mxICell>(); final int targetColumn = getUnlaidSpotColumn(); // Deal with spots if (!event.getSpots().isEmpty()) { Collection<mxCell> spotsWithStyleToUpdate = new HashSet<mxCell>(); for (Spot spot : event.getSpots()) { if (event.getSpotFlag(spot) == ModelChangeEvent.FLAG_SPOT_ADDED) { int frame = spot.getFeature(Spot.FRAME).intValue(); // Put in the graph int column = Math.max(targetColumn, getNextFreeColumn(frame)); mxICell newCell = insertSpotInGraph(spot, column); // move in right+1 free column rowLengths.put(frame, column); spotsWithStyleToUpdate.add((mxCell) newCell); } else if (event.getSpotFlag(spot) == ModelChangeEvent.FLAG_SPOT_MODIFIED) { // Change the look of the cell mxICell cell = updateCellOf(spot); spotsWithStyleToUpdate.add((mxCell) cell); } else if (event.getSpotFlag(spot) == ModelChangeEvent.FLAG_SPOT_REMOVED) { mxICell cell = graph.getCellFor(spot); cellsToRemove.add(cell); } } graph.removeCells(cellsToRemove.toArray(), true); stylist.updateVertexStyle(spotsWithStyleToUpdate); } } finally { graph.getModel().endUpdate(); } // Deal with edges if (!event.getEdges().isEmpty()) { graph.getModel().beginUpdate(); try { if (event.getEdges().size() > 0) { Map<Integer, Set<mxCell>> edgesToUpdate = new HashMap<Integer, Set<mxCell>>(); for (DefaultWeightedEdge edge : event.getEdges()) { if (event.getEdgeFlag(edge) == ModelChangeEvent.FLAG_EDGE_ADDED) { mxCell edgeCell = graph.getCellFor(edge); if (null == edgeCell) { // Make sure target & source cells exist Spot source = model.getTrackModel().getEdgeSource(edge); mxCell sourceCell = graph.getCellFor(source); if (sourceCell == null) { int frame = source.getFeature(Spot.FRAME).intValue(); // Put in the graph int targetColumn = getUnlaidSpotColumn(); int column = Math.max(targetColumn, getNextFreeColumn(frame)); insertSpotInGraph(source, column); // move in right+1 free column rowLengths.put(frame, column); } Spot target = model.getTrackModel().getEdgeTarget(edge); mxCell targetCell = graph.getCellFor(target); if (targetCell == null) { int frame = target.getFeature(Spot.FRAME).intValue(); // Put in the graph int targetColumn = getUnlaidSpotColumn(); int column = Math.max(targetColumn, getNextFreeColumn(frame)); insertSpotInGraph(target, column); // move in right+1 free column rowLengths.put(frame, column); } // And finally create the edge cell edgeCell = graph.addJGraphTEdge(edge); } graph.getModel().add(graph.getDefaultParent(), edgeCell, 0); // Add it to the map of cells to recolor Integer trackID = model.getTrackModel().trackIDOf(edge); Set<mxCell> edgeSet = edgesToUpdate.get(trackID); if (edgesToUpdate.get(trackID) == null) { edgeSet = new HashSet<mxCell>(); edgesToUpdate.put(trackID, edgeSet); } edgeSet.add(edgeCell); } else if (event.getEdgeFlag(edge) == ModelChangeEvent.FLAG_EDGE_MODIFIED) { // Add it to the map of cells to recolor Integer trackID = model.getTrackModel().trackIDOf(edge); Set<mxCell> edgeSet = edgesToUpdate.get(trackID); if (edgesToUpdate.get(trackID) == null) { edgeSet = new HashSet<mxCell>(); edgesToUpdate.put(trackID, edgeSet); } edgeSet.add(graph.getCellFor(edge)); } else if (event.getEdgeFlag(edge) == ModelChangeEvent.FLAG_EDGE_REMOVED) { mxCell cell = graph.getCellFor(edge); graph.removeCells(new Object[] {cell}); } } stylist.execute(edgesToUpdate); SwingUtilities.invokeLater( new Runnable() { public void run() { gui.graphComponent.refresh(); gui.graphComponent.repaint(); } }); } } finally { graph.getModel().endUpdate(); } } }