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

发布于 2024-07-09 20:18:04 字数 809 浏览 4 评论 0原文

我有一个 mx:Canvas 元素,其中包含多个 mx:Panel 元素。 我希望能够绘制一条连接两个这样的 mx:Panel 的线,以便当一个或两个 mx:Panel 被拖动时,该线继续连接两个 mx:Panel。 这似乎是一件微不足道的事情,但我一直无法弄清楚。

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

替代文本 http://img150.imageshack.us/img150/5656/ishot1eu3.jpg< /a>

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

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

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

最终的解决方案,如下所述,需要将移动事件从移动面板分派到其正在移动的画布上。 这迫使线条在整个运动过程中重新绘制。

感谢您的帮助!

I have a mx:Canvas element that contains several mx:Panel elements. I want to be able to draw a line connecting two such mx:Panel's in such a way that the line continues to connect the two mx:Panels when one or both get dragged around. It seems like something that should be trivial to do, but I haven't been able to figure it out.

In effect, this is the problem.

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

Since the updates only occur when the Panel reaches it's final position, as soon as you start dragging the "B" panel, you are left with a dangling line:

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

A possible solution, as suggested below, would be to override the updateDisplayList() method of the mx:Canvas component. Unfortunately, that only updates the drawing after the dragging, and not while in motion.
Listening to the "xChanged" and "yChanged" events in the Panel produces the same results as overriding the updateDisplayList().

The final solution, as pointed out below, requires dispatching the move events from the moving Panel to the Canvas on which it is moving. This forces the lines to get redrawn throughout the whole motion.

Thanks for all the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小红帽 2024-07-16 20:18:04

“我尝试过覆盖
updateDisplayList() 方法
mx:Canvas 组件但这似乎
仅在之后更新绘图
拖着。 我想要这条线
按照 mx:Panel 的状态进行操作
拖拽。”

您可以收听<面板中的 code>MoveEvent.MOVE 事件,并让处理程序调用重绘线条,然后让面板在通过监听 MouseEvent 拖动时分派这些事件。舞台中的 MOUSE_MOVE 事件并在处理程序中分派 MOVE 事件(将此处理程序附加到面板的 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));
}

"I've tried overriding the
updateDisplayList() method of the
mx:Canvas component but that seems to
only update the drawing after the
dragging. I would like for the line to
follow the mx:Panel as it is being
dragged."

You can listen to MoveEvent.MOVE events in the Panels and have the handler call for the redrawing of the lines, and then have the Panels dispatch these events while they are being dragged by listening for MouseEvent.MOUSE_MOVE events in the stage and dispatching the MOVE event in the handler (attach this handler to the stage in the Panel's MouseEvent.MOUSE_DOWN event handler, along with a handler for MouseEvent.MOUSE_UP (attached to the stage as well) -- then remove both of these event listeners from the stage in the MOUSE_UP handler.)

Here's an example (this would be in the Panel subclass:)

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));
}
掩于岁月 2024-07-16 20:18:04

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

flexwires is an open source project to implement this type of "connected lines" UI paradigm in Flex. It might just fit your needs.

百思不得你姐 2024-07-16 20:18:04

您需要重写 Canvas 上的 UIComponent 方法 updateDisplayList() 并在其中进行绘图。

假设您通常熟悉 AS3 中的线条绘制。

You'd want to override the UIComponent method updateDisplayList() on the Canvas and do your drawing in there.

This is assuming you are familiar with line drawing in AS3 in general.

心如狂蝶 2024-07-16 20:18:04

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

Can't you use bind functionality here? the end point of the line bound to the center of the circle?

娇纵 2024-07-16 20:18:04

刚接触 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);
    }

}

New to flash/flex and had a similar problem. I solved it by attaching an event listener to the Enter_Frame event. I am not sure if this is the most efficient solution since it redraws even if the objects have not moved but it worked for me:

    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);
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文