ScrollPane和ScrollBar无法正常工作

时间:2014-06-02 21:52:50

标签: actionscript-3 flash scrollbar scrollpane

我有一个应用程序我正在尝试构建它将显示一个大的地图图像(1920x1040被设置为第一帧的基础层,然后我的所有AS也在第一帧上面的层上),然后通过从外部文件(lines.txt)读取坐标并将特定图像与每一行相关联来绘制线条。

当用户点击某一行时,应该打开一个ScrollPane,显示与他们点击的行相关联的图像。这些图像的高度为1040,宽度至少为4000px,因此我希望图像填满屏幕高度,然后允许用户沿着底部使用滚动条向左和向右滚动以查看完整图像。

现在,我让它在我的lines.txt文件中读取,并正确绘制线条。然后,当我单击一行时,它将在ScrollPane中加载相应的图像(以及一个单击按钮,将删除滚动窗格并允许它们选择一个新行)。

但是,我无法使用水平滚动条。我有它,以便空间显示在滚动条应该是的底部,但是没有向左/向右拖动的栏,也没有可以滚动的方式。

我看到可以使用拖动来滚动,这会很好,但是这也没有用(它现在被注释掉),当我打开它时,当我点击我的后退按钮并尝试单击另一行,它会抛出一个错误,

“TypeError:错误#1009:无法访问空对象引用的属性或方法。     在fl.containers :: ScrollPane / endDrag()“

任何人都能帮我清理一下并弄清楚这里出了什么问题?

我的代码:

import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.geom.ColorTransform;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;

import fl.containers.ScrollPane; 
import fl.events.ScrollEvent;
import fl.controls.ScrollPolicy; 
import fl.controls.DataGrid; 
import fl.data.DataProvider;
import flash.display.Loader;
import flash.net.URLRequest;

import flash.net.URLLoader; 
import fl.controls.UIScrollBar; 
import flash.events.Event;
import fl.controls.ScrollBar;


var worldLines:Array = new Array();
var lineSprites:Array = new Array();
var lineSpritesLength:int;

var basicColorTransform:ColorTransform = new ColorTransform();
basicColorTransform.color = 0x00FF00;

var hoverColorTransform:ColorTransform = new ColorTransform();
hoverColorTransform.color = 0xFFFF00;

populateWorldLines();

function populateWorldLines():void
{
    var textFile:File = File.applicationDirectory.resolvePath("lines.txt");
    var fileContents:String = getFileData(textFile);

    var contentsLength:int = fileContents.split("$").length;

    for(var i:int = 0; i < contentsLength; i++)
    {
        trace(i);
        worldLines[i]    = new Object();

        worldLines[i]["x1"]     = fileContents.slice(0, fileContents.indexOf(","));
        fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);

        worldLines[i]["y1"]     = fileContents.slice(0, fileContents.indexOf(","));
        fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);

        worldLines[i]["x2"]     = fileContents.slice(0, fileContents.indexOf(","));
        fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);

        worldLines[i]["y2"]     = fileContents.slice(0, fileContents.indexOf(","));
        fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);

        worldLines[i]["image"]  = fileContents.slice(0, fileContents.indexOf(";"));
        fileContents = fileContents.slice(fileContents.indexOf("$") + 1, fileContents.length);
    }

    drawLines(worldLines);
}

function drawLines(lines:Array):void
{
    for(var i:int = 0; i < lines.length; i++)
    {
        var line:Sprite = new Sprite;
        line.graphics.moveTo(lines[i]["x1"], lines[i]["y1"]);
        line.graphics.lineStyle(3, basicColorTransform.color);
        line.graphics.lineTo(lines[i]["x2"], lines[i]["y2"]);
        lineSprites.push(line);
        addChild(line);
    }

    lineSpritesLength = lineSprites.length;

    this.addEventListener(MouseEvent.MOUSE_OVER, checkLines);
}

function checkLines(e:MouseEvent):void
{
    var targetSprite:* = e.target;
    for(var i:int = 0; i < lineSpritesLength; i++)
    {
        if(targetSprite == lineSprites[i])
        {
            targetSprite.transform.colorTransform = hoverColorTransform;
            targetSprite.addEventListener(MouseEvent.CLICK, lineClicked);
            targetSprite.addEventListener(MouseEvent.MOUSE_OUT, resetColorTransform);
        }
    }
}

function lineClicked(e:MouseEvent):void
{
    var targetSprite:* = e.target;
    for(var i:int = 0; i < lineSpritesLength; i++)
    {
        if(targetSprite == lineSprites[i])
        {
            showImage(worldLines[i]["x1"], worldLines[i]["y1"], worldLines[i]["image"]);
        }
    }
    //e.target.removeEventListener(e.type, lineClicked);
}

function showImage(xPos:int, yPos:int, imageName:String):void
{

    var aSp:ScrollPane = new ScrollPane(); 
    var aBox:MovieClip = new MovieClip(); 

    drawBox(aBox, imageName);   



    aSp.source = aBox; 
    aSp.setSize(1920, 1040); 
    aSp.move(0, 0); 
    aSp.name = "scrollyPaneThing";
    //aSp.scrollDrag = true;
    aSp.horizontalScrollPolicy=ScrollPolicy.ON;
    aSp.addEventListener(ScrollEvent.SCROLL, scrollListener);


    addChild(aSp);


}

function scrollListener(event:ScrollEvent):void { 

    var mySP:ScrollPane = event.currentTarget as ScrollPane;
    trace("scrolling");
    trace("\t" + "direction:", event.direction);
    trace("\t" + "position:", event.position);
    trace("\t" + "horizontalScrollPosition:", mySP.horizontalScrollPosition, "of", mySP.maxHorizontalScrollPosition);
    trace("\t" + "verticalScrollPosition:", mySP.verticalScrollPosition, "of", mySP.maxVerticalScrollPosition);
};


function drawBox(box:MovieClip,imageName:String):void { 

            trace(imageName + ":imageName");
            var file:File = File.applicationDirectory.resolvePath("dataImages/"+imageName);
            var imageLoader:Loader = new Loader();
            var image:URLRequest = new URLRequest(file.url);
            imageLoader.load(image);
            imageLoader.x = 1;
            imageLoader.y = 1;
            box.addChild (imageLoader);

            trace("backButton.png:imageName");
            var file2:File = File.applicationDirectory.resolvePath("backButton.png");
            var imageLoader2:Loader = new Loader();
            var image2:URLRequest = new URLRequest(file2.url);
            imageLoader2.load(image2);
            imageLoader2.x = 10;
            imageLoader2.y = 950;
            box.addChild (imageLoader2);

            imageLoader2.addEventListener(MouseEvent.CLICK, removeScrollyPaneThing);

}


function removeScrollyPaneThing(MouseEvent):void
{


    removeChild(getChildByName("scrollyPaneThing"));


}



function resetColorTransform(e:MouseEvent):void
{
    e.target.transform.colorTransform = basicColorTransform;
    e.target.removeEventListener(e.type, resetColorTransform);
}

function getFileData(file:File):String
{
    var fDataStream:FileStream; 
    var sContent:String;
    fDataStream = new FileStream();
    fDataStream.open(file, FileMode.READ);
    sContent = fDataStream.readUTFBytes(fDataStream.bytesAvailable);
    fDataStream.close();

    return sContent;
}

1 个答案:

答案 0 :(得分:0)

您的Loader对象具有内置的scrollRect属性 使用简单的ScrollBar比使用ScrollPane更容易, 但鼠标拖动更清洁:

请参阅:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#scrollRect

鼠标拖动:

private var scrollyThingy:Rectangle; 
private var map:Loader;

// holders for the location of the view
//(to allow for cancelling the drag):
private var _cx:int = 0;
private var _cy:int = 0;

private var downpoint:Point = null;



public function init():void{
    // Load your image: 

     /*   I prefer to use embeded png files 
        or draw simple line images, but 
        Loader objects also have a scrollRect property  

        From this point I will assume your main image ('map') is loaded, 
        and 'scrollyThingy' is the part you want diplayed

        I could not follow the code once you added the 
        loader to the stage very well...  
    */

     // to enable mouse dragging:

    map.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

    var w:int = 100;
    var h:int = 100;
    scrollyThingy = new Rectangle(_cx, _cy, w, h);
    map.scrollRect = scrollyThingy;
    AddChild(map);
}

private function onMouseDown(event:MouseEvent):void{
    _downpoint = new Point(event.stageX, event.stageY);

    map.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

    map.addEventListener(MouseEvent.MOUSE_DRAG, onMouseDrag);
    map.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
    map.addEventListener(MouseEvent.RELEASE_OUTSIDE , onReleaseOutside);

}

private function onMouseDrag(event:MouseEvent):void{
    if (_downpoint == null)
        return;

    // the movement delta:
    _dx = int((event.stageX - _downpoint.x));
    _dy = int((event.stageY - _downpoint.y));
    // (if the movement is backwards, use scrollyThingy.x -= _dx)
    scrollyThingy.x += _dx;
    scrollyThingy.y += _dy;
    Loader.scrollRect = scrollyThingy;

}

private function onMouseUp(event:MouseEvent):void{
    if (_downpoint == null)
        return;

    // new corner coords
    _cx += int((event.stageX - _downpoint.x));
    _cy += int((event.stageY - _downpoint.y));

    resetListeners();
}   

private function onReleaseOutside(event:MouseEvent):void{
    // put it back where it was
    resetListeners();

}

private function resetListeners():void{
    scrollyThingy.x = _cx;
    scrollyThingy.y = _cy;
    Loader.scrollRect = scrollyThingy;
    _downpoint = null;

    if(!map.hasEventListener(MouseEvent.MOUSE_DOWN)
    map.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

    //(if it has one, it has them all!)
    if(map.hasEventListener(MouseEvent.MOUSE_DRAG){
        map.removeEventListener(MouseEvent.MOUSE_DRAG, onMouseDrag);
        map.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        map.removeEventListener(MouseEvent.RELEASE_OUTSIDE  , onReleaseOutside);
    }

}

如果您仍然需要ScrollBar,只需将其缩放到您的Loader尺寸减去 视口的大小(xScrollBar.maximum = loader.content.width - scrollyThingy.width, yScrollbar.maximum = loader.content.height - scrollyThingy.height)那么你可以使用  两个栏的听众都是一样的:

function onScrollBarChange(e:event):void{
    scrollyThingy.x = xScrollBar.value;
    scrollyThingy.y = yScrollBar.value;
}

侦听更改事件并设置Loader.scrollRect.x和Loader.scrollRect.y scrollBarx.value&amp;的属性scrollBary.value。

另请注意,我没有包含任何价值检查 您应该在移动scrollRect之前检查值 避免rangeErrors

即。 if(_cx&gt; loader.width - loader.scrollRect.width)         _cx = Loader.width - Loader.scrollRect.width;