【问题标题】:Extending PLayer in Piccolo2d在 Piccolo2d 中扩展播放器
【发布时间】:2014-07-21 19:45:39
【问题描述】:

我有下一个问题。在我的项目中,当从层中添加或删除节点时,我需要将消息委托给第三方库。为了实现这一点,我通过以下方式扩展了 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) 一切正常。

那么,谁能解释一下是什么问题?

【问题讨论】:

    标签: java piccolo


    【解决方案1】:

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

    在这个简短的演示中,当您注释掉 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");
        }
    });
    

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

    【讨论】:

    • 另外,在这个answer 中有一个PUtil.createBasicScenegraph() 的源代码,它说明了如何创建根和层之间的链接。
    猜你喜欢
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多