简体   繁体   中英

Reload a prefuse Tree stucture?

I need to visualize an xml file with prefuse,but due to its size I must load only parts of the file at a time and represent them as a tree strucure in prefuse.I managed to load and visualize the first tree,consisting of all the xml elemts up to predetermined depth,but if I want to see elements deeper in the XML file I need to create a new prefuse tree with the new root being the first element read at the new depth and continuing to read elements until the maximum depth and so on.I am having trouble with loading and visualizing these subtrees in prefuse.Currently I make a call such as currentTree.clear(); and try to use currentTree in the reading process but I get errors like these:

prefuse.Display$InputEventCapturer fireItemClicked
WARNING: Exception thrown by Control: java.lang.ArrayIndexOutOfBoundsException: -1
java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.get(ArrayList.java:324)
    at prefuse.data.Table.getColumn(Table.java:457)
    at prefuse.data.Table.setString(Table.java:1427)
    at prefuse.data.tuple.TableTuple.setString(TableTuple.java:455)
    at loader.TreeLoader.downLevel(TreeLoader.java:322)
    at visualizations.PrefuseTreeVisual$2.itemClicked(PrefuseTreeVisual.java:302)
    at prefuse.Display$InputEventCapturer.fireItemClicked(Display.java:1738)
    at prefuse.Display$InputEventCapturer.mouseClicked(Display.java:1590)
    at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6292)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
    at java.awt.Component.processEvent(Component.java:6054)
    at java.awt.Container.processEvent(Container.java:2041)
    at java.awt.Component.dispatchEventImpl(Component.java:4652)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4482)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4247)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
    at java.awt.Container.dispatchEventImpl(Container.java:2085)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4482)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:644)
    at java.awt.EventQueue.access$000(EventQueue.java:85)
    at java.awt.EventQueue$1.run(EventQueue.java:603)
    at java.awt.EventQueue$1.run(EventQueue.java:601)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    at java.awt.EventQueue$2.run(EventQueue.java:617)
    at java.awt.EventQueue$2.run(EventQueue.java:615)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:614)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

08.05.2012 11:38:47 prefuse.action.ActionList run
WARNING: Row index out of bounds: -1
java.lang.IllegalArgumentException: Row index out of bounds: -1
    at prefuse.data.column.DoubleColumn.getDouble(DoubleColumn.java:112)
    at prefuse.data.Table.getDouble(Table.java:1255)
    at prefuse.visual.VisualTable.getX(VisualTable.java:407)
    at prefuse.visual.tuple.TableVisualItem.getX(TableVisualItem.java:270)
    at visualizations.PrefuseTreeVisual$AutoPanAction.run(PrefuseTreeVisual.java:433)
    at prefuse.action.ActionList.run(ActionList.java:79)
    at prefuse.action.Action.run(Action.java:122)
    at prefuse.activity.Activity.runActivity(Activity.java:165)
    at prefuse.activity.ActivityManager.run(ActivityManager.java:365)

I think the tree structure has some listeners attached to it and when I call clear() on the tree those listeners aren't cleared. How do I clear those listeners? Or is there an easier way to do what I am trying to do? Thanks in advance !

The code making all the trouble is in itemClicked function

package visualizations;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import loader.TreeLoader;
import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.Action;
import prefuse.action.ActionList;
import prefuse.action.ItemAction;
import prefuse.action.RepaintAction;
import prefuse.action.animate.ColorAnimator;
import prefuse.action.animate.LocationAnimator;
import prefuse.action.animate.QualityControlAnimator;
import prefuse.action.animate.VisibilityAnimator;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.FontAction;
import prefuse.action.filter.FisheyeTreeFilter;
import prefuse.action.layout.CollapsedSubtreeLayout;
import prefuse.action.layout.graph.NodeLinkTreeLayout;
import prefuse.activity.SlowInSlowOutPacer;
import prefuse.controls.*;
import prefuse.data.Node;
import prefuse.data.Tree;
import prefuse.data.event.TupleSetListener;
import prefuse.data.io.DataIOException;
import prefuse.data.search.PrefixSearchTupleSet;
import prefuse.data.tuple.TupleSet;
import prefuse.render.AbstractShapeRenderer;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.EdgeRenderer;
import prefuse.render.LabelRenderer;
import prefuse.util.ColorLib;
import prefuse.util.FontLib;
import prefuse.util.ui.JFastLabel;
import prefuse.util.ui.JSearchPanel;
import prefuse.visual.NodeItem;
import prefuse.visual.VisualItem;
import prefuse.visual.expression.InGroupPredicate;
import prefuse.visual.sort.TreeDepthItemSorter;

public class PrefuseTreeVisual extends Display {

    //prefuse specific variables
    private static final String tree = "tree";
    private static final String treeNodes = "tree.nodes";
    private static final String treeEdges = "tree.edges";
    private LabelRenderer m_nodeRenderer;
    private EdgeRenderer m_edgeRenderer;
    private String m_label = "name";
    private int m_orientation = Constants.ORIENT_LEFT_RIGHT;
    private TreeLoader xmlLoader;
    private Tree prefuseTree;
    private JPanel panel;
    private static Visualization vis;

    public PrefuseTreeVisual() {
        vis=new Visualization();
    }

    public void init(Tree t, String label) {
        m_label = label;

        this.setVisualization(vis);
        vis.add(tree, t);

        m_nodeRenderer = new LabelRenderer(m_label);
        m_nodeRenderer.setRenderType(AbstractShapeRenderer.RENDER_TYPE_FILL);
        m_nodeRenderer.setHorizontalAlignment(Constants.LEFT);
        m_nodeRenderer.setRoundedCorner(8, 8);
        m_edgeRenderer = new EdgeRenderer(Constants.EDGE_TYPE_CURVE);

        DefaultRendererFactory rf = new DefaultRendererFactory(m_nodeRenderer);
        rf.add(new InGroupPredicate(treeEdges), m_edgeRenderer);
        vis.setRendererFactory(rf);

        // colors
        ItemAction nodeColor = new NodeColorAction(treeNodes);
        ItemAction textColor = new ColorAction(treeNodes,
                VisualItem.TEXTCOLOR, ColorLib.rgb(0, 0, 0));
        vis.putAction("textColor", textColor);

        ItemAction edgeColor = new ColorAction(treeEdges,
                VisualItem.STROKECOLOR, ColorLib.rgb(200, 200, 200));

        // quick repaint
        ActionList repaint = new ActionList();
        repaint.add(nodeColor);
        repaint.add(new RepaintAction());
        vis.putAction("repaint", repaint);

        // full paint
        ActionList fullPaint = new ActionList();
        fullPaint.add(nodeColor);
        vis.putAction("fullPaint", fullPaint);

        // animate paint change
        ActionList animatePaint = new ActionList(400);
        animatePaint.add(new ColorAnimator(treeNodes));
        animatePaint.add(new RepaintAction());
        vis.putAction("animatePaint", animatePaint);

        // create the tree layout action
        NodeLinkTreeLayout treeLayout = new NodeLinkTreeLayout(tree,
                m_orientation, 50, 0, 8);
        treeLayout.setLayoutAnchor(new Point2D.Double(25, 300));
        vis.putAction("treeLayout", treeLayout);

        CollapsedSubtreeLayout subLayout =
                new CollapsedSubtreeLayout(tree, m_orientation);
        vis.putAction("subLayout", subLayout);

        AutoPanAction autoPan = new AutoPanAction();

        // create the filtering and layout
        ActionList filter = new ActionList();
        filter.add(new FisheyeTreeFilter(tree, 4));
        filter.add(new FontAction(treeNodes, FontLib.getFont("Tahoma", 16)));
        filter.add(treeLayout);
        filter.add(subLayout);
        filter.add(textColor);
        filter.add(nodeColor);
        filter.add(edgeColor);
        vis.putAction("filter", filter);

        // animated transition
        ActionList animate = new ActionList(1000);
        animate.setPacingFunction(new SlowInSlowOutPacer());
        animate.add(autoPan);
        animate.add(new QualityControlAnimator());
        animate.add(new VisibilityAnimator(tree));
        animate.add(new LocationAnimator(treeNodes));
        animate.add(new ColorAnimator(treeNodes));
        animate.add(new RepaintAction());
        vis.putAction("animate", animate);
        vis.alwaysRunAfter("filter", "animate");

        // create animator for orientation changes
        ActionList orient = new ActionList(2000);
        orient.setPacingFunction(new SlowInSlowOutPacer());
        orient.add(autoPan);
        orient.add(new QualityControlAnimator());
        orient.add(new LocationAnimator(treeNodes));
        orient.add(new RepaintAction());
        vis.putAction("orient", orient);

        // ------------------------------------------------

        // initialize the display
        setSize(700, 600);
        setItemSorter(new TreeDepthItemSorter());
        addControlListener(new ZoomToFitControl());
        addControlListener(new ZoomControl());
        addControlListener(new WheelZoomControl());
        addControlListener(new PanControl());
        addControlListener(new FocusControl(1, "filter"));

        registerKeyboardAction(
                new OrientAction(Constants.ORIENT_LEFT_RIGHT),
                "left-to-right", KeyStroke.getKeyStroke("ctrl 1"), WHEN_FOCUSED);
        registerKeyboardAction(
                new OrientAction(Constants.ORIENT_TOP_BOTTOM),
                "top-to-bottom", KeyStroke.getKeyStroke("ctrl 2"), WHEN_FOCUSED);
        registerKeyboardAction(
                new OrientAction(Constants.ORIENT_RIGHT_LEFT),
                "right-to-left", KeyStroke.getKeyStroke("ctrl 3"), WHEN_FOCUSED);
        registerKeyboardAction(
                new OrientAction(Constants.ORIENT_BOTTOM_TOP),
                "bottom-to-top", KeyStroke.getKeyStroke("ctrl 4"), WHEN_FOCUSED);

        // ------------------------------------------------

        // filter graph and perform layout
        setOrientation(m_orientation);
        vis.run("filter");

        TupleSet search = new PrefixSearchTupleSet();
        vis.addFocusGroup(Visualization.SEARCH_ITEMS, search);
        search.addTupleSetListener(new TupleSetListener() {

            @Override
            public void tupleSetChanged(TupleSet t, prefuse.data.Tuple[] add, prefuse.data.Tuple[] rem) {
                vis.cancel("animatePaint");
                vis.run("fullPaint");
                vis.run("animatePaint");
            }
        });
    }

    public JComponent getVisual(String filepath, String label) {
        //set colors for background and foreground
        Color BACKGROUND = Color.WHITE;
        Color FOREGROUND = Color.BLACK;

        //load a partial tree
        xmlLoader = new TreeLoader();
        xmlLoader.setMaxDepth(1);
        prefuseTree = null;
        try {
            prefuseTree = (Tree) xmlLoader.readGraph(filepath);
        } catch (DataIOException ex) {
            Logger.getLogger(PrefuseTreeVisual.class.getName()).log(Level.SEVERE, null, ex);
        }

        final PrefuseTreeVisual tview = new PrefuseTreeVisual();
        tview.init(prefuseTree, label);
        tview.setBackground(BACKGROUND);
        tview.setForeground(FOREGROUND);

        //create a search panel
        JSearchPanel search = new JSearchPanel(tview.getVisualization(), treeNodes, Visualization.SEARCH_ITEMS, m_label, true, true);
        search.setShowResultCount(true);
        search.setBorder(BorderFactory.createEmptyBorder(5, 5, 4, 0));
        search.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 11));
        search.setBackground(BACKGROUND);
        search.setForeground(FOREGROUND);

        final JFastLabel title = new JFastLabel("Title");
        title.setPreferredSize(new Dimension(350, 20));
        title.setVerticalAlignment(SwingConstants.BOTTOM);
        title.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
        title.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 16));
        title.setBackground(BACKGROUND);
        title.setForeground(FOREGROUND);

        tview.addControlListener(new ControlAdapter() {

            @Override
            public void itemEntered(VisualItem item, MouseEvent e) {
                if (item.canGetString(m_label)) {
                    title.setText(item.getString(m_label));
                }
                if (item instanceof NodeItem) {
                    Display d = (Display)e.getSource();
                    ToolTipManager.sharedInstance().setInitialDelay(0);
                    String text = new String();
                    Node nodeData = (Node) item.getSourceTuple();
                    text+="<html>Type:" + nodeData.getString("type");
                    if (nodeData.getString("type").equals("level")) {
                        text+=("<br>Name: " + nodeData.getString("name"));
                        text+=("<br>Depth: " + nodeData.getString("depthInXMLTree"));
                        text+=("<br>Back to: " + nodeData.getString("backto"));
                        text+=("<br>Timestamp: " + nodeData.getString("timestamp")+"</html>");
                    } else if (nodeData.getString("type").equals("branch")) {
                        text+=("<br>Index: " + nodeData.getString("index"));
                        text+=("<br>Value: " + nodeData.getString("value"));
                        text+=("<br>Filtered values: " + nodeData.getString("value"));
                        text+=("<br>Timestamp: " + nodeData.getString("timestamp"));
                        text+=("<br>Has subtree: " + nodeData.getBoolean("hasSubtree")+"</html>");
                    }
                    if (nodeData.getString("type").equals("variable")) {
                        text+=("<br>Name: " + nodeData.getString("name"));
                        text+=("<br>Value: " + nodeData.getString("value"));
                        text+=("<br>Filtered values: " + nodeData.getString("filteredvalues"));
                        text+=("<br>Timestamp: " + nodeData.getString("timestamp")+"</html>");
                    } else if (nodeData.getString("type").equals("status")) {
                        text+=("<br>Result: " + nodeData.getString("result"));
                        text+=("<br>Timestamp: " + nodeData.getString("timestamp")+"</html>");
                    }
                    d.setToolTipText(text);
                }
            }

            @Override
            public void itemExited(VisualItem item, MouseEvent e) {
                title.setText(null);
                Display d = (Display)e.getSource();
                d.setToolTipText(null);
            }

            @Override
            public void itemClicked(VisualItem item, MouseEvent e) {
                if(item instanceof NodeItem)
                {
                    Node nodeData = (Node)item.getSourceTuple();
                    if(nodeData.getString("type").equals("level"))
                    {
                        if(prefuseTree.getRoot().getString("name").equals(nodeData.getString("name")))
                        {
                            //System.out.println("up level");
                            prefuseTree.removeChild(nodeData);
                           // xmlLoader.upLevel();

                        }
                        else
                        {
                          //  System.out.println("down level");

                            prefuseTree.removeChild(nodeData);
                            //xmlLoader.downLevel(nodeData);

                        }
                    }else if(nodeData.getString("type").equals("branch"))
                    {

                    }else if(nodeData.getString("type").equals("variable"))
                    {

                    }else if(nodeData.getString("type").equals("status"))
                    {

                    }
                }
            }

        });

        Box box = new Box(BoxLayout.X_AXIS);
        box.add(Box.createHorizontalStrut(10));
        box.add(title);
        box.add(Box.createHorizontalGlue());
        box.add(search);
        box.add(Box.createHorizontalStrut(3));
        box.setBackground(BACKGROUND);


        panel = new JPanel(new BorderLayout());
        panel.setBackground(BACKGROUND);
        panel.setForeground(FOREGROUND);
        panel.add(tview, BorderLayout.CENTER);
        panel.add(box, BorderLayout.SOUTH);
        return panel;
    }

    public void setOrientation(int orientation) {
        NodeLinkTreeLayout rtl = (NodeLinkTreeLayout) vis.getAction("treeLayout");
        CollapsedSubtreeLayout stl = (CollapsedSubtreeLayout) vis.getAction("subLayout");
        switch (orientation) {
            case Constants.ORIENT_LEFT_RIGHT:
                m_nodeRenderer.setHorizontalAlignment(Constants.LEFT);
                m_edgeRenderer.setHorizontalAlignment1(Constants.RIGHT);
                m_edgeRenderer.setHorizontalAlignment2(Constants.LEFT);
                m_edgeRenderer.setVerticalAlignment1(Constants.CENTER);
                m_edgeRenderer.setVerticalAlignment2(Constants.CENTER);
                break;
            case Constants.ORIENT_RIGHT_LEFT:
                m_nodeRenderer.setHorizontalAlignment(Constants.RIGHT);
                m_edgeRenderer.setHorizontalAlignment1(Constants.LEFT);
                m_edgeRenderer.setHorizontalAlignment2(Constants.RIGHT);
                m_edgeRenderer.setVerticalAlignment1(Constants.CENTER);
                m_edgeRenderer.setVerticalAlignment2(Constants.CENTER);
                break;
            case Constants.ORIENT_TOP_BOTTOM:
                m_nodeRenderer.setHorizontalAlignment(Constants.CENTER);
                m_edgeRenderer.setHorizontalAlignment1(Constants.CENTER);
                m_edgeRenderer.setHorizontalAlignment2(Constants.CENTER);
                m_edgeRenderer.setVerticalAlignment1(Constants.BOTTOM);
                m_edgeRenderer.setVerticalAlignment2(Constants.TOP);
                break;
            case Constants.ORIENT_BOTTOM_TOP:
                m_nodeRenderer.setHorizontalAlignment(Constants.CENTER);
                m_edgeRenderer.setHorizontalAlignment1(Constants.CENTER);
                m_edgeRenderer.setHorizontalAlignment2(Constants.CENTER);
                m_edgeRenderer.setVerticalAlignment1(Constants.TOP);
                m_edgeRenderer.setVerticalAlignment2(Constants.BOTTOM);
                break;
            default:
                throw new IllegalArgumentException(
                        "Unrecognized orientation value: " + orientation);
        }
        m_orientation = orientation;
        rtl.setOrientation(orientation);
        stl.setOrientation(orientation);
    }

    public int getOrientation() {
        return m_orientation;
    }

    public class OrientAction extends AbstractAction {

        private int orientation;

        public OrientAction(int orientation) {
            this.orientation = orientation;
        }

        @Override
        public void actionPerformed(ActionEvent evt) {
            setOrientation(orientation);
            getVisualization().cancel("orient");
            getVisualization().run("treeLayout");
            getVisualization().run("orient");
        }
    }

    public class AutoPanAction extends Action {

        private Point2D m_start = new Point2D.Double();
        private Point2D m_end = new Point2D.Double();
        private Point2D m_cur = new Point2D.Double();
        private int m_bias = 150;

        @Override
        public void run(double frac) {
            TupleSet ts = vis.getFocusGroup(Visualization.FOCUS_ITEMS);
            if (ts.getTupleCount() == 0) {
                return;
            }

            if (frac == 0.0) {
                int xbias = 0, ybias = 0;
                switch (m_orientation) {
                    case Constants.ORIENT_LEFT_RIGHT:
                        xbias = m_bias;
                        break;
                    case Constants.ORIENT_RIGHT_LEFT:
                        xbias = -m_bias;
                        break;
                    case Constants.ORIENT_TOP_BOTTOM:
                        ybias = m_bias;
                        break;
                    case Constants.ORIENT_BOTTOM_TOP:
                        ybias = -m_bias;
                        break;
                }

                VisualItem vi = (VisualItem) ts.tuples().next();
                m_cur.setLocation(getWidth() / 2, getHeight() / 2);
                getAbsoluteCoordinate(m_cur, m_start);
                m_end.setLocation(vi.getX() + xbias, vi.getY() + ybias);
            } else {
                m_cur.setLocation(m_start.getX() + frac * (m_end.getX() - m_start.getX()),
                        m_start.getY() + frac * (m_end.getY() - m_start.getY()));
                panToAbs(m_cur);
            }
        }
    }

    public static class NodeColorAction extends ColorAction {

        public NodeColorAction(String group) {
            super(group, VisualItem.FILLCOLOR);
        }

        @Override
        public int getColor(VisualItem item) {
            if (vis.isInGroup(item, Visualization.SEARCH_ITEMS)) {
                return ColorLib.rgb(255, 190, 190);
            } else if (vis.isInGroup(item, Visualization.FOCUS_ITEMS)) {
                return ColorLib.rgb(198, 229, 229);
            } else if (item.getDOI() > -1) {
                return ColorLib.rgb(164, 193, 193);
            } else {
                return ColorLib.rgba(255, 255, 255, 0);
            }
        }
    } // end of inner class TreeMapColorAction
}

您可以使用TreeWillExpandListener在其中放置创建节点子代的代码。

public void treeWillExpand(TreeExpansionEvent event)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM