使用addElement的Flex4不能正确显示元素

时间:2010-08-19 14:17:10

标签: flex flash actionscript

我正在使用新的Flex4 Spark,但我遇到了一个可怕的问题。让我先解释一下这种情况。我有一个容器mx:Canvas,其中我addElement()有一个类型实例DocumentWindow。根据文档的类型,文档窗口类应该是视图的持有者。 DocumentWindow类扩展了TitleWindow。我还有一个mx:Canvas内置buttonBar的任务栏,以便窗口可以切换。所以我用两个词来获得Windows持有者和任务栏。

现在出现了一件奇怪的事情:当我放置DocumentWindow类型为“doc”(加载由swftools制作的swf)时,窗口会出现在Windows持有者中,并作为任务栏上的任务。但是,如果我首先打开其他内容 - DocumentWindow,其类型为音频或视频,导致DocumentWindow实例化内部的不同视图,则窗口中不显示任务按钮taskBar。我在其上添加了trace(),它显示numElements正在增加,taskBar ButtonBar.dataProvider.length增加,所以事情就在那里 - 只是在我打开DocumentWindow之前它们一直不可见用'doc'类型?!我甚至试图让DocumentWindow不加载内部视图,因为我认为唯一的区别是视图......但是即使是'doc'类型DocumentWindow也未显示。一条线索可能是,在添加“doc”视图之前,永远不会调用creationComplete。什么想法可能是错的?

以下是我从Windows持有人处获得的跟踪(来自Windows持有人numElements的{​​{1}}和来自Canvas的{​​{1}}:

1 windows, 1 tasks
    win[0] = (0, 0) - [550, 400], visible=true, alpha=1
1 windows, 1 tasks
    win[0] = (0, 0) - [550, 400], visible=true, alpha=1
1 windows, 1 tasks
    win[0] = (0, 0) - [550, 400], visible=true, alpha=1
1 windows, 1 tasks
    win[0] = (0, 0) - [550, 400], visible=true, alpha=1
1 windows, 1 tasks
    win[0] = (0, 0) - [550, 400], visible=true, alpha=1

PS:我ButtonBar.dataProvider.length也是Windows持有人的大小 - 没关系,它足够大了:))

这是主要的容器代码:

taskBar

以下是trace()类代码:



<s:Group
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:components="some.package.components.*"

    initialize="init()"
    creationComplete="main()">

    <fx:Script>
    <![CDATA[

        public function openDocument(di:DocumentInfo, id:String = null):TaskInfo {
            var w:DocumentWindow = new DocumentWindow();
            var t:TaskInfo = new TaskInfo(di, w, id);
            w.title = di.label;

            var docInfo:DocumentInfo = mServer.getDocumentInfo(di.type, di.label);
            w.init(docInfo, t);

            windows.addWindow(w);
            taskBar.addTask(t);

            return t;
        }

    ]]>
    </fx:Script>



    <mx:HBox id="bottomButtons" horizontalGap="0"
             left="0" bottom="0">
        <mx:Button id="userListButton" click="toggleUserList()"
                   width="40" height="40"/>
        <mx:Canvas id="handButtons"
            horizontalScrollPolicy="off" verticalScrollPolicy="off"
            width="40" height="40">
            <mx:Button id="raiseHandButton" click="toggleRaiseHand()"
                       visible="false" width="40" height="40"/>
            <mx:Button id="sitDownButton" click="doSitDown()"
                       visible="false" width="40" height="40"/>
        </mx:Canvas>
    </mx:HBox>

    <mx:HDividedBox id="vdivider" left="0" top="0" right="0" bottom="40">
        <components:WindowsView id="windows"/>
        <components:RightPanel id="rightPanel"/>
    </mx:HDividedBox>

    <components:TaskBar id="taskBar"
                        left="{bottomButtons.width}" bottom="0" right="0" height="40"/>

</s:Group>

WindowsView代码:



<?xml version="1.0" encoding="utf-8"?>
<s:Group
        xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx"

        click="showStuff()"
        width="100%" height="100%">

    <fx:Script>
        <![CDATA[
            import some.package.EClassView;

            import mx.events.FlexEvent;

            private function showStuff():void {
                trace(numChildren + ' windows, ' + EClassView.instance.taskBar.taskButtons.dataProvider.length + ' tasks');
                var w:DocumentWindow;
                for(var i:int = 0; i < numElements; ++i) {
                    w = getElementAt(i) as DocumentWindow;
                    if(w == null) continue;
                    trace("\twin[" + i + "] = (" + w.x + ", " + w.y + ") - [" + w.width + ", " + w.height + "], visible=" + w.visible + ", alpha=" + w.alpha);
                }
            }

            public function addWindow(w:DocumentWindow):void {
                w.addEventListener(FlexEvent.CREATION_COMPLETE, onWindowCreation);
                addElement(w);
            }

            private function onWindowCreation(e:FlexEvent):void {
                var w:DocumentWindow = e.currentTarget as DocumentWindow;
                w.removeEventListener(FlexEvent.CREATION_COMPLETE, onWindowCreation);
                w.center();
            }

        ]]>
    </fx:Script>

    <s:Rect width="100%" height="100%">
        <s:fill>
            <s:SolidColor color="0xeeeeee" alpha="1"/>
        </s:fill>
    </s:Rect>

</s:Group>

实际上TaskBar的{​​{1}}永远不会被派遣!我假设 <?xml version="1.0" encoding="utf-8"?> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" initialize="init()" creationComplete="main()"> <fx:Script> <![CDATA[ import some.package.EClassView; import some.package.data.TaskInfo; import some.package.events.TaskEvent; import some.package.skins.GradientButtonSkin; import mx.collections.ArrayCollection; import mx.core.IVisualElement; import mx.core.IVisualElementContainer; import mx.events.ItemClickEvent; import spark.components.Button; import spark.components.DataGroup; import spark.components.Group; import spark.events.IndexChangeEvent; import spark.skins.spark.ButtonBarSkin; private var mTasks:ArrayCollection; public function get tasks():ArrayCollection { return mTasks; } private function init():void { mTasks = new ArrayCollection([]); } private function main():void { taskButtons.dataProvider = mTasks; } public function addTask(task:TaskInfo):void { task.index = mTasks.length; mTasks.addItem(task); task.win.addEventListener("minimize", onWinMinimize); task.win.addEventListener("maximize", onWinMaximize); task.win.addEventListener("restore", onWinRestore); taskButtons.selectedIndex = task.index; } public function removeTaskAt(i:int):void { var task:TaskInfo = mTasks[i] as TaskInfo; var evt:TaskEvent = new TaskEvent(TaskEvent.CLOSING); task.dispatchEvent(evt); if(evt.stopped) return; mTasks.removeItemAt(i) as TaskInfo; EClassView.instance.windows.removeElement(task.win); task.win.removeEventListener("minimize", onWinMinimize); task.win.removeEventListener("maximize", onWinMaximize); task.win.removeEventListener("restore", onWinRestore); rebuildTaskIndexes(); } public function getTaskById(tid:String):TaskInfo { for each(var t:TaskInfo in mTasks) { if(t.id == tid) return t; } return null; } public function set volume(v:Number):void { for each(var t:TaskInfo in mTasks) { t.win.view.setVolume(v); } } private function rebuildTaskIndexes():void { for(var n:int = 0; n < mTasks.length; ++n) (mTasks[n] as TaskInfo).index = n; } private function onWinMinimize(e:Event):void { var win:DocumentWindow = e.currentTarget as DocumentWindow; win.visible = false; var desktop:IVisualElementContainer = win.parent as IVisualElementContainer; var nw:DocumentWindow; taskButtons.selectedIndex = mTasks.length - 1; } private function onWinMaximize(e:Event):void { var win:DocumentWindow = e.currentTarget as DocumentWindow; win.bring2front(); win.resizable = win.movable = false; win.maximized = true; var ws:WindowsView = EClassView.instance.windows; win.width = ws.width; win.height = ws.height; } private function onWinRestore(e:Event):void { var win:DocumentWindow = e.currentTarget as DocumentWindow; win.doRestore(); } private function onTaskChanged(e:MouseEvent):void { var newt:TaskInfo = mTasks[taskButtons.selectedIndex] as TaskInfo; newt.win.doRestore(); } ]]> </fx:Script> <s:ButtonBar id="taskButtons" requireSelection="true" styleName="taskbar" labelField="title" click="onTaskChanged(event)" x="0" width="{width - taskButtons.x}" height="100%"/> </s:Group> 类型'doc'创建了某种在其他视图中缺失的事件......但是视图太复杂而无法在这里发布..这将是一个巨大的帖子:)

1 个答案:

答案 0 :(得分:0)

向我们展示一些代码,最好是一个可运行的样本。但是,听起来你正在将MX / Halo组件与Spark组件混合在一起。在Halo组件(例如画布)中,您应该使用addChild,而不是addElement。