在Piccolo2d中扩展PLayer

时间:2014-07-21 19:45:39

标签: java piccolo

我有下一个问题。在我的项目中,我需要在添加或从层中删除节点时将消息委托给第三方库。为了达到这个目的,我已经通过下一个方式扩展了PLayer:

public class DelegateLayer extends PLayer {
    private Delegate delegate = null;
    private boolean delegationNeeded = false;
    public DelegateLayer() {
        super();
    }
    @Override
    public void removeChildren(final Collection children) {
        for (Object child : children) {
            removeChild((PNode)child);
        }
    }
    @Override
    public void addChildren(final Collection children) {
        for (Object child : children) {
            addChild((PNode) child);
        }
    }

    @Override
    public void addChild(final PNode child) {
        if (delegationNeeded) {
            Preconditions.checkNotNull(delegate, "DelegateLayer: Delegate is not initialized");
            delegate.delegateNodeAdded((CloudNode)child);
        }
        super.addChild(child);
    }

    @Override
    public PNode removeChild(final PNode child) {
        if (delegationNeeded) {
            Preconditions.checkNotNull(delegate, "DelegateLayer: Delegate is not initialized");
            delegate.delegateNodeRemoved((CloudNode)child);
        }
        return super.removeChild(child);
    }

    public void setDelegationNeeded(boolean needed) {
        this.delegationNeeded = needed;
    }

    public void setDelegate(ClusterUpdateDelegate delegate) {
        this.delegate = delegate;
    }
}


我还将此节点图层添加到画布的相机中:

DelegateLayer nodeLayer = new DelegateLayer();
camera.addLayer(0, nodeLayer);

然而,在我将节点放置到图层并应用转换(在点上居中节点)后,没有任何反应。但是当我与PLayer交流时,我使用camera.getLayer(0)一切正常。

那么,有人可以解释一下是什么问题吗?

1 个答案:

答案 0 :(得分:1)

您可能错过了将新创建的图层添加到PRoot的调用。以下是Piccolo2D Patterns中描述的运行时结构的快照:

enter image description here

在这个简短的演示中,当您注释掉canvas.getCamera().getRoot().addChild(layer);时,动画停止工作:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import edu.umd.cs.piccolo.PCanvas;
import edu.umd.cs.piccolo.PLayer;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolo.util.PBounds;

public class Test {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {   
            public void run() {   
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationByPlatform(true);

                final PCanvas canvas = new PCanvas() {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(600, 400);
                    }
                };

                PLayer layer = new PLayer() {
                    @Override
                    public void addChild(final PNode child) {
                        System.out.println("notify: addChild");
                        super.addChild(child);
                    }
                };

                canvas.getCamera().addLayer(0, layer);
                canvas.getCamera().getRoot().addChild(layer);

                final PPath node = PPath.createRectangle(0, 0, 100, 100);
                node.setPaint(Color.RED);
                canvas.getLayer().addChild(node);

                canvas.addInputEventListener(new PBasicInputEventHandler() {
                    @Override
                    public void mouseClicked(PInputEvent event) {
                        Point2D p = event.getCamera().localToView(
                                event.getCanvasPosition());
                        PBounds bounds = node.getBounds();
                        final double dx = p.getX() - bounds.getCenterX();
                        final double dy = p.getY() - bounds.getCenterY();
                        node.animateToBounds(node.getBounds().x + dx, bounds.y
                                + dy, bounds.width, bounds.height, 300);
                    }
                });

                frame.add(canvas);            
                frame.pack();
                frame.setVisible(true);
            }
        });
    }    
}

另外,作为替代方案,您可以在不添加自定义图层的情况下监听PNode.PROPERTY_CHILDREN属性:

canvas.getLayer().addPropertyChangeListener(PNode.PROPERTY_CHILDREN, new PropertyChangeListener() {
    @Override
    public void propertyChange(PropertyChangeEvent e) {
        System.out.println("notify");
    }
});

虽然,在这种方法中,您没有关于添加/删除哪个孩子的信息。