Search in sources :

Example 11 with Node

use of ini.trakem2.display.Node in project TrakEM2 by trakem2.

the class TMLHandler method getProjectData.

/**
 * returns 4 objects packed in an array:
 *	 <pre>
 *	 [0] = root TemplateThing
 *	 [1] = root ProjectThing (contains Project instance)
 *	 [2] = root LayerThing (contains the top-level LayerSet)
 *	 [3] = expanded states of all ProjectThing objects
 *	 </pre>
 * <p>
 * Also, triggers the reconstruction of links and assignment of Displayable objects to their layer.
 * </p>
 */
public Object[] getProjectData(final boolean open_displays) {
    if (null == project)
        return null;
    this.open_displays = open_displays;
    // Links exist between Displayable objects.
    for (final Displayable d : ht_displayables.values()) {
        String olinks = ht_links.get(d);
        // not linked
        if (null == olinks)
            continue;
        String[] links = olinks.split(",");
        Long lid = null;
        for (int i = 0; i < links.length; i++) {
            try {
                lid = new Long(links[i]);
            } catch (NumberFormatException nfe) {
                Utils.log2("Ignoring incorrectly formated link '" + links[i] + "' for ob " + d);
                continue;
            }
            Displayable partner = ht_displayables.get(lid);
            if (null != partner)
                d.link(partner, false);
            else
                Utils.log("TMLHandler: can't find partner with id=" + links[i] + " for Displayable with id=" + d.getId());
        }
    }
    // 1.2 - Reconstruct linked properties
    for (final Map.Entry<Displayable, Map<Long, Map<String, String>>> lpe : all_linked_props.entrySet()) {
        final Displayable origin = lpe.getKey();
        for (final Map.Entry<Long, Map<String, String>> e : lpe.getValue().entrySet()) {
            final Displayable target = ht_displayables.get(e.getKey());
            if (null == target) {
                Utils.log("Setting linked properties for origin " + origin.getId() + ":\n\t* Could not find target displayable #" + e.getKey());
                continue;
            }
            origin.setLinkedProperties(target, e.getValue());
        }
    }
    // 2 - Add Displayable objects to ProjectThing that can contain them
    for (final Map.Entry<Long, ProjectThing> entry : ht_oid_pt.entrySet()) {
        ProjectThing pt = entry.getValue();
        Object od = ht_displayables.remove(entry.getKey());
        // Utils.log("==== processing: Displayable [" + od + "]  vs. ProjectThing [" + pt + "]");
        if (null != od) {
            pt.setObject(od);
        } else {
            Utils.log("#### Failed to find a Displayable for ProjectThing " + pt + " #####");
        }
    }
    // 3 - Assign a layer pointer to ZDisplayable objects
    for (final ZDisplayable zd : ht_zdispl.values()) {
        // zd.setLayer((Layer)zd.getLayerSet().getLayers().get(0));
        zd.setLayer(zd.getLayerSet().getLayer(0));
    }
    // 4 - Assign layers to Treeline nodes
    for (final Layer la : al_layers) {
        final List<Node<?>> list = node_layer_table.remove(la.getId());
        if (null == list)
            continue;
        for (final Node<?> nd : list) nd.setLayer(la);
    }
    if (!node_layer_table.isEmpty()) {
        Utils.log("ERROR: node_layer_table is not empty!");
    }
    // 5 - Assign root nodes to Treelines, now that all nodes have a layer
    for (final Map.Entry<Tree<?>, Node<?>> e : tree_root_nodes.entrySet()) {
        if (null == e.getValue()) {
            // Utils.log2("Ignoring, applies to new Treeline format only.");
            continue;
        }
        // Can't compile with <?>
        // will generate node caches of each Treeline
        e.getKey().setRoot((Node) e.getValue());
    }
    tree_root_nodes.clear();
    // Assign colors to nodes
    for (final Map.Entry<Color, Collection<Node<?>>> e : node_colors.entrySet()) {
        for (final Node<?> nd : e.getValue()) {
            nd.setColor(e.getKey());
        }
    }
    node_colors.clear();
    // 6 - Run legacy operations
    for (final Runnable r : legacy) {
        r.run();
    }
    try {
        // Create a table with all layer ids vs layer instances:
        final HashMap<Long, Layer> ht_lids = new HashMap<Long, Layer>();
        for (final Layer layer : al_layers) {
            ht_lids.put(new Long(layer.getId()), layer);
        }
        // Spawn threads to recreate buckets, starting from the subset of displays to open
        int n = Runtime.getRuntime().availableProcessors();
        switch(n) {
            case 1:
                break;
            case 2:
            case 3:
            case 4:
                n--;
                break;
            default:
                n -= 2;
                break;
        }
        final ExecutorService exec = Utils.newFixedThreadPool(n, "TMLHandler-recreateBuckets");
        final Set<Long> dlids = new HashSet<Long>();
        final LayerSet layer_set = (LayerSet) root_lt.getObject();
        final List<Future<?>> fus = new ArrayList<Future<?>>();
        final List<Future<?>> fus2 = new ArrayList<Future<?>>();
        for (final HashMap<String, String> ht_attributes : al_displays) {
            String ob = ht_attributes.get("layer_id");
            if (null == ob)
                continue;
            final Long lid = new Long(ob);
            dlids.add(lid);
            final Layer la = ht_lids.get(lid);
            if (null == la) {
                ht_lids.remove(lid);
                continue;
            }
            // to open later:
            new Display(project, Long.parseLong(ht_attributes.get("id")), la, ht_attributes);
            fus.add(exec.submit(new Runnable() {

                public void run() {
                    la.recreateBuckets();
                }
            }));
        }
        fus.add(exec.submit(new Runnable() {

            public void run() {
                // only for ZDisplayable
                layer_set.recreateBuckets(false);
            }
        }));
        // Ensure launching:
        if (dlids.isEmpty() && layer_set.size() > 0) {
            dlids.add(layer_set.getLayer(0).getId());
        }
        final List<Layer> layers = layer_set.getLayers();
        for (final Long lid : new HashSet<Long>(dlids)) {
            fus.add(exec.submit(new Runnable() {

                public void run() {
                    int start = layer_set.indexOf(layer_set.getLayer(lid.longValue()));
                    int next = start + 1;
                    int prev = start - 1;
                    while (next < layer_set.size() || prev > -1) {
                        if (prev > -1) {
                            final Layer lprev = layers.get(prev);
                            synchronized (dlids) {
                                if (dlids.add(lprev.getId())) {
                                    // returns true if not there already
                                    fus2.add(exec.submit(new Runnable() {

                                        public void run() {
                                            lprev.recreateBuckets();
                                        }
                                    }));
                                }
                            }
                            prev--;
                        }
                        if (next < layers.size()) {
                            final Layer lnext = layers.get(next);
                            synchronized (dlids) {
                                if (dlids.add(lnext.getId())) {
                                    // returns true if not there already
                                    fus2.add(exec.submit(new Runnable() {

                                        public void run() {
                                            lnext.recreateBuckets();
                                        }
                                    }));
                                }
                            }
                            next++;
                        }
                    }
                    Utils.log2("done recreateBuckets chunk");
                }
            }));
        }
        Utils.wait(fus);
        exec.submit(new Runnable() {

            public void run() {
                Utils.log2("waiting for TMLHandler fus...");
                Utils.wait(fus2);
                Utils.log2("done waiting TMLHandler fus.");
                exec.shutdown();
            }
        });
    } catch (Throwable t) {
        IJError.print(t);
    }
    return new Object[] { root_tt, root_pt, root_lt, ht_pt_expanded };
}
Also used : HashMap(java.util.HashMap) Node(ini.trakem2.display.Node) ArrayList(java.util.ArrayList) AreaTree(ini.trakem2.display.AreaTree) Tree(ini.trakem2.display.Tree) ProjectThing(ini.trakem2.tree.ProjectThing) HashSet(java.util.HashSet) Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) LayerSet(ini.trakem2.display.LayerSet) Color(java.awt.Color) Layer(ini.trakem2.display.Layer) ZDisplayable(ini.trakem2.display.ZDisplayable) ExecutorService(java.util.concurrent.ExecutorService) Collection(java.util.Collection) Future(java.util.concurrent.Future) Map(java.util.Map) HashMap(java.util.HashMap) Display(ini.trakem2.display.Display)

Example 12 with Node

use of ini.trakem2.display.Node in project TrakEM2 by trakem2.

the class DefaultTreeTransferHandler method canPerformAction.

public boolean canPerformAction(DNDTree target, DefaultMutableTreeNode dragged_node, int action, Point location) {
    // prevent drags from non-tree components
    if (null == dragged_node)
        return false;
    // Can't drop onto a TemplateTree
    if (target instanceof TemplateTree) {
        return false;
    }
    // Can't drag a node that contains a Project!
    if (dragged_node.getUserObject() instanceof ProjectThing && ((ProjectThing) dragged_node.getUserObject()).getObject() instanceof Project) {
        return false;
    }
    // Can't drag basic object nodes from a template tree RECONSIDERED, I like it even if it looks inconsistent (but types are types!)
    /*
		if (dragged_node.getUserObject() instanceof TemplateThing && project.isBasicType(((Thing)dragged_node.getUserObject()).getType())) {
			return false;
		}
		*/
    // else, the target has to be not null
    TreePath pathTarget = target.getPathForLocation(location.x, location.y);
    if (pathTarget == null) {
        target.setSelectionPath(null);
        return false;
    }
    /* // debug
		if (action == DnDConstants.ACTION_COPY) {
			Utils.log("can drop: Action copy");
		} else if (action == DnDConstants.ACTION_MOVE) {
			Utils.log("can drop: Action move");
		} else {
			Utils.log("can drop: Unexpected action: " + action);
		}
		*/
    target.setSelectionPath(pathTarget);
    DefaultMutableTreeNode parent_node = (DefaultMutableTreeNode) pathTarget.getLastPathComponent();
    // can be a Thing or an Attribute
    Object parent_ob = parent_node.getUserObject();
    Thing child_thing = (Thing) dragged_node.getUserObject();
    if (DnDConstants.ACTION_MOVE == action || DnDConstants.ACTION_COPY == action) {
        if (parent_ob instanceof ProjectThing) {
            ProjectThing parent_thing = (ProjectThing) parent_ob;
            // check if it's allowed to give to this parent such a child:
            if (!parent_thing.uniquePathExists(child_thing.getType()) && !parent_thing.canHaveAsChild(child_thing)) {
                // Utils.log("Not possible.");
                return false;
            }
            // - the leaf that is going to be dropped into itself or any of its descendants.
            if (parent_node == dragged_node.getParent() || dragged_node.isNodeDescendant(parent_node)) {
                // Utils.log("preventing dragging onto itself or any of the self children.");
                return false;
            } else {
                return true;
            }
        }
    }
    // default:
    return false;
}
Also used : Project(ini.trakem2.Project) TreePath(javax.swing.tree.TreePath) DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode)

Example 13 with Node

use of ini.trakem2.display.Node in project TrakEM2 by trakem2.

the class ProjectThing method createChild.

public ProjectThing createChild(String type) {
    // create the Displayable
    TemplateThing tt = template.getChildTemplate(type);
    if (null == tt) {
        Utils.log2("Can't create a child of type " + type);
        return null;
    }
    Object ob = project.makeObject(tt);
    Layer layer = null;
    if (ob instanceof Displayable) {
        // which layer to add it to? Get it from the front Display
        layer = Display.getFrontLayer(this.project);
        if (null == layer) {
            Utils.showMessage("Open a display first!");
            ((DBObject) ob).removeFromDatabase();
            return null;
        }
    }
    // wrap it in a new ProjectThing
    ProjectThing pt = null;
    try {
        pt = new ProjectThing(tt, project, ob);
    } catch (Exception e) {
        IJError.print(e);
        return null;
    }
    // add it here as child
    addChild(pt);
    // finally, add it to the layer if appropriate
    if (null != layer) {
        if (ob instanceof ZDisplayable) {
            layer.getParent().add((ZDisplayable) ob);
        } else {
            layer.add((Displayable) ob);
        }
    }
    // finally, return it to be added to the ProjectTree as a new node
    return pt;
}
Also used : ZDisplayable(ini.trakem2.display.ZDisplayable) ZDisplayable(ini.trakem2.display.ZDisplayable) Displayable(ini.trakem2.display.Displayable) DBObject(ini.trakem2.persistence.DBObject) Layer(ini.trakem2.display.Layer) DBObject(ini.trakem2.persistence.DBObject)

Example 14 with Node

use of ini.trakem2.display.Node in project TrakEM2 by trakem2.

the class ProjectTree method mousePressed.

public void mousePressed(final MouseEvent me) {
    super.dispatcher.execSwing(new Runnable() {

        public void run() {
            if (!me.getSource().equals(ProjectTree.this) || !project.isInputEnabled()) {
                return;
            }
            final int x = me.getX();
            final int y = me.getY();
            // find the node and set it selected
            final TreePath path = getPathForLocation(x, y);
            if (null == path) {
                return;
            }
            ProjectTree.this.setSelectionPath(path);
            selected_node = (DefaultMutableTreeNode) path.getLastPathComponent();
            if (2 == me.getClickCount() && !me.isPopupTrigger() && MouseEvent.BUTTON1 == me.getButton()) {
                // show in the front Display
                if (null == selected_node)
                    return;
                Object obt = selected_node.getUserObject();
                if (!(obt instanceof ProjectThing))
                    return;
                ProjectThing thing = (ProjectThing) obt;
                thing.setVisible(true);
                Object obd = thing.getObject();
                if (obd instanceof Displayable) {
                    // additionaly, get the front Display (or make a new one if none) and show in it the layer in which the Displayable object is contained.
                    Displayable displ = (Displayable) obd;
                    Display.showCentered(displ.getLayer(), displ, true, me.isShiftDown());
                }
                return;
            } else if (me.isPopupTrigger() || (ij.IJ.isMacOSX() && me.isControlDown()) || MouseEvent.BUTTON2 == me.getButton() || 0 != (me.getModifiers() & Event.META_MASK)) {
                // the last block is from ij.gui.ImageCanvas, aparently to make the right-click work on windows?
                JPopupMenu popup = getPopupMenu(selected_node);
                if (null == popup)
                    return;
                popup.show(ProjectTree.this, x, y);
                return;
            }
        }
    });
}
Also used : Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) TreePath(javax.swing.tree.TreePath) DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) DBObject(ini.trakem2.persistence.DBObject) JPopupMenu(javax.swing.JPopupMenu)

Example 15 with Node

use of ini.trakem2.display.Node in project TrakEM2 by trakem2.

the class ProjectTree method tryAddNewConnector.

/**
 * If the parent node of {@code active} can accept a Connector or has a direct child
 * node that can accept a {@link Connector}, add a new {@link Connector} and return it.
 *
 * @param d The {@link Displayable} that serves as reference, to decide which node to add the new {@link Connector}.
 * @param selectNode Whether to select the new node containing the {@link Connector} in the ProjectTree.
 *
 * @return The newly created {@link Connector}.
 */
public Connector tryAddNewConnector(final Displayable d, final boolean selectNode) {
    ProjectThing pt = project.findProjectThing(d);
    ProjectThing parent = (ProjectThing) pt.getParent();
    TemplateThing connectorType = project.getTemplateThing("connector");
    boolean add = false;
    if (parent.canHaveAsChild(connectorType)) {
        // Add as a sibling of pt
        add = true;
    } else {
        // Inspect if any of the sibling nodes can have it as child
        for (final ProjectThing child : parent.getChildren()) {
            if (child.canHaveAsChild(connectorType)) {
                parent = child;
                add = true;
                break;
            }
        }
    }
    Connector c = null;
    DefaultMutableTreeNode node = null;
    if (add) {
        // reuse same String instance
        c = new Connector(project, connectorType.getType());
        node = addChild(parent, connectorType.getType(), c);
    }
    if (null != node) {
        d.getLayerSet().add(c);
        if (selectNode)
            setSelectionPath(new TreePath(node.getPath()));
        return c;
    }
    Utils.logAll("Could not add a new Connector related to " + d);
    return null;
}
Also used : Connector(ini.trakem2.display.Connector) DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) TreePath(javax.swing.tree.TreePath)

Aggregations

DBObject (ini.trakem2.persistence.DBObject)16 ProjectThing (ini.trakem2.tree.ProjectThing)12 HashMap (java.util.HashMap)12 HashSet (java.util.HashSet)12 TreePath (javax.swing.tree.TreePath)12 DefaultMutableTreeNode (javax.swing.tree.DefaultMutableTreeNode)11 Displayable (ini.trakem2.display.Displayable)9 ZDisplayable (ini.trakem2.display.ZDisplayable)9 ArrayList (java.util.ArrayList)9 GenericDialog (ij.gui.GenericDialog)8 Layer (ini.trakem2.display.Layer)7 LayerThing (ini.trakem2.tree.LayerThing)6 Point (java.awt.Point)6 Map (java.util.Map)6 JMenuItem (javax.swing.JMenuItem)6 JPopupMenu (javax.swing.JPopupMenu)6 Project (ini.trakem2.Project)5 TemplateThing (ini.trakem2.tree.TemplateThing)5 Color (java.awt.Color)5 AreaTree (ini.trakem2.display.AreaTree)4