複数の段へのテキストの分割

MultiColumnTextField クラスは、複数の TextField オブジェクトにテキストを配分します。これらのオブジェクトは、後で新聞の段組みのように配置されます。

まず、MultiColumnTextField() コンストラクタによって、次のように TextField オブジェクトの配列が作成されます。1 つのオブジェクトが 1 つの段に対応します。

    for (var i:int = 0; i < cols; i++)
    {
        var field:TextField = new TextField();
        field.autoSize = TextFieldAutoSize.NONE;
        field.wordWrap = true;
        field.styleSheet = this.styleSheet;
        
        this.fieldArray.push(field);
        this.addChild(field);
    }

各 TextField オブジェクトは配列に追加され、さらに addChild() メソッドによって表示リストに追加されます。

StoryLayout オブジェクトの text プロパティまたは styleSheet プロパティが変更されると、layoutColumns() メソッドが呼び出されて、テキストが再表示されます。layoutColumns() メソッドは、次に示す getOptimalHeight() メソッドを呼び出して、指定されたレイアウト幅に合わせてすべてのテキストを配置するために必要な高さを正確にピクセル単位で算出します。

public function getOptimalHeight(str:String):int
{
    if (fieldArray.length == 0 || str == "" || str == null)
    {
        return this.preferredHeight;
    }
    else
    {
        var colWidth:int = Math.floor( (this.preferredWidth - 
            ((this.numColumns - 1) * gutter)) / this.numColumns);

        var field:TextField = fieldArray[0] as TextField;
        field.width = colWidth;
        field.htmlText = str;

        var linesPerCol:int = Math.ceil(field.numLines / this.numColumns);
        var metrics:TextLineMetrics = field.getLineMetrics(0);
        var prefHeight:int = linesPerCol * metrics.height;
        return prefHeight + 4;
    }
}

getOptimalHeight() メソッドでは、まず各段の幅が計算されます。次に、配列の最初の TextField オブジェクトの幅と htmlText プロパティが設定されます。getOptimalHeight() メソッドでは、この最初の TextField オブジェクトを使用してテキストの折り返された総行数を調べ、その総行数に基づいて、各段に配分する行数を特定します。続いて、最初の行のテキストのサイズの詳細情報を含む TextLineMetrics オブジェクトを取得するために、TextField.getLineMetrics() メソッドが呼び出されます。TextLineMetrics.height プロパティは、アセント、ディセント、および行送りを含めたテキスト行全体の高さを表します (ピクセル単位)。MultiColumnTextField オブジェクトの最適な高さは、この行全体の高さと 1 段の行数を乗算し、さらに 4 ピクセルを加算したものになります。この 4 ピクセルは、TextField オブジェクトの上下それぞれに設ける 2 ピクセルの境界の分です。

layoutColumns() メソッド全体のコードを次に示します。

public function layoutColumns():void
{
    if (this._text == "" || this._text == null)
    {
        return;
    }

    if (this.fitToText)
    {
        this.preferredHeight = this.getOptimalHeight(this._text);
    }
    
    var colWidth:int = Math.floor( (this.preferredWidth - 
        ((numColumns - 1) * gutter)) / numColumns);
    var field:TextField;
    var remainder:String = this._text;
    var fieldText:String = "";
    
    for (var i:int = 0; i < fieldArray.length; i++)
    {
        field = this.fieldArray[i] as TextField;
        field.width = colWidth;
        field.height = this.preferredHeight;
        
        field.x = i * (colWidth + gutter);
        field.y = 0;
        
        field.htmlText = "<p>" + remainder + "</p>";
        
        remainder = "";
        fieldText = "";
        
        var linesRemaining:int = field.numLines;
        var linesVisible:int = field.numLines - field.maxScrollV + 1;
        for (var j:int = 0; j < linesRemaining; j++)
        {
            if (j < linesVisible)
            {
                fieldText += field.getLineText(j);
            }
            else
            {
                remainder +=  field.getLineText(j);
            }
        }
        
        field.htmlText = "<p>" + fieldText + "</p>";
    }
}

getOptimalHeight() メソッドの呼び出しによって preferredHeight プロパティが設定された後、layoutColumns() メソッドでは TextField オブジェクトが反復処理され、各オブジェクトの高さには preferredHeight の値が設定されます。続いて、layoutColumns() メソッドによって、各フィールドにちょうど収まる行数のテキストが配分されます。このとき、個々のフィールドでスクロールが発生することがなく、また、各後続フィールドのテキストは直前のフィールドでテキストが終わった箇所から始まるように配分されます。


 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート

現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000240.html