Revision 3 as of 2011-12-24 04:09:40

Clear message
Locked History Actions

GWT/Widget/FlexTable

FlexTable

レイアウト上のバグとの対策

現象

FlexTableには非常に大きなバグがある。しかし、FlexTableの構造上、不可避のものなので「仕様」と言ってもよいかもしれない。

例えば以下のコードを実行すると、Bはなぜか2列目にはならず、三列目になってしまう。 つまり、(0,0)位置のセルのRowSpanを2にすると、二行目の列位置がずれてしまう。

    FlexTable table = view.getFlexTable();    
    table.setText(0, 0, "X");
    table.getFlexCellFormatter().setRowSpan(0,  0, 2);    
    table.setText(0,  1, "A");
    table.setText(1,  1, "B");

以下のように、後から(0,0)位置のセルを入れても同じ現象になる。

    FlexTable table = view.getFlexTable();    
    table.setText(0,  1, "A");
    table.setText(1,  1, "B");
    table.setText(0, 0, "X");
    table.getFlexCellFormatter().setRowSpan(0,  0, 2);     

原因

これは、実際に生成されるtableタグでの解釈と、FlexTableでのセル位置指定にズレがあるからである。 例えば、上の例の場合、いずれも

<tr>
 <td rowspan="2">X</td>
 <td>A</td>
</tr>
<tr>
  <td></td>
  <td><B</td>
</tr>

というタグが生成される。FlexTable側としては指示された場所にデータを入れているつもりだろうが、 tableタグの解釈としては、これはプログラマの意図とは異なるものになってしまう。 つまり、AとBは同じ列にはならない。

対策

FlexTableをそのまま使う上での対策としては、(この例の場合では)プログラマ側が、どの列が一つ多くなっているかを認識し、その列より右側の列位置を指定する再に、列インデックスを減産するというものである。しかしこれはいかにも面倒であろう。

もう一つの対策としては、FlexTableを継承した新たなクラスを作成し、RowSpanあるいはColSpanが指定された場合には、それがどの列に影響を及ぼすかを保持しておき、プログラマ側から示されたセル位置指定を自動的に補正するというものである。

ただし、この場合、上の例の二つ目で示したように、「後から左側のセルのデータを入れ、そのRowSpanを指定した場合には、結局ずれてしまう」という問題を解決しなければならない。

つまり、この問題を根本的に解決するには、現在のFlexTableが行なっているような、「setText等のメソッドがよびだされたら、その場でDOM操作を行なってタグを作成する」を改め、いったん内部的なバッファにデータ指定をため込み、最後にその位置を調整しながらタグを作成するといったことを行わなければならない。