AWTDataTableはカラムヘッダーをクリックすることでそのカラムの値を使ってテーブルに表示されるデータをソートする仕組みがありますが、ソートはAWTSortOrderingというオブジェクトが行っています。
ソートされる値は文字列として扱われているので、
- C
- A
- B
は
- A
- B
- C
または
- C
- B
- A
と正しくソートされますが、
- 2
- 100
- 45
は
- 100
- 2
- 45
または
- 45
- 2
- 100
とソートされてしまい、数量や金額といった数値が正しくソートされません。
また製品番号や伝票番号などでよく使われる
- No2
- No10
- No9
のような場合も正しくソートされません。
これを解決するには、
- Compareインターフェースを実装したFormatterを追加する
- カラムにそのFormatterをバインディングする
ということを行います。
以下に実装例を示します。
MyFormatter.java
まずFormatterです。AWFormatterのサブクラスでCompareインターフェースを実装します。
package app.util;
import java.text.ParseException;
import ariba.ui.aribaweb.util.AWFormatter;
import ariba.util.core.Compare;
public class MyFormatter extends AWFormatter implements Compare {
@Override
public Object parseObject(String stringToParse) throws ParseException {
return stringToParse;
}
@Override
public String format(Object objectToFormat) {
return (String)objectToFormat;
}
/**
* ソート対象の値から数値部分だけを抜き出して数値として比較する
*/
@Override
public int compare(Object o1, Object o2) {
String s1, s2;
s1 = o1 == null ? null : (String)o1;
s2 = o2 == null ? null : (String)o2;
if(s1 != null && s2 != null) {
int l1 = Integer.parseInt(s1.replaceAll("[^0-9]", ""));
int l2 = Integer.parseInt(s2.replaceAll("[^0-9]", ""));
return l1 - l2;
} else {
if(s1 == null && s2 == null) {
return Compare.EqualTo;
} else if(s1 == null) {
return Compare.LessThan;
} else {
return Compare.GreaterThan;
}
}
}
}
Application.java
アプリケーション起動時に作成したFormatterをシステムに登録する。例ではMyFormatterを"myformatter"という名前で登録しています。この名前はテンプレートファイル(AWL)ののバインディングを行うときに参照される名前です。
...
...
@Override
public void init() {
super.init();
installFormatters();
}
...
...
private void installFormatters() {
AWVFormatterFactory.registerProvider(new FormatterProvider() {
@Override
public void populateFormatters(Map<String, Object> formatters, Locale locale, TimeZone timeZone) {
Map<String, AWFormatter> map = MapUtil.map();
map.put("myformatter", new MyFormatter());
for(Map.Entry<String, AWFormatter> entry : map.entrySet()) {
formatters.put(entry.getKey(), entry.getValue());
}
}});
}
テンプレートファイル(AWL)を修正する
<t:DataTable ....>
...
...
<t:Column key="orderNo" label="Order #" formatter="$formatters.myformatter" />
...
...
</t:DataTable>