サイトトップ

Director Flash 書籍 業務内容 プロフィール

Macromedia Flash非公式テクニカルノート

ComboBoxコンポーネントの項目を削除してもドロップダウンリストの大きさが変わらない

ID: FN0908001 Product: Flash Platform: All Version: CS4/ActionScript 3.0

問題
ComboBox.removeItemAt()メソッドでComboBoxコンポーネントインスタンスの項目を削除しても、ドロップダウンリスト(外枠)の大きさがもとのままで、高さが縮みません(図001)[*1]

図001■項目が削除されてもドロップダウンリストの大きさは変わらない
図001左図 項目を削除
図001右図

[*1] 英語による解説は、JActionScripters「Resizing the drop down list of ComboBox when removeItem() is called」に投稿しました。

See "Resizing the drop down list of ComboBox when removeItem() is called" of JActionScripters for English explanation.


原因
ComboBoxコンポーネントはドロップダウンリストとしてListコンポーネントを利用し、ComboBox.removeItem()メソッドは内部的にList.removeItem()を呼出しています。項目を削除しても大きさが変わらないのは、Listコンポーネントの動作にもとづくものと思われます。

しかしながら、ComboBox.removeItemAt()メソッドを用いれば、ドロップダウンリストの大きさは正しく変わります。したがって、ComboBox.removeItemAt()メソッドの動作結果は、ComboBoxコンポーネントに応じた処理の調整がされていないバグだと考えられます。


対処法
以下のテスト用フレームアクション(スクリプト001)のように、ComboBox.removeItem()メソッドで項目を削除した後UIComponent.validateNow()を呼出します。なお、コンポーネントをタイムラインに動的に配置するときは、そのコンポーネントは[ライブラリ]に予め格納しておく必要があります。

スクリプト001■項目削除後UIComponent.validateNow()メソッドを呼出す

// フレームアクション
// [ライブラリ]にComboBoxコンポーネントを格納
import fl.controls.ComboBox;
var myComboBox:ComboBox = new ComboBox();
addChild(myComboBox);
myComboBox.addEventListener(Event.CHANGE, xSelected);
myComboBox.addItem({label:"Dreamweaver CS4", data:"html"});
myComboBox.addItem({label:"Fireworks CS4", data:"png"});
myComboBox.addItem({label:"Flash CS4 Professional", data:"fla"});
function xSelected(eventObject:Event):void {
  var myItem:Object = myComboBox.getItemAt(0);
  myComboBox.removeItem(myItem);
  myComboBox.validateNow();   // UIComponent.validateNow()を呼出し
}

上記スクリプト001を[ムービープレビュー]で確かめると、ComboBoxコンポーネントインスタンスの項目が削除されれば、ドロップダウンリストの大きさもそれに合わせて調整されます(図002)。

図002■項目が削除されるとドロップダウンリストの大きさも調整される
図002左図 項目を削除
図002右図

詳細解説
ComboBoxクラスには、メソッドremoveItem()およびremoveItemAt()は以下のスクリプト002のように定義されています(図003)。比べてみるとわかるように、removeItem()メソッドはUIComponent.invalidate()メソッドを呼出していません。それがこの問題の原因になっているようです。

スクリプト002■ComboBoxクラスにおけるメソッドremoveItem()およびremoveItemAt()の定義

public class ComboBox extends UIComponent implements IFocusManagerComponent {
  // ...[中略]...
  public function removeItem(item:Object):Object {
    return list.removeItem(item);
  }
  // ...[中略]...
  public function removeItemAt(index:uint):void {
    list.removeItemAt(index);
    invalidate(InvalidationType.DATA);
  }

図003■ComboBoxクラスに定義されたremoveItem()およびremoveItemAt()メソッド
図003

したがって、前掲スクリプト001の例でいえば、つぎのようにメソッドUIComponent.validateNow()に替えてUIComponent.invalidate()を呼出してもよいでしょう[*2]

import fl.core.InvalidationType;
// ...[中略]...
function xSelected(eventObject:Event):void {
  var myItem:Object = myComboBox.getItemAt(0);
  myComboBox.removeItem(myItem);
  myComboBox.invalidate(InvalidationType.DATA);   // UIComponent.invalidate()を呼出し
}

[*2] UIComponent.validateNow()メソッドでは、厳密にはつぎのように定数InvalidationType.ALLを引数としてUIComponent.invalidate()メソッドが呼出されているという違いはあります。

public class UIComponent extends Sprite {
  // ...[中略]...
  public function validateNow():void {
    invalidate(InvalidationType.ALL,false);
    draw();
  }


作成者: 野中文雄
作成日: 2008年8月9日


Copyright © 2001-2009 Fumio Nonaka.  All rights reserved.