問題
ComboBox.removeItemAt()メソッドでComboBoxコンポーネントインスタンスの項目を削除しても、ドロップダウンリスト(外枠)の大きさがもとのままで、高さが縮みません(図001)[*1]。
図001■項目が削除されてもドロップダウンリストの大きさは変わらない
|
項目を削除
→
|
|
原因
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■項目が削除されるとドロップダウンリストの大きさも調整される
|
項目を削除
→
|
|
詳細解説
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()メソッド
したがって、前掲スクリプト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日