ScrollPane и ScrollBar не работают

У меня есть приложение, которое я пытаюсь создать, где оно будет отображать большое изображение карты (1920x1040, установленное в качестве базового слоя первого кадра, затем вся моя AS находится на уровне выше и в первом кадре), а затем рисовать линии к нему, считывая их координаты из внешнего файла (lines.txt) и связывая определенное изображение с каждой строкой.

Когда пользователь щелкает строку, должна открываться ScrollPane, отображающая изображение, связанное с строкой, на которой он щелкнул. Эти изображения имеют высоту 1040 пикселей и ширину не менее 4000 пикселей, поэтому я хочу, чтобы изображение занимало всю высоту экрана, а затем позволяло пользователю использовать полосу прокрутки внизу для прокрутки влево и вправо, чтобы увидеть полное изображение.

Прямо сейчас он работает там, где он читается в моем файле lines.txt, и правильно рисует линии. Затем, когда я нажимаю на строку, она загружает соответствующее изображение в ScrollPane (вместе с кнопкой, которую нужно щелкнуть, чтобы удалить панель прокрутки и позволить им выбрать новую строку).

Однако я не могу заставить работать горизонтальную полосу прокрутки. У меня так, что внизу появляется пространство, где должна быть полоса прокрутки, но нет полосы для перетаскивания влево / вправо и нет возможности прокручивать.

Я видел, что можно использовать перетаскивание для прокрутки, что было бы неплохо, но это тоже не сработало (теперь оно закомментировано), и когда я его включаю, когда я нажимаю кнопку `` Назад '' и пытаюсь нажать другую строка, выдает сообщение об ошибке:

«TypeError: Ошибка № 1009: невозможно получить доступ к свойству или методу ссылки на нулевой объект. At 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;
}

person Justgrant2009    schedule 02.06.2014    source источник


Ответы (1)


Ваш объект загрузчика имеет встроенное свойство scrollRect.
НАМНОГО проще использовать простую полосу прокрутки, чем 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, просто масштабируйте его до размеров вашего загрузчика за вычетом размера области просмотра (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 и scrollBary.value.

Также обратите внимание, что я не включал никакой проверки значений.
Вы должны проверить значения перед перемещением scrollRect, чтобы избежать rangeErrors

т.е. if (_cx> loader.width - loader.scrollRect.width) _cx = Loader.width - Loader.scrollRect.width;

person schwack    schedule 03.06.2014
comment
К сожалению, я недостаточно знаю об AS, чтобы полностью понять, что мне здесь делать с вашей помощью. Если я попытаюсь добавить частные переменные вверху своего фрейма действий (где я уже объявляю другие переменные), при компиляции будет выдана ошибка, в которой говорится, что частный атрибут может использоваться только в определениях свойств класса. Кроме того, насколько я понимаю этот код, вы применяете движение перетаскивания к карте, и я не хочу этого, я хочу, чтобы движение перетаскивания влияло только на изображения, загруженные загрузчиком. - person Justgrant2009; 03.06.2014