Archive for the ‘UI’ Category
flexのDataGridで縦と横のスクロールバーがあるか調べる。
しかしながら、標準のメソッドではこの方法が見つからないので・・・
以下のmx_internalなメソッドを使って調べる。
mx_internal::scroll_verticalScrollBar; mx_internal::scroll_horizontalScrollBar;
どうやら、スクロールバーがあるかどうかは、
1)nullが返ってきたとき。
2)visible=falseだったとき。
のようである。
このメソッド(getter)はScrollControlBaseのメソッドなのでかなりの広範囲で使えるだろう。
ただし、あくまでもmx_internalなメソッドなので使用の際にはそのことをお忘れなく。。。。
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="init()"
updateComplete="update()"
>
<mx:Script>
<![CDATA[
import mx.core.ScrollPolicy;
import mx.controls.scrollClasses.ScrollBar;
import mx.collections.ArrayCollection;
private function init():void{
// データを作成する
var src:Array = new Array();
for(var i:int = 0; i<30; i++){
var obj:Object = new Object();
obj.label = "ラベル" + i;
obj.idx = i;
src.push(obj);
}
dg.dataProvider = new ArrayCollection(src);
}
private function update():void{
var vs:ScrollBar = dg.mx_internal::scroll_verticalScrollBar;
var hs:ScrollBar = dg.mx_internal::scroll_horizontalScrollBar;
if(vs){
if(vs.visible){
vlog.text =" Found !! " + vs.width;
}
else{
vlog.text = "Found !! But not visible";
}
}
else{
vlog.text = "*NOT* found ...";
}
if(hs){
if(hs.visible){
hlog.text = "Found !!" + hs.height;
}
else{
hlog.text =" Found !! But not visible";
}
}
else{
hlog.text = "*NOT* found ...";
}
}
private function changeHBar():void{
if(hbar.selected){
dg.horizontalScrollPolicy = ScrollPolicy.ON;
}
else{
dg.horizontalScrollPolicy = ScrollPolicy.OFF;
}
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:DataGrid width="100%" height="90%" id="dg">
<mx:columns>
<mx:DataGridColumn headerText="LABEL" dataField="label" minWidth="150"/>
<mx:DataGridColumn headerText="INDEX" dataField="idx" minWidth="150"/>
</mx:columns>
</mx:DataGrid>
<mx:CheckBox id="hbar" change="changeHBar()"/>
<mx:HBox>
<mx:Label text="VerticalScrollBar" />
<mx:Label id="vlog" />
</mx:HBox>
<mx:HBox>
<mx:Label text="HorizontalScrollBar" />
<mx:Label id="hlog" />
</mx:HBox>
</mx:VBox>
</mx:Application>
flexのDataGridを使ってデータ一覧を表示したが、なぜか、マウスのカーソル通り、背景が反転しない。
もしや、DataProviderを自作しているためか?
でも、同じオブジェクトを使いまわしているところはないし・・・
ん・・・
何かデータにゴミがあるとおかしくなるのか?
と、データのプロパティを1つ1つ調べていくと、
uid
というフィールドがおかしいというところまでは力技で突き止めた。
んー、このフィールド名ではなく、別のフィールド名(messageId)という名前に変更したところ、
きちんと動くようになった・・・・
ちなみに、ほかでも同じような状況になったことがあるのだが、uidをダブらないようにしたらこの状況は起きていないので、
明らかに、このフィールドが作用している・・・
もしや、これは使えないフィールドというものが存在するかも。。。。。
私の場合、SQLiteを使ってデータを保存して、このフィールド名にuidというものを使ってしまった。
このように、DBという制約に頭がいってしまい、
uidというフィールドがFlexのframeworkレベルまで影響を及ぼすということを認識していなかった。
多少調べてみたら、
http://livedocs.adobe.com/flex/3_jp/langref/mx/controls/listClasses/BaseListData.html
というところが関係しそうな気がする。
さらに調べてみると、そのuidは、
http://livedocs.adobe.com/flex/3_jp/langref/mx/utils/UIDUtil.html#getUID()
で、itemのuidフィールドを見てそこからuidを取得しているから
uidというフィールドに一意にならないデータとして使ってはならないということだ。
私の場合、メールのmessage-idをuidとして保存していたのだが、意味としては重複してはならないが、
データとして結果として重複する場合があるので、まあ、それはそれでいいかとしていたが、
やはり、名前を変えることにした。
通常、uidというフィールドにユニークでない値をつかうということは少ないと思うが、
レアなケースだけにすぐに原因も見つけられなかった。
まあ、これでもう少し、
DataGridの中身が理解できたので、それはそれでいい経験ということで納得しよう。
さて、DataGirdのヘッダをいろいろとカスタマイズしたいなとおもって、その備忘録です。
1)ヘッダを表示しない
単純にDataGridの1列目を項目として2列目を値の入力などのようなプロパティ編集として使いたい場合に、
ヘッダを表示したくないということがある。
この場合には
<mx:DataGrid showHeaders="false" />
ただし、ここで注意しなければいけないのがヘッダの表示がないと、列幅を変える場所がなくなってしまうのです。
普通のセルの縦の区切り線でもサイズを変更できるようにできればいいのですが・・・
なので、私が気をつけているのは・・・
<mx:DataGridColumn headerText="項目名" minWidth="100" width="100" /> <mx:DataGridColumn headerText="値" />
のように1列目は幅を固定します。
ただし、なぜかリサイズとかすると、この設定を無視してサイズが変わるので画面の更新で再度、設定しなおします。
(headerTextは表示されませんが、わかりやすいように値をいれているだけです。)
列の幅の調整については私はこのようにしてにげました。
2)あるヘッダだけソートをさせなくしたい。
セルにチェックボックスや、ボタンなどを表示しているときに、そのヘッダをクリックされてもソートされないようにしたい。
<mx:DataGridColumn sortable="false" />
3)ヘッダにアイコンなどの画像などを表示したい
DataGridColumnに対してheaderRendererを設定してやればよい。
<mx:DataGridColumn id="dgf_priority">
<mx:headerRenderer>
<mx:Component>
<mx:HBox verticalAlign="middle" horizontalGap="0">
<mx:Image source="@Embed('assets/star_s.png')" />
<mx:Label text="スター" />
</mx:HBox>
</mx:Component>
</mx:headerRenderer>
</mx:DataGridColumn>
4)ヘッダの高さを取得・変更する
ヘッダの高さは
<mx:DataGridColumn headerHeight=”10″ />
のように設定できます。取得も同じプロパティです。
flexでは、ResourceManagerという機能を使って文言を別のファイルにして管理が行えます。
したがって、マルチランゲージ対応などもこれを使って行えます。
では、Flex Builderを使ってこのResourceManagerを使って文言を別のファイルにします。
1)Flex Builderのpropertiesファイルに日本語を記述できるようにする。
この設定を忘れると、文字コードがおかしいといわれ保存ができません。
はじめ、Flex Builder日本語版で、propertiesファイルがJavaなどのpropertiesファイルと同じようにしなければ、
日本語を記述できないと勘違いしてしまいましたが、単なるFlex Builderの設定のようです。
(せっかく日本語版なのですから、このあたりのデフォルトもきちんと設定されているとうれしいのですが・・・・)
ウィンドウ>設定 から、一般>コンテンツ・タイプ
で
「テキスト」を開くと、「Javaプロパティー・ファイル」がありますので、そこのデフォルト・エンコーディングを”UTF-8″に変更してください。
2)ソースディレクトリの下に
locale/ja_JP
ディレクトリを作成し、ここに文言ファイルを置きます。
別のディレクトリに配置し、そこをソースディレクトリとして追加してもかまいません。
3)コンパイル時に、ja_JPを使うようにします。
プロジェクトのプロパティで、「Flexコンパイラ」の「追加コンパイラ引数」に以下のように設定します。
-locale ja_JP -allow-source-path-overlap=true -source-path=locale/{locale}
4)実際に文言ファイルを作成します。
ここではファイル名はLBL0001.propertiesにします。
title=これはタイトルです。 desc=ここには説明が入ります。
5)文言ファイルで定義した文言をMXMLで使用する
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
label="{resourceManager.getString('LBL0001','title')}"
>
<mx:Metadata>
[ResourceBundle("LBL0001")]
</mx:Metadata>
</mx>
という感じで利用可能です。
文言だけじゃなく、ちょっとしたシステム設定などにも使えるのではないでしょうか?
Flexでは、ダイアログをPopUpManagerを使って作成することができる。
また、作成時に画面の中央にダイアログを表示したい場合には
private function createDialog():void{
var popup:IFlexDisplayObject = PopupManager.createPoopup([親画面],[Dialogのクラス],true);
PopupManager.centerPopup(popup);
}
のようにすればよい。
ここで、[Dialogのクラス]は、通常MXMLのようなものをさすと思う。
でも、小さい画面で開いていたが、ダイアログが見えないので画面を最大にしたとしても、
このままではダイアログは中央には移動しない。
ここで、親画面のリサイズとともにダイアログも中央の移動してほしい場合には
画面の更新とともに、以下のようなメソッド(関数)を作成しておき実行する。
private function updateEnd():void{
if(_curPopup){
PopUpManager.centerPopUp(_curPopup);
}
}
ここで、_curPopupは先の作成時の処理を
private var _curPopup:IFlexDisplayObject = null;
private function createDialog():void{
_curPopup = PopupManager.createPoopup([親画面],[Dialogのクラス],true);
PopupManager.centerPopup(_curPopup);
}
のように変えておけばよい。
また、画面の更新時の処理はMXMLであれば、
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" updateComplete="updateEnd()" >
のように、updateCompleteのプロパティ(イベント)を使うのが楽だ。
ちなみに、このイベントは正確にはmx.events.FlexEvent.UPDATE_COMPLETEになるので、AS内であればこのイベントで処理をする。


