在Flex / Actionscript中连接线(同时拖动)

时间:2008-12-02 17:55:12

标签: flex actionscript-3 air flex3

我有一个mx:Canvas元素,它包含几个mx:Panel元素。我希望能够绘制一条连接两个这样的mx:Panel的线,使得当一个或两个被拖动时,线继续连接两个mx:面板。这似乎应该是微不足道的事情,但我无法弄明白。

实际上,这就是问题所在。

alt text http://img150.imageshack.us/img150/5656/ishot1eu3.jpg

由于更新仅在Panel达到最终位置时发生,因此只要您开始拖动“B”面板,就会留下悬空线:

alt text http://img212.imageshack.us/img212/4296/ishot2qi6.jpg

如下所示,可能的解决方案是覆盖mx:Canvas组件的updateDisplayList()方法。不幸的是,这只是在拖动后更新绘图,而不是在运动时。 在Panel中监听“xChanged”和“yChanged”事件会产生与覆盖updateDisplayList()相同的结果。

如下所述,最终解决方案需要将移动事件从移动面板调度到它正在移动的画布上。这会强制线在整个运动过程中重新绘制。

感谢您的帮助!

5 个答案:

答案 0 :(得分:4)

  

“我试过压倒了   updateDisplayList()方法   mx:Canvas组件,但似乎   只有更新后的图纸   拖动。我想换线   按照mx:Panel进行操作   拖“。

您可以在Panel中收听MoveEvent.MOVE事件并让处理程序调用重新绘制行,然后让Panel在通过监听MouseEvent.MOUSE_MOVE事件进行拖动时调度这些事件在阶段并在处理程序中调度MOVE事件(将此处理程序附加到Panel的MouseEvent.MOUSE_DOWN事件处理程序中的阶段,以及MouseEvent.MOUSE_UP的处理程序(也附加到阶段) ) - 然后从MOUSE_UP处理程序中的阶段中删除这两个事件侦听器。)

这是一个例子(这将在Panel子类中:)

private function attachListeners():void
{
    this.addEventListener(MouseEvent.MOUSE_DOWN, selfMouseDownHandler, false,0,true);
    this.addEventListener(MoveEvent.MOVE, selfMoveHandler, false,0,true);
}

private function selfMoveHandler(event:MoveEvent):void
{
    redrawConnectedLinks();
}

private function selfMouseDownHandler(event:MouseEvent):void
{
    stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler, false,0,true);
    stage.addEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false,0,true);
}

private function stageMouseUpHandler(event:MouseEvent):void
{
    stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler, false);
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false);
}

private function stageMouseMoveHandler(event:MouseEvent):void
{
    dispatchEvent(new MoveEvent(MoveEvent.MOVE));
}

答案 1 :(得分:1)

flexwires是一个开源项目,用于在Flex中实现此类“连接线”UI范例。它可能符合您的需求。

答案 2 :(得分:0)

您想要覆盖Canvas上的UIComponent方法updateDisplayList()并在那里进行绘制。

这是假设您熟悉AS3中的线条图。

答案 3 :(得分:0)

你不能在这里使用绑定功能吗?线的终点是否与圆心相连?

答案 4 :(得分:0)

flash / flex新手并遇到类似问题。我通过将一个事件监听器附加到Enter_Frame事件来解决它。我不确定这是否是最有效的解决方案,因为它重新绘制,即使对象没有移动但它对我有效:

    import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;

public class Association extends Sprite
{
    private var t1:DisplayObject;
    private var t2:DisplayObject;
    //Connects two objects
    public function Association(t1:DisplayObject, t2:DisplayObject)
    {
        this.t1=t1;
        this.t2=t2;
        this.addEventListener(Event.ENTER_FRAME, redraw)
        super();
    }

    public function redraw(event:Event):void
    {
        graphics.clear();
        graphics.lineStyle(2,0x000000);
        graphics.moveTo(t1.x,t1.y);
        graphics.lineTo(t2.x,t2.y);
    }

}