重新加载prefuse Tree结构?

时间:2012-05-08 08:44:11

标签: java xml swing listeners prefuse

我需要使用prefuse可视化xml文件,但由于它的大小,我必须一次只加载文件的一部分并将它们表示为prefuse中的树结构。我设法加载并可视化第一个树,包括所有xml elemts到达预定深度,但如果我想在XML文件中看到更深层的元素,我需要创建一个新的prefuse树,新的root是在新深度读取的第一个元素,并继续读取元素,直到最大深度等等。我在加载和在预熔中可视化这些子树时遇到问题。目前我进行了一个调用,例如currentTree.clear();并尝试在阅读过程中使用currentTree,但我得到这样的错误:

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)

我认为树结构附加了一些监听器,当我在树上调用clear()时,那些监听器不会被清除。我如何清除那些听众?或者有更简单的方法来做我想做的事情?提前谢谢!

造成所有麻烦的代码在itemClicked函数

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
}

1 个答案:

答案 0 :(得分:1)

您可以使用TreeWillExpandListener将节点子代的创建代码放在那里。

public void treeWillExpand(TreeExpansionEvent event)